]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/lock.hh
dnsdist: Wrap pthread_ objects
[thirdparty/pdns.git] / pdns / lock.hh
index a20c2208f47ba38462f62058b8600d0826cb6139..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"
@@ -56,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;
@@ -68,8 +93,7 @@ public:
 
     int err;
     if((err = pthread_rwlock_wrlock(d_lock))) {
-      errno = err;
-      throw PDNSException("error acquiring rwlock wrlock: "+stringerror());
+      throw PDNSException("error acquiring rwlock wrlock: "+stringerror(err));
     }
   }
   ~WriteLock()
@@ -80,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;
@@ -88,7 +120,6 @@ public:
   WriteLock(const WriteLock& rhs) = delete;
   WriteLock& operator=(const WriteLock& rhs) = delete;
 
-
 };
 
 class TryWriteLock
@@ -109,8 +140,7 @@ public:
     d_havelock=false;
     int err;
     if((err = pthread_rwlock_trywrlock(d_lock)) && err!=EBUSY) {
-      errno = err;
-      throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror());
+      throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror(err));
     }
     d_havelock=(err==0);
   }
@@ -118,10 +148,19 @@ public:
   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)
@@ -156,15 +195,25 @@ public:
 
     int err;
     if((err = pthread_rwlock_tryrdlock(d_lock)) && err!=EBUSY) {
-      errno = err;
-      throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror());
+      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()
@@ -197,10 +246,18 @@ public:
 
     int err;
     if((err = pthread_rwlock_rdlock(d_lock))) {
-      errno = err;
-      throw PDNSException("error acquiring rwlock readlock: "+stringerror());
+      throw PDNSException("error acquiring rwlock readlock: "+stringerror(err));
     }
   }
+
+  ReadLock(ReadWriteLock& lock): ReadLock(lock.getLock())
+  {
+  }
+
+  ReadLock(ReadWriteLock* lock): ReadLock(lock->getLock())
+  {
+  }
+
   ~ReadLock()
   {
     if(g_singleThreaded)
@@ -212,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