]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_utilities/lib/threading.h
Security-59306.61.1.tar.gz
[apple/security.git] / OSX / libsecurity_utilities / lib / threading.h
index a903dc100b96bf5ed1db9f4598f4a3ae85cd85f5..5886f0475c61567447b3fb7965689b6f0667defd 100644 (file)
@@ -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 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 {
+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 <class TakeLock, class ReleaseLock,
        void (TakeLock::*_lock)() = &TakeLock::lock,
        void (TakeLock::*_unlock)() = &TakeLock::unlock,
@@ -301,25 +380,6 @@ public:
 //
 class Thread {
     NOCOPY(Thread)
-public:
-    class Identity {
-        friend class Thread;
-        
-        Identity(pthread_t id) : mIdent(id) { }
-    public:
-        Identity() { }
-        
-        static Identity current()      { return pthread_self(); }
-
-        bool operator == (const Identity &other) const
-        { return pthread_equal(mIdent, other.mIdent); }
-        
-        bool operator != (const Identity &other) const
-        { return !(*this == other); }
-    
-    private:
-        pthread_t mIdent;
-    };
 
 public:
     Thread() { }                               // constructor
@@ -333,8 +393,6 @@ protected:
     virtual void action() = 0;         // the action to be performed
 
 private:
-    Identity self;                             // my own identity (instance constant)
-
     static void *runner(void *); // argument to pthread_create
 };