Index: base/lock.h |
=================================================================== |
--- base/lock.h (revision 3066) |
+++ base/lock.h (working copy) |
@@ -7,14 +7,16 @@ |
#include "base/lock_impl.h" |
-// A convenient wrapper for a critical section. |
+// A convenient wrapper for an OS specific critical section. |
// |
-// NOTE: A thread may acquire the same lock multiple times, but it must call |
-// Release for each call to Acquire in order to finally release the lock. |
+// 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). |
// |
// Complication: UnitTest for DeathTests catch DCHECK exceptions, so we need |
// to write code assuming DCHECK will throw. This means we need to save any |
// assertable value in a local until we can safely throw. |
+ |
class Lock { |
public: |
Lock(); |
@@ -22,7 +24,7 @@ |
void Acquire(); |
void Release(); |
// If the lock is not held, take it and return true. If the lock is already |
- // held by something else, immediately return false. |
+ // held by another thread, immediately return false. |
bool Try(); |
// Return the underlying lock implementation. |
@@ -33,20 +35,13 @@ |
private: |
LockImpl lock_; // User-supplied underlying lock implementation. |
- // All private data is implicitly protected by spin_lock_. |
- // Be VERY careful to only access under that lock. |
- int32 recursion_count_shadow_; |
- |
- // Allow access to GetCurrentThreadRecursionCount() |
- friend class AutoUnlock; |
- int32 GetCurrentThreadRecursionCount(); |
- |
#ifndef NDEBUG |
- // Even in Debug mode, the expensive tallies won't be calculated by default. |
- bool recursion_used_; |
- int32 acquisition_count_; |
- |
- int32 contention_count_; |
+ // All private data is implicitly protected by lock_. |
+ // Be VERY careful to only access members under that lock. |
+ int32 recursion_count_shadow_; |
+ bool recursion_used_; // Allow debugging to continued after a DCHECK(). |
+ int32 acquisition_count_; // Number of times lock was acquired. |
+ int32 contention_count_; // Number of times there was contention. |
#endif // NDEBUG |
DISALLOW_COPY_AND_ASSIGN(Lock); |
@@ -68,27 +63,23 @@ |
DISALLOW_COPY_AND_ASSIGN(AutoLock); |
}; |
-// AutoUnlock is a helper class for ConditionVariable instances |
-// that is analogous to AutoLock. It provides for nested Releases |
-// of a lock for the Wait functionality of a ConditionVariable class. |
-// The destructor automatically does the corresponding Acquire |
-// calls (to return to the initial nested lock state). |
- |
-// Instances of AutoUnlock can ***ONLY*** validly be constructed if the |
-// caller currently holds the lock provided as the constructor's argument. |
-// If that ***REQUIREMENT*** is violated in debug mode, a DCHECK will |
-// be generated in the Lock class. In production (non-debug), |
-// the results are undefined (and probably bad) if the caller |
-// is not already holding the indicated lock. |
+// AutoUnlock is a helper class for ConditionVariable that will Release() the |
+// lock argument in the constructor, and re-Acquire() it in the destructor. |
class ConditionVariable; |
class AutoUnlock { |
private: // Everything is private, so only our friend can use us. |
friend class ConditionVariable; // The only user of this class. |
- explicit AutoUnlock(Lock& lock); |
- ~AutoUnlock(); |
+ explicit AutoUnlock(Lock& lock) : lock_(&lock) { |
+ // We require our caller to have the lock. |
+ lock_->Release(); |
+ } |
+ |
+ ~AutoUnlock() { |
+ lock_->Acquire(); |
+ } |
+ |
Lock* lock_; |
- int release_count_; |
}; |
#endif // BASE_LOCK_H_ |