]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/lock.hh
dnsdist: Wrap pthread_ objects
[thirdparty/pdns.git] / pdns / lock.hh
index 4a0c4a1161e789d139ecb820cdd405ace1489d6c..d3933059f5e2a5b5d5e3bf7b04b34c85ab8f5367 100644 (file)
@@ -19,9 +19,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-#ifndef LOCK_HH
-#define LOCK_HH
-
+#pragma once
 #include <pthread.h>
 #include <errno.h>
 #include "misc.hh"
@@ -40,8 +38,12 @@ public:
   {
     if(g_singleThreaded)
       return;
-    if((errno=pthread_mutex_lock(d_lock)))
+
+    int err;
+    if((err = pthread_mutex_lock(d_lock))) {
+      errno = err;
       throw PDNSException("error acquiring lock: "+stringerror());
+    }
   }
   ~Lock()
   {
@@ -52,6 +54,33 @@ public:
   }
 };
 
+class ReadWriteLock
+{
+public:
+  ReadWriteLock()
+  {
+    if (pthread_rwlock_init(&d_lock, nullptr) != 0) {
+      throw std::runtime_error("Error creating a read-write lock: " + stringerror());
+    }
+  }
+
+  ~ReadWriteLock() {
+    /* might have been moved */
+    pthread_rwlock_destroy(&d_lock);
+  }
+
+  ReadWriteLock(const ReadWriteLock& rhs) = delete;
+  ReadWriteLock& operator=(const ReadWriteLock& rhs) = delete;
+
+  pthread_rwlock_t* getLock()
+  {
+    return &d_lock;
+  }
+
+private:
+  pthread_rwlock_t d_lock;
+};
+
 class WriteLock
 {
   pthread_rwlock_t *d_lock;
@@ -62,8 +91,9 @@ public:
     if(g_singleThreaded)
       return;
 
-    if((errno=pthread_rwlock_wrlock(d_lock))) {
-      throw PDNSException("error acquiring rwlock wrlock: "+stringerror());
+    int err;
+    if((err = pthread_rwlock_wrlock(d_lock))) {
+      throw PDNSException("error acquiring rwlock wrlock: "+stringerror(err));
     }
   }
   ~WriteLock()
@@ -74,6 +104,14 @@ public:
       pthread_rwlock_unlock(d_lock);
   }
 
+  WriteLock(ReadWriteLock& lock): WriteLock(lock.getLock())
+  {
+  }
+
+  WriteLock(ReadWriteLock* lock): WriteLock(lock->getLock())
+  {
+  }
+
   WriteLock(WriteLock&& rhs)
   {
     d_lock = rhs.d_lock;
@@ -82,7 +120,6 @@ public:
   WriteLock(const WriteLock& rhs) = delete;
   WriteLock& operator=(const WriteLock& rhs) = delete;
 
-
 };
 
 class TryWriteLock
@@ -101,18 +138,29 @@ public:
     }
 
     d_havelock=false;
-    if((errno=pthread_rwlock_trywrlock(d_lock)) && errno!=EBUSY)
-      throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror());
-    d_havelock=(errno==0);
+    int err;
+    if((err = pthread_rwlock_trywrlock(d_lock)) && err!=EBUSY) {
+      throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror(err));
+    }
+    d_havelock=(err==0);
   }
 
   TryWriteLock(TryWriteLock&& rhs)
   {
     d_lock = rhs.d_lock;
-    rhs.d_lock=0;
+    rhs.d_lock = nullptr;
+    d_havelock = rhs.d_havelock;
+    rhs.d_havelock = false;
+  }
+
+  TryWriteLock(ReadWriteLock& lock): TryWriteLock(lock.getLock())
+  {
+  }
+
+  TryWriteLock(ReadWriteLock* lock): TryWriteLock(lock->getLock())
+  {
   }
 
-  
   ~TryWriteLock()
   {
     if(g_singleThreaded)
@@ -145,14 +193,27 @@ public:
       return;
     }
 
-    if((errno=pthread_rwlock_tryrdlock(d_lock)) && errno!=EBUSY)
-      throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror());
-    d_havelock=(errno==0);
+    int err;
+    if((err = pthread_rwlock_tryrdlock(d_lock)) && err!=EBUSY) {
+      throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror(err));
+    }
+    d_havelock=(err==0);
+  }
+
+  TryReadLock(ReadWriteLock& lock): TryReadLock(lock.getLock())
+  {
   }
+
+  TryReadLock(ReadWriteLock* lock): TryReadLock(lock->getLock())
+  {
+  }
+
   TryReadLock(TryReadLock&& rhs)
   {
     d_lock = rhs.d_lock;
-    rhs.d_lock=0;
+    rhs.d_lock = nullptr;
+    d_havelock = rhs.d_havelock;
+    rhs.d_havelock = false;
   }
 
   ~TryReadLock()
@@ -183,9 +244,20 @@ public:
     if(g_singleThreaded)
       return;
 
-    if((errno=pthread_rwlock_rdlock(d_lock)))
-      throw PDNSException("error acquiring rwlock readlock: "+stringerror());
+    int err;
+    if((err = pthread_rwlock_rdlock(d_lock))) {
+      throw PDNSException("error acquiring rwlock readlock: "+stringerror(err));
+    }
+  }
+
+  ReadLock(ReadWriteLock& lock): ReadLock(lock.getLock())
+  {
+  }
+
+  ReadLock(ReadWriteLock* lock): ReadLock(lock->getLock())
+  {
   }
+
   ~ReadLock()
   {
     if(g_singleThreaded)
@@ -197,9 +269,8 @@ public:
   ReadLock(ReadLock&& rhs)
   {
     d_lock = rhs.d_lock;
-    rhs.d_lock=0;
+    rhs.d_lock = nullptr;
   }
   ReadLock(const ReadLock& rhs) = delete;
   ReadLock& operator=(const ReadLock& rhs) = delete;
 };
-#endif