tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SQLiteMutex.h (3886B)


      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 public:
     25  /**
     26   * Constructs a wrapper for a sqlite3_mutex that has deadlock detecting.
     27   *
     28   * @param aName
     29   *        A name which can be used to reference this mutex.
     30   */
     31  explicit SQLiteMutex(const char* aName)
     32      : BlockingResourceBase(aName, eMutex), mMutex(nullptr) {}
     33 
     34  /**
     35   * Sets the mutex that we are wrapping.  We generally do not have access to
     36   * our mutex at class construction, so we have to set it once we get access to
     37   * it.
     38   *
     39   * @param aMutex
     40   *        The sqlite3_mutex that we are going to wrap.
     41   */
     42  void initWithMutex(sqlite3_mutex* aMutex) {
     43    MOZ_ASSERT(aMutex, "You must pass in a valid mutex!");
     44    MOZ_ASSERT(!mMutex, "A mutex has already been set for this!");
     45    mMutex = aMutex;
     46  }
     47 
     48  /**
     49   * After a connection has been successfully closed, its mutex is a dangling
     50   * pointer, and as such it should be destroyed.
     51   */
     52  void destroy() { mMutex = NULL; }
     53 
     54  /**
     55   * Acquires the mutex.
     56   */
     57  void lock() {
     58    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
     59 #if defined(DEBUG)
     60    // While SQLite Mutexes may be recursive, in our own code we do not want to
     61    // treat them as such.
     62    CheckAcquire();
     63 #endif
     64 
     65    ::sqlite3_mutex_enter(mMutex);
     66 
     67 #if defined(DEBUG)
     68    Acquire();  // Call is protected by us holding the mutex.
     69 #endif
     70  }
     71 
     72  /**
     73   * Releases the mutex.
     74   */
     75  void unlock() {
     76    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
     77 #if defined(DEBUG)
     78    // While SQLite Mutexes may be recursive, in our own code we do not want to
     79    // treat them as such.
     80    Release();  // Call is protected by us holding the mutex.
     81 #endif
     82 
     83    ::sqlite3_mutex_leave(mMutex);
     84  }
     85 
     86  /**
     87   * Asserts that the current thread owns the mutex.
     88   */
     89  void assertCurrentThreadOwns() {
     90    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
     91    MOZ_ASSERT(::sqlite3_mutex_held(mMutex),
     92               "Mutex is not held, but we expect it to be!");
     93  }
     94 
     95  /**
     96   * Asserts that the current thread does not own the mutex.
     97   */
     98  void assertNotCurrentThreadOwns() {
     99    MOZ_ASSERT(mMutex, "No mutex associated with this wrapper!");
    100    MOZ_ASSERT(::sqlite3_mutex_notheld(mMutex),
    101               "Mutex is held, but we expect it to not be!");
    102  }
    103 
    104 private:
    105  sqlite3_mutex* mMutex;
    106 };
    107 
    108 /**
    109 * Automatically acquires the mutex when it enters scope, and releases it when
    110 * it leaves scope.
    111 */
    112 class MOZ_STACK_CLASS SQLiteMutexAutoLock {
    113 public:
    114  explicit SQLiteMutexAutoLock(SQLiteMutex& aMutex) : mMutex(aMutex) {
    115    mMutex.lock();
    116  }
    117 
    118  ~SQLiteMutexAutoLock() { mMutex.unlock(); }
    119 
    120 private:
    121  SQLiteMutex& mMutex;
    122 };
    123 
    124 /**
    125 * Automatically releases the mutex when it enters scope, and acquires it when
    126 * it leaves scope.
    127 */
    128 class MOZ_STACK_CLASS SQLiteMutexAutoUnlock {
    129 public:
    130  explicit SQLiteMutexAutoUnlock(SQLiteMutex& aMutex) : mMutex(aMutex) {
    131    mMutex.unlock();
    132  }
    133 
    134  ~SQLiteMutexAutoUnlock() { mMutex.lock(); }
    135 
    136 private:
    137  SQLiteMutex& mMutex;
    138 };
    139 
    140 }  // namespace storage
    141 }  // namespace mozilla
    142 
    143 #endif  // mozilla_storage_SQLiteMutex_h_