共计 8895 个字符,预计需要花费 23 分钟才能阅读完成。
AtomicCounter.h 线程平安的原子援用计数 实现
// | |
// AtomicCounter.h | |
// | |
// Library: Foundation | |
// Package: Core | |
// Module: AtomicCounter | |
// | |
// Definition of the AtomicCounter class. | |
// | |
// Copyright (c) 2009, Applied Informatics Software Engineering GmbH. | |
// and Contributors. | |
// | |
// SPDX-License-Identifier: BSL-1.0 | |
// | |
#ifndef Foundation_AtomicCounter_INCLUDED | |
#define Foundation_AtomicCounter_INCLUDED | |
namespace Poco { | |
class AtomicCounter | |
/// This class implements a simple counter, which | |
/// provides atomic operations that are safe to | |
/// use in a multithreaded environment. | |
/// | |
/// Typical usage of AtomicCounter is for implementing | |
/// reference counting and similar things. | |
/// | |
/// On some platforms, the implementation of AtomicCounter | |
/// is based on atomic primitives specific to the platform | |
/// (such as InterlockedIncrement, etc. on Windows), and | |
/// thus very efficient. On platforms that do not support | |
/// atomic primitives, operations are guarded by a FastMutex. | |
/// | |
/// The following platforms currently have atomic | |
/// primitives: | |
/// - Windows | |
/// - Mac OS X | |
/// - GCC 4.1+ (Intel platforms only) | |
{ | |
public: | |
typedef int ValueType; /// The underlying integer type. | |
AtomicCounter(); | |
/// Creates a new AtomicCounter and initializes it to zero. | |
explicit AtomicCounter(ValueType initialValue); | |
/// Creates a new AtomicCounter and initializes it with | |
/// the given value. | |
AtomicCounter(const AtomicCounter &counter); | |
/// Creates the counter by copying another one. | |
~AtomicCounter(); | |
/// Destroys the AtomicCounter. | |
AtomicCounter &operator=(const AtomicCounter &counter); | |
/// Assigns the value of another AtomicCounter. | |
AtomicCounter &operator=(ValueType value); | |
/// Assigns a value to the counter. | |
operator ValueType() const; | |
/// Returns the value of the counter. | |
ValueType value() const; | |
/// Returns the value of the counter. | |
ValueType operator++(); // prefix | |
/// Increments the counter and returns the result. | |
ValueType | |
operator++(int); // postfix | |
/// Increments the counter and returns the previous value. | |
ValueType operator--(); // prefix | |
/// Decrements the counter and returns the result. | |
ValueType | |
operator--(int); // postfix | |
/// Decrements the counter and returns the previous value. | |
bool operator!() const; | |
/// Returns true if the counter is zero, false otherwise. | |
private: | |
typedef int ImplType; | |
ImplType _counter; | |
}; | |
AtomicCounter::AtomicCounter() : _counter(0) {} | |
AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue) | |
: _counter(initialValue) {} | |
AtomicCounter::AtomicCounter(const AtomicCounter &counter) | |
: _counter(counter.value()) {} | |
AtomicCounter::~AtomicCounter() {} | |
// | |
// GCC 4.1+ atomic builtins. | |
// | |
inline AtomicCounter::operator AtomicCounter::ValueType() const {return _counter;} | |
inline AtomicCounter::ValueType AtomicCounter::value() const {return _counter;} | |
inline AtomicCounter::ValueType AtomicCounter::operator++() // prefix | |
{return __sync_add_and_fetch(&_counter, 1); | |
} | |
inline AtomicCounter::ValueType AtomicCounter::operator++(int) // postfix | |
{return __sync_fetch_and_add(&_counter, 1); | |
} | |
inline AtomicCounter::ValueType AtomicCounter::operator--() // prefix | |
{return __sync_sub_and_fetch(&_counter, 1); | |
} | |
inline AtomicCounter::ValueType AtomicCounter::operator--(int) // postfix | |
{return __sync_fetch_and_sub(&_counter, 1); | |
} | |
inline bool AtomicCounter::operator!() const { return _counter == 0;} | |
} // namespace Poco | |
#endif // Foundation_AtomicCounter_INCLUDED |
SharedPtr 智能指针的实现
// | |
// SharedPtr.h | |
// | |
// Library: Foundation | |
// Package: Core | |
// Module: SharedPtr | |
// | |
// Definition of the SharedPtr template class. | |
// | |
// Copyright (c) 2005-2008, Applied Informatics Software Engineering GmbH. | |
// and Contributors. | |
// | |
// SPDX-License-Identifier: BSL-1.0 | |
// | |
#ifndef Foundation_SharedPtr_INCLUDED | |
#define Foundation_SharedPtr_INCLUDED | |
#include "AtomicCounter.h" | |
#include <algorithm> | |
#include <cassert> | |
#include <exception> | |
#include <stdexcept> | |
namespace Poco { | |
class ReferenceCounter | |
/// Simple ReferenceCounter object, does not delete itself when count reaches 0. | |
{ | |
public: | |
ReferenceCounter() : _cnt(1) {} | |
void duplicate() { ++_cnt;} | |
int release() { return --_cnt;} | |
int referenceCount() const { return _cnt.value(); } | |
private: | |
AtomicCounter _cnt; | |
}; | |
template <class C> | |
class ReleasePolicy | |
/// The default release policy for SharedPtr, which | |
/// simply uses the delete operator to delete an object. | |
{ | |
public: | |
static void release(C *pObj) | |
/// Delete the object. | |
/// Note that pObj can be 0. | |
{delete pObj;} | |
}; | |
template <class C> | |
class ReleaseArrayPolicy | |
/// The release policy for SharedPtr holding arrays. | |
{ | |
public: | |
static void release(C *pObj) | |
/// Delete the object. | |
/// Note that pObj can be 0. | |
{delete[] pObj; | |
} | |
}; | |
template <class C, class RC = ReferenceCounter, class RP = ReleasePolicy<C> > | |
class SharedPtr | |
/// SharedPtr is a "smart" pointer for classes implementing | |
/// reference counting based garbage collection. | |
/// SharedPtr is thus similar to AutoPtr. Unlike the | |
/// AutoPtr template, which can only be used with | |
/// classes that support reference counting, SharedPtr | |
/// can be used with any class. For this to work, a | |
/// SharedPtr manages a reference count for the object | |
/// it manages. | |
/// | |
/// SharedPtr works in the following way: | |
/// If an SharedPtr is assigned an ordinary pointer to | |
/// an object (via the constructor or the assignment operator), | |
/// it takes ownership of the object and the object's reference | |
/// count is initialized to one. | |
/// If the SharedPtr is assigned another SharedPtr, the | |
/// object's reference count is incremented by one. | |
/// The destructor of SharedPtr decrements the object's | |
/// reference count by one and deletes the object if the | |
/// reference count reaches zero. | |
/// SharedPtr supports dereferencing with both the -> | |
/// and the * operator. An attempt to dereference a null | |
/// SharedPtr results in a NullPointerException being thrown. | |
/// SharedPtr also implements all relational operators and | |
/// a cast operator in case dynamic casting of the encapsulated data types | |
/// is required. | |
{ | |
public: | |
SharedPtr() : _pCounter(new RC), _ptr(0) {} | |
SharedPtr(C *ptr) try : _pCounter(new RC), _ptr(ptr) {} catch (...) {RP::release(ptr); | |
} | |
template <class Other, class OtherRP> | |
SharedPtr(const SharedPtr<Other, RC, OtherRP> &ptr) | |
: _pCounter(ptr._pCounter), _ptr(const_cast<Other *>(ptr.get())) {_pCounter->duplicate(); | |
} | |
SharedPtr(const SharedPtr &ptr) : _pCounter(ptr._pCounter), _ptr(ptr._ptr) {_pCounter->duplicate(); | |
} | |
~SharedPtr() { | |
try {release(); | |
} catch (...) {assert(0); | |
} | |
} | |
SharedPtr &assign(C *ptr) {if (get() != ptr) {SharedPtr tmp(ptr); | |
swap(tmp); | |
} | |
return *this; | |
} | |
SharedPtr &assign(const SharedPtr &ptr) {if (&ptr != this) {SharedPtr tmp(ptr); | |
swap(tmp); | |
} | |
return *this; | |
} | |
template <class Other, class OtherRP> | |
SharedPtr &assign(const SharedPtr<Other, RC, OtherRP> &ptr) {if (ptr.get() != _ptr) {SharedPtr tmp(ptr); | |
swap(tmp); | |
} | |
return *this; | |
} | |
SharedPtr &operator=(C *ptr) {return assign(ptr); } | |
SharedPtr &operator=(const SharedPtr &ptr) {return assign(ptr); } | |
template <class Other, class OtherRP> | |
SharedPtr &operator=(const SharedPtr<Other, RC, OtherRP> &ptr) {return assign<Other>(ptr); | |
} | |
void swap(SharedPtr &ptr) {std::swap(_ptr, ptr._ptr); | |
std::swap(_pCounter, ptr._pCounter); | |
} | |
template <class Other> | |
SharedPtr<Other, RC, RP> cast() const | |
/// Casts the SharedPtr via a dynamic cast to the given type. | |
/// Returns an SharedPtr containing NULL if the cast fails. | |
/// Example: (assume class Sub: public Super) | |
/// SharedPtr<Super> super(new Sub()); | |
/// SharedPtr<Sub> sub = super.cast<Sub>(); | |
/// poco_assert (sub.get()); | |
{Other *pOther = dynamic_cast<Other *>(_ptr); | |
if (pOther) | |
return SharedPtr<Other, RC, RP>(_pCounter, pOther); | |
return SharedPtr<Other, RC, RP>();} | |
template <class Other> | |
SharedPtr<Other, RC, RP> unsafeCast() const | |
/// Casts the SharedPtr via a static cast to the given type. | |
/// Example: (assume class Sub: public Super) | |
/// SharedPtr<Super> super(new Sub()); | |
/// SharedPtr<Sub> sub = super.unsafeCast<Sub>(); | |
/// poco_assert (sub.get()); | |
{Other *pOther = static_cast<Other *>(_ptr); | |
return SharedPtr<Other, RC, RP>(_pCounter, pOther); | |
} | |
C *operator->() { return deref(); } | |
const C *operator->() const { return deref(); } | |
C &operator*() { return *deref(); } | |
const C &operator*() const { return *deref(); } | |
C *get() { return _ptr;} | |
const C *get() const { return _ptr;} | |
operator C *() { return _ptr;} | |
operator const C *() const { return _ptr;} | |
bool operator!() const { return _ptr == 0;} | |
bool isNull() const { return _ptr == 0;} | |
bool operator==(const SharedPtr &ptr) const {return get() == ptr.get();} | |
bool operator==(const C *ptr) const {return get() == ptr; } | |
bool operator==(C *ptr) const {return get() == ptr; } | |
bool operator!=(const SharedPtr &ptr) const {return get() != ptr.get();} | |
bool operator!=(const C *ptr) const {return get() != ptr; } | |
bool operator!=(C *ptr) const {return get() != ptr; } | |
bool operator<(const SharedPtr &ptr) const {return get() < ptr.get();} | |
bool operator<(const C *ptr) const {return get() < ptr; } | |
bool operator<(C *ptr) const {return get() < ptr; } | |
bool operator<=(const SharedPtr &ptr) const {return get() <= ptr.get();} | |
bool operator<=(const C *ptr) const {return get() <= ptr; } | |
bool operator<=(C *ptr) const {return get() <= ptr; } | |
bool operator>(const SharedPtr &ptr) const {return get() > ptr.get();} | |
bool operator>(const C *ptr) const {return get() > ptr; } | |
bool operator>(C *ptr) const {return get() > ptr; } | |
bool operator>=(const SharedPtr &ptr) const {return get() >= ptr.get();} | |
bool operator>=(const C *ptr) const {return get() >= ptr; } | |
bool operator>=(C *ptr) const {return get() >= ptr; } | |
int referenceCount() const { return _pCounter->referenceCount(); } | |
protected: | |
C *deref() const {if (!_ptr) | |
throw std::exception(); | |
return _ptr; | |
} | |
void release() {assert(_pCounter); | |
int i = _pCounter->release(); | |
if (i == 0) {RP::release(_ptr); | |
_ptr = 0; | |
delete _pCounter; | |
_pCounter = 0; | |
} | |
} | |
SharedPtr(RC *pCounter, C *ptr) | |
: _pCounter(pCounter), _ptr(ptr) | |
/// for cast operation | |
{poco_assert_dbg(_pCounter); | |
_pCounter->duplicate();} | |
protected: | |
RC *_pCounter; | |
C *_ptr; | |
template <class OtherC, class OtherRC, class OtherRP> friend class SharedPtr; | |
}; | |
template <class C, class RC, class RP> | |
inline void swap(SharedPtr<C, RC, RP> &p1, SharedPtr<C, RC, RP> &p2) {p1.swap(p2); | |
} | |
} // namespace Poco | |
#endif // Foundation_SharedPtr_INCLUDED |
正文完