Index: base/lock_impl_win.cc |
=================================================================== |
--- base/lock_impl_win.cc (revision 3595) |
+++ base/lock_impl_win.cc (working copy) |
@@ -3,8 +3,17 @@ |
// found in the LICENSE file. |
#include "base/lock_impl.h" |
+#include "base/logging.h" |
+// NOTE: Although windows critical sections support recursive locks, we do not |
+// allow this, and we will commonly fire a DCHECK() if a thread attempts to |
+// acquire the lock a second time (while already holding it). |
+ |
LockImpl::LockImpl() { |
+#ifndef NDEBUG |
+ recursion_count_shadow_ = 0; |
+ recursion_used_ = false; |
+#endif // NDEBUG |
// The second parameter is the spin count, for short-held locks it avoid the |
// contending thread from going to sleep which helps performance greatly. |
::InitializeCriticalSectionAndSpinCount(&os_lock_, 2000); |
@@ -15,14 +24,35 @@ |
} |
bool LockImpl::Try() { |
- return ::TryEnterCriticalSection(&os_lock_) != FALSE; |
+ if (::TryEnterCriticalSection(&os_lock_) != FALSE) { |
+#ifndef NDEBUG |
+ recursion_count_shadow_++; |
+ if (2 == recursion_count_shadow_ && !recursion_used_) { |
+ recursion_used_ = true; |
+ DCHECK(false); // Catch accidental redundant lock acquisition. |
+ } |
+#endif |
+ return true; |
+ } |
+ return false; |
} |
void LockImpl::Lock() { |
::EnterCriticalSection(&os_lock_); |
+#ifndef NDEBUG |
+ // ONLY access data after locking. |
+ recursion_count_shadow_++; |
+ if (2 == recursion_count_shadow_ && !recursion_used_) { |
+ recursion_used_ = true; |
+ DCHECK(false); // Catch accidental redundant lock acquisition. |
+ } |
+#endif // NDEBUG |
} |
void LockImpl::Unlock() { |
+#ifndef NDEBUG |
+ --recursion_count_shadow_; // ONLY access while lock is still held. |
+ DCHECK(0 <= recursion_count_shadow_); |
+#endif // NDEBUG |
::LeaveCriticalSection(&os_lock_); |
} |
- |