LCOV - code coverage report
Current view: top level - xpcom/base - StaticMutex.h (source / functions) Hit Total Coverage
Test: output.info Lines: 19 20 95.0 %
Date: 2017-07-14 16:53:18 Functions: 5 5 100.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_StaticMutex_h
       8             : #define mozilla_StaticMutex_h
       9             : 
      10             : #include "mozilla/Atomics.h"
      11             : #include "mozilla/Mutex.h"
      12             : 
      13             : namespace mozilla {
      14             : 
      15             : /**
      16             :  * StaticMutex is a Mutex that can (and in fact, must) be used as a
      17             :  * global/static variable.
      18             :  *
      19             :  * The main reason to use StaticMutex as opposed to
      20             :  * StaticAutoPtr<OffTheBooksMutex> is that we instantiate the StaticMutex in a
      21             :  * thread-safe manner the first time it's used.
      22             :  *
      23             :  * The same caveats that apply to StaticAutoPtr apply to StaticMutex.  In
      24             :  * particular, do not use StaticMutex as a stack variable or a class instance
      25             :  * variable, because this class relies on the fact that global variablies are
      26             :  * initialized to 0 in order to initialize mMutex.  It is only safe to use
      27             :  * StaticMutex as a global or static variable.
      28             :  */
      29             : class MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS StaticMutex
      30             : {
      31             : public:
      32             :   // In debug builds, check that mMutex is initialized for us as we expect by
      33             :   // the compiler.  In non-debug builds, don't declare a constructor so that
      34             :   // the compiler can see that the constructor is trivial.
      35             : #ifdef DEBUG
      36         120 :   StaticMutex()
      37         120 :   {
      38         120 :     MOZ_ASSERT(!mMutex);
      39         120 :   }
      40             : #endif
      41             : 
      42        6775 :   void Lock()
      43             :   {
      44        6775 :     Mutex()->Lock();
      45        6775 :   }
      46             : 
      47        6775 :   void Unlock()
      48             :   {
      49        6775 :     Mutex()->Unlock();
      50        6775 :   }
      51             : 
      52          79 :   void AssertCurrentThreadOwns()
      53             :   {
      54             : #ifdef DEBUG
      55          79 :     Mutex()->AssertCurrentThreadOwns();
      56             : #endif
      57          79 :   }
      58             : 
      59             : private:
      60       13628 :   OffTheBooksMutex* Mutex()
      61             :   {
      62       13628 :     if (mMutex) {
      63       13587 :       return mMutex;
      64             :     }
      65             : 
      66          41 :     OffTheBooksMutex* mutex = new OffTheBooksMutex("StaticMutex");
      67          41 :     if (!mMutex.compareExchange(nullptr, mutex)) {
      68           0 :       delete mutex;
      69             :     }
      70             : 
      71          41 :     return mMutex;
      72             :   }
      73             : 
      74             :   Atomic<OffTheBooksMutex*> mMutex;
      75             : 
      76             : 
      77             :   // Disallow copy constructor, but only in debug mode.  We only define
      78             :   // a default constructor in debug mode (see above); if we declared
      79             :   // this constructor always, the compiler wouldn't generate a trivial
      80             :   // default constructor for us in non-debug mode.
      81             : #ifdef DEBUG
      82             :   StaticMutex(StaticMutex& aOther);
      83             : #endif
      84             : 
      85             :   // Disallow these operators.
      86             :   StaticMutex& operator=(StaticMutex* aRhs);
      87             :   static void* operator new(size_t) CPP_THROW_NEW;
      88             :   static void operator delete(void*);
      89             : };
      90             : 
      91             : typedef BaseAutoLock<StaticMutex> StaticMutexAutoLock;
      92             : typedef BaseAutoUnlock<StaticMutex> StaticMutexAutoUnlock;
      93             : 
      94             : } // namespace mozilla
      95             : 
      96             : #endif

Generated by: LCOV version 1.13