storage/src/SQLiteMutex.h

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:cf027b54147b
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef mozilla_storage_SQLiteMutex_h_
8 #define mozilla_storage_SQLiteMutex_h_
9
10 #include "mozilla/BlockingResourceBase.h"
11 #include "sqlite3.h"
12
13 namespace mozilla {
14 namespace storage {
15
16 /**
17 * Wrapper class for sqlite3_mutexes. To be used whenever we want to use a
18 * sqlite3_mutex.
19 *
20 * @warning Never EVER wrap the same sqlite3_mutex with a different SQLiteMutex.
21 * If you do this, you void the deadlock detector's warranty!
22 */
23 class SQLiteMutex : private BlockingResourceBase
24 {
25 public:
26 /**
27 * Constructs a wrapper for a sqlite3_mutex that has deadlock detecting.
28 *
29 * @param aName
30 * A name which can be used to reference this mutex.
31 */
32 SQLiteMutex(const char *aName)
33 : BlockingResourceBase(aName, eMutex)
34 , mMutex(nullptr)
35 {
36 }
37
38 /**
39 * Sets the mutex that we are wrapping. We generally do not have access to
40 * our mutex at class construction, so we have to set it once we get access to
41 * it.
42 *
43 * @param aMutex
44 * The sqlite3_mutex that we are going to wrap.
45 */
46 void initWithMutex(sqlite3_mutex *aMutex)
47 {
48 NS_ASSERTION(aMutex, "You must pass in a valid mutex!");
49 NS_ASSERTION(!mMutex, "A mutex has already been set for this!");
50 mMutex = aMutex;
51 }
52
53 #if !defined(DEBUG) || defined(MOZ_NATIVE_SQLITE)
54 /**
55 * Acquires the mutex.
56 */
57 void lock()
58 {
59 sqlite3_mutex_enter(mMutex);
60 }
61
62 /**
63 * Releases the mutex.
64 */
65 void unlock()
66 {
67 sqlite3_mutex_leave(mMutex);
68 }
69
70 /**
71 * Asserts that the current thread owns the mutex.
72 */
73 void assertCurrentThreadOwns()
74 {
75 }
76
77 /**
78 * Asserts that the current thread does not own the mutex.
79 */
80 void assertNotCurrentThreadOwns()
81 {
82 }
83
84 #else
85 void lock()
86 {
87 NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
88
89 // While SQLite Mutexes may be recursive, in our own code we do not want to
90 // treat them as such.
91 CallStack callContext = CallStack();
92
93 CheckAcquire(callContext);
94 sqlite3_mutex_enter(mMutex);
95 Acquire(callContext); // Call is protected by us holding the mutex.
96 }
97
98 void unlock()
99 {
100 NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
101
102 // While SQLite Mutexes may be recursive, in our own code we do not want to
103 // treat them as such.
104 Release(); // Call is protected by us holding the mutex.
105 sqlite3_mutex_leave(mMutex);
106 }
107
108 void assertCurrentThreadOwns()
109 {
110 NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
111 NS_ASSERTION(sqlite3_mutex_held(mMutex),
112 "Mutex is not held, but we expect it to be!");
113 }
114
115 void assertNotCurrentThreadOwns()
116 {
117 NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
118 NS_ASSERTION(sqlite3_mutex_notheld(mMutex),
119 "Mutex is held, but we expect it to not be!");
120 }
121 #endif // ifndef DEBUG
122
123 private:
124 sqlite3_mutex *mMutex;
125 };
126
127 /**
128 * Automatically acquires the mutex when it enters scope, and releases it when
129 * it leaves scope.
130 */
131 class MOZ_STACK_CLASS SQLiteMutexAutoLock
132 {
133 public:
134 SQLiteMutexAutoLock(SQLiteMutex &aMutex)
135 : mMutex(aMutex)
136 {
137 mMutex.lock();
138 }
139
140 ~SQLiteMutexAutoLock()
141 {
142 mMutex.unlock();
143 }
144
145 private:
146 SQLiteMutex &mMutex;
147 };
148
149 /**
150 * Automatically releases the mutex when it enters scope, and acquires it when
151 * it leaves scope.
152 */
153 class MOZ_STACK_CLASS SQLiteMutexAutoUnlock
154 {
155 public:
156 SQLiteMutexAutoUnlock(SQLiteMutex &aMutex)
157 : mMutex(aMutex)
158 {
159 mMutex.unlock();
160 }
161
162 ~SQLiteMutexAutoUnlock()
163 {
164 mMutex.lock();
165 }
166
167 private:
168 SQLiteMutex &mMutex;
169 };
170
171 } // namespace storage
172 } // namespace mozilla
173
174 #endif // mozilla_storage_SQLiteMutex_h_

mercurial