Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/storage/SQLiteMutex.h
Line
Count
Source (jump to first uncovered line)
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
  explicit SQLiteMutex(const char *aName)
33
  : BlockingResourceBase(aName, eMutex)
34
  , mMutex(nullptr)
35
0
  {
36
0
  }
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
0
  {
48
0
    NS_ASSERTION(aMutex, "You must pass in a valid mutex!");
49
0
    NS_ASSERTION(!mMutex, "A mutex has already been set for this!");
50
0
    mMutex = aMutex;
51
0
  }
52
53
  /**
54
   * After a connection has been successfully closed, its mutex is a dangling
55
   * pointer, and as such it should be destroyed.
56
   */
57
0
  void destroy() {
58
0
    mMutex = NULL;
59
0
  }
60
61
#if !defined(DEBUG) || defined(MOZ_SYSTEM_SQLITE)
62
  /**
63
   * Acquires the mutex.
64
   */
65
  void lock()
66
0
  {
67
0
    ::sqlite3_mutex_enter(mMutex);
68
0
  }
69
70
  /**
71
   * Releases the mutex.
72
   */
73
  void unlock()
74
0
  {
75
0
    ::sqlite3_mutex_leave(mMutex);
76
0
  }
77
78
  /**
79
   * Asserts that the current thread owns the mutex.
80
   */
81
  void assertCurrentThreadOwns()
82
0
  {
83
0
  }
84
85
  /**
86
   * Asserts that the current thread does not own the mutex.
87
   */
88
  void assertNotCurrentThreadOwns()
89
0
  {
90
0
  }
91
92
#else
93
  void lock()
94
  {
95
    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
96
97
    // While SQLite Mutexes may be recursive, in our own code we do not want to
98
    // treat them as such.
99
100
    CheckAcquire();
101
    ::sqlite3_mutex_enter(mMutex);
102
    Acquire(); // Call is protected by us holding the mutex.
103
  }
104
105
  void unlock()
106
  {
107
    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
108
109
    // While SQLite Mutexes may be recursive, in our own code we do not want to
110
    // treat them as such.
111
    Release(); // Call is protected by us holding the mutex.
112
    ::sqlite3_mutex_leave(mMutex);
113
  }
114
115
  void assertCurrentThreadOwns()
116
  {
117
    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
118
    MOZ_ASSERT(sqlite3_mutex_held(mMutex),
119
               "Mutex is not held, but we expect it to be!");
120
  }
121
122
  void assertNotCurrentThreadOwns()
123
  {
124
    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
125
    MOZ_ASSERT(sqlite3_mutex_notheld(mMutex),
126
               "Mutex is held, but we expect it to not be!");
127
  }
128
#endif // ifndef DEBUG
129
130
private:
131
  sqlite3_mutex *mMutex;
132
};
133
134
/**
135
 * Automatically acquires the mutex when it enters scope, and releases it when
136
 * it leaves scope.
137
 */
138
class MOZ_STACK_CLASS SQLiteMutexAutoLock
139
{
140
public:
141
  explicit SQLiteMutexAutoLock(SQLiteMutex &aMutex)
142
  : mMutex(aMutex)
143
0
  {
144
0
    mMutex.lock();
145
0
  }
146
147
  ~SQLiteMutexAutoLock()
148
0
  {
149
0
    mMutex.unlock();
150
0
  }
151
152
private:
153
  SQLiteMutex &mMutex;
154
};
155
156
/**
157
 * Automatically releases the mutex when it enters scope, and acquires it when
158
 * it leaves scope.
159
 */
160
class MOZ_STACK_CLASS SQLiteMutexAutoUnlock
161
{
162
public:
163
  explicit SQLiteMutexAutoUnlock(SQLiteMutex &aMutex)
164
  : mMutex(aMutex)
165
0
  {
166
0
    mMutex.unlock();
167
0
  }
168
169
  ~SQLiteMutexAutoUnlock()
170
0
  {
171
0
    mMutex.lock();
172
0
  }
173
174
private:
175
  SQLiteMutex &mMutex;
176
};
177
178
} // namespace storage
179
} // namespace mozilla
180
181
#endif // mozilla_storage_SQLiteMutex_h_