X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..7e6b461318c8a779d91381531435a68ee4e8b6ed:/OSX/libsecurity_utilities/lib/threading.h?ds=inline diff --git a/OSX/libsecurity_utilities/lib/threading.h b/OSX/libsecurity_utilities/lib/threading.h index a903dc10..5886f047 100644 --- a/OSX/libsecurity_utilities/lib/threading.h +++ b/OSX/libsecurity_utilities/lib/threading.h @@ -152,6 +152,13 @@ public: ~RecursiveMutex() {} }; +class NormalMutex : public Mutex +{ +public: + NormalMutex() : Mutex(normal) {} + ~NormalMutex() {} +}; + // // Condition variables // @@ -197,7 +204,27 @@ public: private: unsigned int mCount; // counter level }; - + +// +// A ReadWriteLock is a wrapper around a pthread_rwlock +// +class ReadWriteLock : public Mutex { +public: + ReadWriteLock(); + ~ReadWriteLock() { check(pthread_rwlock_destroy(&mLock)); } + + // Takes the read lock + bool lock(); + bool tryLock(); + void unlock(); + + bool writeLock(); + bool tryWriteLock(); + +private: + pthread_rwlock_t mLock; +}; + // // A guaranteed-unlocker stack-based class. @@ -228,6 +255,58 @@ protected: bool mActive; }; +// +// This class behaves exactly as StLock above, but accepts a pointer to a mutex instead of a reference. +// If the pointer is NULL, this class does nothing. Otherwise, it behaves as StLock. +// Try not to use this. +// +template +class StMaybeLock { +public: + StMaybeLock(Lock *lck) : me(lck), mActive(false) + { if(me) { (me->*_lock)(); mActive = true; } } + StMaybeLock(Lock *lck, bool option) : me(lck), mActive(option) { } + ~StMaybeLock() { if (me) { if(mActive) (me->*_unlock)(); } else {mActive = false;} } + + bool isActive() const { return mActive; } + void lock() { if(me) { if(!mActive) { (me->*_lock)(); mActive = true; }}} + void unlock() { if(me) { if(mActive) { (me->*_unlock)(); mActive = false; }}} + void release() { if(me) { assert(mActive); mActive = false; } } + + operator const Lock &() const { return me; } + +protected: + Lock *me; + bool mActive; +}; + +// Note: if you use the TryRead or TryWrite modes, you must check if you +// actually have the lock before proceeding +class StReadWriteLock { +public: + enum Type { + Read, + TryRead, + Write, + TryWrite + }; + StReadWriteLock(ReadWriteLock &lck, Type type) : mType(type), mIsLocked(false), mRWLock(lck) + { lock(); } + ~StReadWriteLock() { if(mIsLocked) unlock(); } + + bool lock(); + void unlock(); + bool isLocked(); + +protected: + Type mType; + bool mIsLocked; + ReadWriteLock& mRWLock; +}; + + template