aboutsummaryrefslogtreecommitdiff
path: root/src/client/windows/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/windows/common')
-rw-r--r--src/client/windows/common/auto_critical_section.h22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/client/windows/common/auto_critical_section.h b/src/client/windows/common/auto_critical_section.h
index 82c7b7f1..a2076b04 100644
--- a/src/client/windows/common/auto_critical_section.h
+++ b/src/client/windows/common/auto_critical_section.h
@@ -40,14 +40,31 @@ class AutoCriticalSection {
public:
// Creates a new instance with the given critical section object
// and enters the critical section immediately.
- explicit AutoCriticalSection(CRITICAL_SECTION* cs) : cs_(cs) {
+ explicit AutoCriticalSection(CRITICAL_SECTION* cs) : cs_(cs), taken_(false) {
assert(cs_);
- EnterCriticalSection(cs_);
+ Acquire();
}
// Destructor: leaves the critical section.
~AutoCriticalSection() {
+ if (taken_) {
+ Release();
+ }
+ }
+
+ // Enters the critical section. Recursive Acquire() calls are not allowed.
+ void Acquire() {
+ assert(!taken_);
+ EnterCriticalSection(cs_);
+ taken_ = true;
+ }
+
+ // Leaves the critical section. The caller should not call Release() unless
+ // the critical seciton has been entered already.
+ void Release() {
+ assert(taken_);
LeaveCriticalSection(cs_);
+ taken_ = false;
}
private:
@@ -56,6 +73,7 @@ class AutoCriticalSection {
AutoCriticalSection& operator=(const AutoCriticalSection&);
CRITICAL_SECTION* cs_;
+ bool taken_;
};
} // namespace google_breakpad