Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: base/lock.h

Issue 5630: Disallow Lock class support for recursive locking (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/lock.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_LOCK_H_ 5 #ifndef BASE_LOCK_H_
6 #define BASE_LOCK_H_ 6 #define BASE_LOCK_H_
7 7
8 #include "base/lock_impl.h" 8 #include "base/lock_impl.h"
9 9
10 // A convenient wrapper for a critical section. 10 // A convenient wrapper for an OS specific critical section.
11 // 11 //
12 // NOTE: A thread may acquire the same lock multiple times, but it must call 12 // NOTE: Although windows critical sections support recursive locks, we do not
13 // Release for each call to Acquire in order to finally release the lock. 13 // allow this, and we will commonly fire a DCHECK() if a thread attempts to
14 // acquire the lock a second time (while already holding it).
14 // 15 //
15 // Complication: UnitTest for DeathTests catch DCHECK exceptions, so we need 16 // Complication: UnitTest for DeathTests catch DCHECK exceptions, so we need
16 // to write code assuming DCHECK will throw. This means we need to save any 17 // to write code assuming DCHECK will throw. This means we need to save any
17 // assertable value in a local until we can safely throw. 18 // assertable value in a local until we can safely throw.
19
18 class Lock { 20 class Lock {
19 public: 21 public:
20 Lock(); 22 Lock();
21 ~Lock(); 23 ~Lock();
22 void Acquire(); 24 void Acquire();
23 void Release(); 25 void Release();
24 // If the lock is not held, take it and return true. If the lock is already 26 // If the lock is not held, take it and return true. If the lock is already
25 // held by something else, immediately return false. 27 // held by another thread, immediately return false.
26 bool Try(); 28 bool Try();
27 29
28 // Return the underlying lock implementation. 30 // Return the underlying lock implementation.
29 // TODO(awalker): refactor lock and condition variables so that this is 31 // TODO(awalker): refactor lock and condition variables so that this is
30 // unnecessary. 32 // unnecessary.
31 LockImpl* lock_impl() { return &lock_; } 33 LockImpl* lock_impl() { return &lock_; }
32 34
33 private: 35 private:
34 LockImpl lock_; // User-supplied underlying lock implementation. 36 LockImpl lock_; // User-supplied underlying lock implementation.
35 37
36 // All private data is implicitly protected by spin_lock_. 38 #ifndef NDEBUG
37 // Be VERY careful to only access under that lock. 39 // All private data is implicitly protected by lock_.
40 // Be VERY careful to only access members under that lock.
38 int32 recursion_count_shadow_; 41 int32 recursion_count_shadow_;
39 42 bool recursion_used_; // Allow debugging to continued after a DCHECK().
40 // Allow access to GetCurrentThreadRecursionCount() 43 int32 acquisition_count_; // Number of times lock was acquired.
41 friend class AutoUnlock; 44 int32 contention_count_; // Number of times there was contention.
42 int32 GetCurrentThreadRecursionCount();
43
44 #ifndef NDEBUG
45 // Even in Debug mode, the expensive tallies won't be calculated by default.
46 bool recursion_used_;
47 int32 acquisition_count_;
48
49 int32 contention_count_;
50 #endif // NDEBUG 45 #endif // NDEBUG
51 46
52 DISALLOW_COPY_AND_ASSIGN(Lock); 47 DISALLOW_COPY_AND_ASSIGN(Lock);
53 }; 48 };
54 49
55 // A helper class that acquires the given Lock while the AutoLock is in scope. 50 // A helper class that acquires the given Lock while the AutoLock is in scope.
56 class AutoLock { 51 class AutoLock {
57 public: 52 public:
58 explicit AutoLock(Lock& lock) : lock_(lock) { 53 explicit AutoLock(Lock& lock) : lock_(lock) {
59 lock_.Acquire(); 54 lock_.Acquire();
60 } 55 }
61 56
62 ~AutoLock() { 57 ~AutoLock() {
63 lock_.Release(); 58 lock_.Release();
64 } 59 }
65 60
66 private: 61 private:
67 Lock& lock_; 62 Lock& lock_;
68 DISALLOW_COPY_AND_ASSIGN(AutoLock); 63 DISALLOW_COPY_AND_ASSIGN(AutoLock);
69 }; 64 };
70 65
71 // AutoUnlock is a helper class for ConditionVariable instances 66 // AutoUnlock is a helper class for ConditionVariable that will Release() the
72 // that is analogous to AutoLock. It provides for nested Releases 67 // lock argument in the constructor, and re-Acquire() it in the destructor.
73 // of a lock for the Wait functionality of a ConditionVariable class.
74 // The destructor automatically does the corresponding Acquire
75 // calls (to return to the initial nested lock state).
76
77 // Instances of AutoUnlock can ***ONLY*** validly be constructed if the
78 // caller currently holds the lock provided as the constructor's argument.
79 // If that ***REQUIREMENT*** is violated in debug mode, a DCHECK will
80 // be generated in the Lock class. In production (non-debug),
81 // the results are undefined (and probably bad) if the caller
82 // is not already holding the indicated lock.
83 class ConditionVariable; 68 class ConditionVariable;
84 class AutoUnlock { 69 class AutoUnlock {
85 private: // Everything is private, so only our friend can use us. 70 private: // Everything is private, so only our friend can use us.
86 friend class ConditionVariable; // The only user of this class. 71 friend class ConditionVariable; // The only user of this class.
87 explicit AutoUnlock(Lock& lock); 72
88 ~AutoUnlock(); 73 explicit AutoUnlock(Lock& lock) : lock_(&lock) {
74 // We require our caller to have the lock.
75 lock_->Release();
76 }
77
78 ~AutoUnlock() {
79 lock_->Acquire();
80 }
89 81
90 Lock* lock_; 82 Lock* lock_;
91 int release_count_;
92 }; 83 };
93 84
94 #endif // BASE_LOCK_H_ 85 #endif // BASE_LOCK_H_
95 86
OLDNEW
« no previous file with comments | « no previous file | base/lock.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698