Browse Source

[2332] Make sure preUnlockAction() doesn't throw when it shouldn't.

adding a parameter to control that.
JINMEI Tatuya 12 years ago
parent
commit
7f94f671e0
2 changed files with 15 additions and 5 deletions
  1. 9 4
      src/lib/util/threads/lock.cc
  2. 6 1
      src/lib/util/threads/lock.h

+ 9 - 4
src/lib/util/threads/lock.cc

@@ -128,9 +128,14 @@ Mutex::lock() {
 }
 }
 
 
 void
 void
-Mutex::preUnlockAction() {
+Mutex::preUnlockAction(bool throw_ok) {
     if (impl_->locked_count == 0) {
     if (impl_->locked_count == 0) {
-        isc_throw(isc::InvalidOperation, "Unlock attempt for unlocked mutex");
+        if (throw_ok) {
+            isc_throw(isc::InvalidOperation,
+                      "Unlock attempt for unlocked mutex");
+        } else {
+            assert(false);
+        }
     }
     }
     --impl_->locked_count;
     --impl_->locked_count;
 }
 }
@@ -138,7 +143,7 @@ Mutex::preUnlockAction() {
 void
 void
 Mutex::unlock() {
 Mutex::unlock() {
     assert(impl_ != NULL);
     assert(impl_ != NULL);
-    preUnlockAction();          // Only in debug mode
+    preUnlockAction(false);     // Only in debug mode.  Ensure no throw.
     const int result = pthread_mutex_unlock(&impl_->mutex);
     const int result = pthread_mutex_unlock(&impl_->mutex);
     assert(result == 0); // This should never be possible
     assert(result == 0); // This should never be possible
 }
 }
@@ -181,7 +186,7 @@ CondVar::~CondVar() {
 
 
 void
 void
 CondVar::wait(Mutex& mutex) {
 CondVar::wait(Mutex& mutex) {
-    mutex.preUnlockAction();    // Only in debug mode
+    mutex.preUnlockAction(true);    // Only in debug mode
     const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
     const int result = pthread_cond_wait(&impl_->cond_, &mutex.impl_->mutex);
     mutex.postLockAction();     // Only in debug mode
     mutex.postLockAction();     // Only in debug mode
 
 

+ 6 - 1
src/lib/util/threads/lock.h

@@ -116,7 +116,12 @@ private:
 
 
     // Commonly called before releasing the lock, checking and updating
     // Commonly called before releasing the lock, checking and updating
     // internal state for debug.
     // internal state for debug.
-    void preUnlockAction();
+    //
+    // If throw_ok is true, it throws \c isc::InvalidOperation when the check
+    // fails; otherwise it aborts the process.  This parameter must be set
+    // to false if the call to this shouldn't result in an exception (e.g.
+    // when called from a destructor).
+    void preUnlockAction(bool throw_ok);
 
 
     class Impl;
     class Impl;
     Impl* impl_;
     Impl* impl_;