]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mutex: assert we are unlocked by the same thread that locked
authorSage Weil <sage@inktank.com>
Tue, 17 Jul 2012 20:52:57 +0000 (13:52 -0700)
committerSage Weil <sage@inktank.com>
Fri, 27 Jul 2012 17:43:25 +0000 (10:43 -0700)
This only works for non-recursive locks.  (Which is probably all of them?)

Signed-off-by: Sage Weil <sage@inktank.com>
src/common/Cond.h
src/common/Mutex.h

index da44aedc70d1609b81f041e6c9136cf59062e110..ee95a65b5b6608fe03eaef1e57767df83b33745d 100644 (file)
@@ -51,9 +51,9 @@ class Cond {
 
     assert(mutex.is_locked());
 
-    --mutex.nlock;
+    mutex._pre_unlock();
     int r = pthread_cond_wait(&_c, &mutex._m);
-    ++mutex.nlock;
+    mutex._post_lock();
     return r;
   }
 
@@ -66,9 +66,11 @@ class Cond {
 
     struct timespec ts;
     when.to_timespec(&ts);
-    --mutex.nlock;
+
+    mutex._pre_unlock();
     int r = pthread_cond_timedwait(&_c, &mutex._m, &ts);
-    ++mutex.nlock;
+    mutex._post_lock();
+
     return r;
   }
   int WaitInterval(CephContext *cct, Mutex &mutex, utime_t interval) {
index 26c4f010d50994b8678911b16b781ea87249b6e6..1370c0e77012595516856ac485571f61b1eba4d8 100644 (file)
@@ -32,6 +32,7 @@ private:
 
   pthread_mutex_t _m;
   int nlock;
+  pthread_t locked_by;
 
   // don't allow copying.
   void operator=(Mutex &M) {}
@@ -52,7 +53,7 @@ private:
 
 public:
   Mutex(const char *n, bool r = false, bool ld=true, bool bt=false) :
-    name(n), id(-1), recursive(r), lockdep(ld), backtrace(bt), nlock(0) {
+    name(n), id(-1), recursive(r), lockdep(ld), backtrace(bt), nlock(0), locked_by(0) {
     if (recursive) {
       // Mutexes of type PTHREAD_MUTEX_RECURSIVE do all the same checks as
       // mutexes of type PTHREAD_MUTEX_ERRORCHECK.
@@ -98,7 +99,7 @@ public:
     int r = pthread_mutex_trylock(&_m);
     if (r == 0) {
       if (lockdep && g_lockdep) _locked();
-      nlock++;
+      _post_lock();
     }
     return r == 0;
   }
@@ -106,18 +107,29 @@ public:
   void Lock(bool no_lockdep=false) {
     if (lockdep && g_lockdep && !no_lockdep) _will_lock();
     int r = pthread_mutex_lock(&_m);
-    if (lockdep && g_lockdep) _locked();
     assert(r == 0);
-    if (!recursive)
+    if (lockdep && g_lockdep) _locked();
+    _post_lock();
+  }
+  void _post_lock() {
+    if (!recursive) {
       assert(nlock == 0);
+      locked_by = pthread_self();
+    };
     nlock++;
   }
 
-  void Unlock() {
+  void _pre_unlock() {
     assert(nlock > 0);
     --nlock;
-    if (!recursive)
+    if (!recursive) {
+      assert(locked_by == pthread_self());
+      locked_by = 0;
       assert(nlock == 0);
+    }
+  }
+  void Unlock() {
+    _pre_unlock();
     if (lockdep && g_lockdep) _will_unlock();
     int r = pthread_mutex_unlock(&_m);
     assert(r == 0);