X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195..e3d3b979fd185d8303f28a937baa53a187fb8c7d:/libsecurity_utilities/lib/refcount.h?ds=sidebyside diff --git a/libsecurity_utilities/lib/refcount.h b/libsecurity_utilities/lib/refcount.h index b5a72678..e68cf718 100644 --- a/libsecurity_utilities/lib/refcount.h +++ b/libsecurity_utilities/lib/refcount.h @@ -29,6 +29,7 @@ #define _SECURITY_REFCOUNT_H_ #include +#include namespace Security { @@ -70,14 +71,23 @@ public: protected: template friend class RefPointer; - void ref() const { ++mRefCount; RCDEBUG(UP, mRefCount); } - unsigned int unref() const { RCDEBUG(DOWN, mRefCount - 1); return --mRefCount; } + void ref() const + { + OSAtomicIncrement32(&mRefCount); + RCDEBUG(UP, mRefCount); + } + + unsigned int unref() const + { + RCDEBUG(DOWN, mRefCount - 1); + return OSAtomicDecrement32(&mRefCount); + } // if you call this for anything but debug output, you will go to hell (free handbasket included) unsigned int refCountForDebuggingOnly() const { return mRefCount; } private: - mutable AtomicCounter mRefCount; + volatile mutable int32_t mRefCount; }; @@ -111,7 +121,7 @@ public: T & operator * () const { _check(); return *ptr; } protected: - void release() + void release_internal() { if (ptr && ptr->unref() == 0) { @@ -120,11 +130,28 @@ protected: } } - void setPointer(T *p) { if (p) p->ref(); release(); ptr = p; } + void release() + { + StLock mutexLock(mMutex); + release_internal(); + } + + void setPointer(T *p) + { + StLock mutexLock(mMutex); + if (p) + { + p->ref(); + } + + release_internal(); + ptr = p; + } void _check() const { } T *ptr; + Mutex mMutex; }; template