LCOV - code coverage report
Current view: top level - xpcom/threads - Mutex.h (source / functions) Hit Total Coverage
Test: output.info Lines: 36 36 100.0 %
Date: 2017-07-14 16:53:18 Functions: 20 23 87.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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_Mutex_h
       8             : #define mozilla_Mutex_h
       9             : 
      10             : #include "mozilla/BlockingResourceBase.h"
      11             : #include "mozilla/GuardObjects.h"
      12             : #include "mozilla/PlatformMutex.h"
      13             : 
      14             : //
      15             : // Provides:
      16             : //
      17             : //  - Mutex, a non-recursive mutex
      18             : //  - MutexAutoLock, an RAII class for ensuring that Mutexes are properly
      19             : //    locked and unlocked
      20             : //  - MutexAutoUnlock, complementary sibling to MutexAutoLock
      21             : //
      22             : //  - OffTheBooksMutex, a non-recursive mutex that doesn't do leak checking
      23             : //  - OffTheBooksMutexAuto{Lock,Unlock} - Like MutexAuto{Lock,Unlock}, but for
      24             : //    an OffTheBooksMutex.
      25             : //
      26             : // Using MutexAutoLock/MutexAutoUnlock etc. is MUCH preferred to making bare
      27             : // calls to Lock and Unlock.
      28             : //
      29             : namespace mozilla {
      30             : 
      31             : /**
      32             :  * OffTheBooksMutex is identical to Mutex, except that OffTheBooksMutex doesn't
      33             :  * include leak checking.  Sometimes you want to intentionally "leak" a mutex
      34             :  * until shutdown; in these cases, OffTheBooksMutex is for you.
      35             :  */
      36             : class OffTheBooksMutex : public detail::MutexImpl, BlockingResourceBase
      37             : {
      38             : public:
      39             :   /**
      40             :    * @param aName A name which can reference this lock
      41             :    * @returns If failure, nullptr
      42             :    *          If success, a valid Mutex* which must be destroyed
      43             :    *          by Mutex::DestroyMutex()
      44             :    **/
      45        1316 :   explicit OffTheBooksMutex(const char* aName)
      46        1316 :     : detail::MutexImpl()
      47             :     , BlockingResourceBase(aName, eMutex)
      48             : #ifdef DEBUG
      49        1316 :     , mOwningThread(nullptr)
      50             : #endif
      51             :   {
      52        1317 :   }
      53             : 
      54         249 :   ~OffTheBooksMutex()
      55         249 :   {
      56             : #ifdef DEBUG
      57         249 :     MOZ_ASSERT(!mOwningThread, "destroying a still-owned lock!");
      58             : #endif
      59         249 :   }
      60             : 
      61             : #ifndef DEBUG
      62             :   /**
      63             :    * Lock this mutex.
      64             :    **/
      65             :   void Lock() { this->lock(); }
      66             : 
      67             :   /**
      68             :    * Unlock this mutex.
      69             :    **/
      70             :   void Unlock() { this->unlock(); }
      71             : 
      72             :   /**
      73             :    * Assert that the current thread owns this mutex in debug builds.
      74             :    *
      75             :    * Does nothing in non-debug builds.
      76             :    **/
      77             :   void AssertCurrentThreadOwns() const {}
      78             : 
      79             :   /**
      80             :    * Assert that the current thread does not own this mutex.
      81             :    *
      82             :    * Note that this function is not implemented for debug builds *and*
      83             :    * non-debug builds due to difficulties in dealing with memory ordering.
      84             :    *
      85             :    * It is therefore mostly useful as documentation.
      86             :    **/
      87             :   void AssertNotCurrentThreadOwns() const {}
      88             : 
      89             : #else
      90             :   void Lock();
      91             :   void Unlock();
      92             : 
      93             :   void AssertCurrentThreadOwns() const;
      94             : 
      95        1066 :   void AssertNotCurrentThreadOwns() const
      96             :   {
      97             :     // FIXME bug 476536
      98        1066 :   }
      99             : 
     100             : #endif  // ifndef DEBUG
     101             : 
     102             : private:
     103             :   OffTheBooksMutex();
     104             :   OffTheBooksMutex(const OffTheBooksMutex&);
     105             :   OffTheBooksMutex& operator=(const OffTheBooksMutex&);
     106             : 
     107             :   friend class CondVar;
     108             : 
     109             : #ifdef DEBUG
     110             :   PRThread* mOwningThread;
     111             : #endif
     112             : };
     113             : 
     114             : /**
     115             :  * Mutex
     116             :  * When possible, use MutexAutoLock/MutexAutoUnlock to lock/unlock this
     117             :  * mutex within a scope, instead of calling Lock/Unlock directly.
     118             :  */
     119             : class Mutex : public OffTheBooksMutex
     120             : {
     121             : public:
     122        1269 :   explicit Mutex(const char* aName)
     123        1269 :     : OffTheBooksMutex(aName)
     124             :   {
     125        1270 :     MOZ_COUNT_CTOR(Mutex);
     126        1270 :   }
     127             : 
     128         249 :   ~Mutex()
     129         249 :   {
     130         249 :     MOZ_COUNT_DTOR(Mutex);
     131         249 :   }
     132             : 
     133             : private:
     134             :   Mutex();
     135             :   Mutex(const Mutex&);
     136             :   Mutex& operator=(const Mutex&);
     137             : };
     138             : 
     139             : template<typename T>
     140             : class MOZ_RAII BaseAutoUnlock;
     141             : 
     142             : /**
     143             :  * MutexAutoLock
     144             :  * Acquires the Mutex when it enters scope, and releases it when it leaves
     145             :  * scope.
     146             :  *
     147             :  * MUCH PREFERRED to bare calls to Mutex.Lock and Unlock.
     148             :  */
     149             : template<typename T>
     150             : class MOZ_RAII BaseAutoLock
     151             : {
     152             : public:
     153             :   /**
     154             :    * Constructor
     155             :    * The constructor aquires the given lock.  The destructor
     156             :    * releases the lock.
     157             :    *
     158             :    * @param aLock A valid mozilla::Mutex* returned by
     159             :    *              mozilla::Mutex::NewMutex.
     160             :    **/
     161       64963 :   explicit BaseAutoLock(T& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     162       64963 :     : mLock(&aLock)
     163             :   {
     164       64964 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     165       64965 :     NS_ASSERTION(mLock, "null mutex");
     166       64965 :     mLock->Lock();
     167       64958 :   }
     168             : 
     169       64932 :   ~BaseAutoLock(void)
     170             :   {
     171       64932 :     mLock->Unlock();
     172       64935 :   }
     173             : 
     174             : private:
     175             :   BaseAutoLock();
     176             :   BaseAutoLock(BaseAutoLock&);
     177             :   BaseAutoLock& operator=(BaseAutoLock&);
     178             :   static void* operator new(size_t) CPP_THROW_NEW;
     179             : 
     180             :   friend class BaseAutoUnlock<T>;
     181             : 
     182             :   T* mLock;
     183             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     184             : };
     185             : 
     186             : typedef BaseAutoLock<Mutex> MutexAutoLock;
     187             : typedef BaseAutoLock<OffTheBooksMutex> OffTheBooksMutexAutoLock;
     188             : 
     189             : /**
     190             :  * MutexAutoUnlock
     191             :  * Releases the Mutex when it enters scope, and re-acquires it when it leaves
     192             :  * scope.
     193             :  *
     194             :  * MUCH PREFERRED to bare calls to Mutex.Unlock and Lock.
     195             :  */
     196             : template<typename T>
     197             : class MOZ_RAII BaseAutoUnlock
     198             : {
     199             : public:
     200         727 :   explicit BaseAutoUnlock(T& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     201         727 :     : mLock(&aLock)
     202             :   {
     203         727 :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     204         727 :     NS_ASSERTION(mLock, "null lock");
     205         727 :     mLock->Unlock();
     206         727 :   }
     207             : 
     208             :   explicit BaseAutoUnlock(
     209             :     BaseAutoLock<T>& aAutoLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     210             :     : mLock(aAutoLock.mLock)
     211             :   {
     212             :     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     213             :     NS_ASSERTION(mLock, "null lock");
     214             :     mLock->Unlock();
     215             :   }
     216             : 
     217         727 :   ~BaseAutoUnlock()
     218             :   {
     219         727 :     mLock->Lock();
     220         727 :   }
     221             : 
     222             : private:
     223             :   BaseAutoUnlock();
     224             :   BaseAutoUnlock(BaseAutoUnlock&);
     225             :   BaseAutoUnlock& operator=(BaseAutoUnlock&);
     226             :   static void* operator new(size_t) CPP_THROW_NEW;
     227             : 
     228             :   T* mLock;
     229             :   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
     230             : };
     231             : 
     232             : typedef BaseAutoUnlock<Mutex> MutexAutoUnlock;
     233             : typedef BaseAutoUnlock<OffTheBooksMutex> OffTheBooksMutexAutoUnlock;
     234             : 
     235             : } // namespace mozilla
     236             : 
     237             : 
     238             : #endif // ifndef mozilla_Mutex_h

Generated by: LCOV version 1.13