]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_utilities/lib/threading.h
Security-57740.20.22.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / threading.h
index 60168536e66e006ba4b877483713e11fb647216a..34a47636ab83f0c09e692a7b703913b4afaa3067 100644 (file)
@@ -248,6 +248,33 @@ 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 Lock,
+void (Lock::*_lock)() = &Lock::lock,
+void (Lock::*_unlock)() = &Lock::unlock>
+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 {