1// Copyright (c) 2008, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#ifndef CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__
31#define CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__
32
33#include <windows.h>
34
35namespace google_breakpad {
36
37// Automatically enters the critical section in the constructor and leaves
38// the critical section in the destructor.
39class AutoCriticalSection {
40 public:
41  // Creates a new instance with the given critical section object
42  // and enters the critical section immediately.
43  explicit AutoCriticalSection(CRITICAL_SECTION* cs) : cs_(cs), taken_(false) {
44    assert(cs_);
45    Acquire();
46  }
47
48  // Destructor: leaves the critical section.
49  ~AutoCriticalSection() {
50    if (taken_) {
51      Release();
52    }
53  }
54
55  // Enters the critical section. Recursive Acquire() calls are not allowed.
56  void Acquire() {
57    assert(!taken_);
58    EnterCriticalSection(cs_);
59    taken_ = true;
60  }
61
62  // Leaves the critical section. The caller should not call Release() unless
63  // the critical seciton has been entered already.
64  void Release() {
65    assert(taken_);
66    taken_ = false;
67    LeaveCriticalSection(cs_);
68  }
69
70 private:
71  // Disable copy ctor and operator=.
72  AutoCriticalSection(const AutoCriticalSection&);
73  AutoCriticalSection& operator=(const AutoCriticalSection&);
74
75  CRITICAL_SECTION* cs_;
76  bool taken_;
77};
78
79}  // namespace google_breakpad
80
81#endif  // CLIENT_WINDOWS_COMMON_AUTO_CRITICAL_SECTION_H__
82