storage/src/SQLiteMutex.h

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     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/. */
     7 #ifndef mozilla_storage_SQLiteMutex_h_
     8 #define mozilla_storage_SQLiteMutex_h_
    10 #include "mozilla/BlockingResourceBase.h"
    11 #include "sqlite3.h"
    13 namespace mozilla {
    14 namespace storage {
    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   }
    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   }
    53 #if !defined(DEBUG) || defined(MOZ_NATIVE_SQLITE)
    54   /**
    55    * Acquires the mutex.
    56    */
    57   void lock()
    58   {
    59     sqlite3_mutex_enter(mMutex);
    60   }
    62   /**
    63    * Releases the mutex.
    64    */
    65   void unlock()
    66   {
    67     sqlite3_mutex_leave(mMutex);
    68   }
    70   /**
    71    * Asserts that the current thread owns the mutex.
    72    */
    73   void assertCurrentThreadOwns()
    74   {
    75   }
    77   /**
    78    * Asserts that the current thread does not own the mutex.
    79    */
    80   void assertNotCurrentThreadOwns()
    81   {
    82   }
    84 #else
    85   void lock()
    86   {
    87     NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
    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();
    93     CheckAcquire(callContext);
    94     sqlite3_mutex_enter(mMutex);
    95     Acquire(callContext); // Call is protected by us holding the mutex.
    96   }
    98   void unlock()
    99   {
   100     NS_ASSERTION(mMutex, "No mutex associated with this wrapper!");
   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   }
   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   }
   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
   123 private:
   124   sqlite3_mutex *mMutex;
   125 };
   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   }
   140   ~SQLiteMutexAutoLock()
   141   {
   142     mMutex.unlock();
   143   }
   145 private:
   146   SQLiteMutex &mMutex;
   147 };
   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   }
   162   ~SQLiteMutexAutoUnlock()
   163   {
   164     mMutex.lock();
   165   }
   167 private:
   168   SQLiteMutex &mMutex;
   169 };
   171 } // namespace storage
   172 } // namespace mozilla
   174 #endif // mozilla_storage_SQLiteMutex_h_

mercurial