LCOV - code coverage report
Current view: top level - xpcom/threads - ReentrantMonitor.h (source / functions) Hit Total Coverage
Test: output.info Lines: 34 49 69.4 %
Date: 2017-07-14 16:53:18 Functions: 9 13 69.2 %
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_ReentrantMonitor_h
       8             : #define mozilla_ReentrantMonitor_h
       9             : 
      10             : #include "prmon.h"
      11             : 
      12             : #ifdef MOZILLA_INTERNAL_API
      13             : #include "GeckoProfiler.h"
      14             : #endif //MOZILLA_INTERNAL_API
      15             : 
      16             : #include "mozilla/BlockingResourceBase.h"
      17             : 
      18             : //
      19             : // Provides:
      20             : //
      21             : //  - ReentrantMonitor, a Java-like monitor
      22             : //  - ReentrantMonitorAutoEnter, an RAII class for ensuring that
      23             : //    ReentrantMonitors are properly entered and exited
      24             : //
      25             : // Using ReentrantMonitorAutoEnter is MUCH preferred to making bare calls to
      26             : // ReentrantMonitor.Enter and Exit.
      27             : //
      28             : namespace mozilla {
      29             : 
      30             : 
      31             : /**
      32             :  * ReentrantMonitor
      33             :  * Java-like monitor.
      34             :  * When possible, use ReentrantMonitorAutoEnter to hold this monitor within a
      35             :  * scope, instead of calling Enter/Exit directly.
      36             :  **/
      37             : class ReentrantMonitor : BlockingResourceBase
      38             : {
      39             : public:
      40             :   /**
      41             :    * ReentrantMonitor
      42             :    * @param aName A name which can reference this monitor
      43             :    */
      44         277 :   explicit ReentrantMonitor(const char* aName)
      45         277 :     : BlockingResourceBase(aName, eReentrantMonitor)
      46             : #ifdef DEBUG
      47         277 :     , mEntryCount(0)
      48             : #endif
      49             :   {
      50         277 :     MOZ_COUNT_CTOR(ReentrantMonitor);
      51         277 :     mReentrantMonitor = PR_NewMonitor();
      52         277 :     if (!mReentrantMonitor) {
      53           0 :       MOZ_CRASH("Can't allocate mozilla::ReentrantMonitor");
      54             :     }
      55         277 :   }
      56             : 
      57             :   /**
      58             :    * ~ReentrantMonitor
      59             :    **/
      60         232 :   ~ReentrantMonitor()
      61         232 :   {
      62         232 :     NS_ASSERTION(mReentrantMonitor,
      63             :                  "improperly constructed ReentrantMonitor or double free");
      64         232 :     PR_DestroyMonitor(mReentrantMonitor);
      65         232 :     mReentrantMonitor = 0;
      66         232 :     MOZ_COUNT_DTOR(ReentrantMonitor);
      67         232 :   }
      68             : 
      69             : #ifndef DEBUG
      70             :   /**
      71             :    * Enter
      72             :    * @see prmon.h
      73             :    **/
      74             :   void Enter() { PR_EnterMonitor(mReentrantMonitor); }
      75             : 
      76             :   /**
      77             :    * Exit
      78             :    * @see prmon.h
      79             :    **/
      80             :   void Exit() { PR_ExitMonitor(mReentrantMonitor); }
      81             : 
      82             :   /**
      83             :    * Wait
      84             :    * @see prmon.h
      85             :    **/
      86             :   nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
      87             :   {
      88             : #ifdef MOZILLA_INTERNAL_API
      89             :     AutoProfilerThreadSleep sleep;
      90             : #endif //MOZILLA_INTERNAL_API
      91             :     return PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ?
      92             :       NS_OK : NS_ERROR_FAILURE;
      93             :   }
      94             : 
      95             : #else // ifndef DEBUG
      96             :   void Enter();
      97             :   void Exit();
      98             :   nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT);
      99             : 
     100             : #endif  // ifndef DEBUG
     101             : 
     102             :   /**
     103             :    * Notify
     104             :    * @see prmon.h
     105             :    **/
     106          56 :   nsresult Notify()
     107             :   {
     108          56 :     return PR_Notify(mReentrantMonitor) == PR_SUCCESS ? NS_OK :
     109          56 :                                                         NS_ERROR_FAILURE;
     110             :   }
     111             : 
     112             :   /**
     113             :    * NotifyAll
     114             :    * @see prmon.h
     115             :    **/
     116           0 :   nsresult NotifyAll()
     117             :   {
     118           0 :     return PR_NotifyAll(mReentrantMonitor) == PR_SUCCESS ? NS_OK :
     119           0 :                                                            NS_ERROR_FAILURE;
     120             :   }
     121             : 
     122             : #ifdef DEBUG
     123             :   /**
     124             :    * AssertCurrentThreadIn
     125             :    * @see prmon.h
     126             :    **/
     127        6685 :   void AssertCurrentThreadIn()
     128             :   {
     129        6685 :     PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mReentrantMonitor);
     130        6685 :   }
     131             : 
     132             :   /**
     133             :    * AssertNotCurrentThreadIn
     134             :    * @see prmon.h
     135             :    **/
     136          36 :   void AssertNotCurrentThreadIn()
     137             :   {
     138             :     // FIXME bug 476536
     139          36 :   }
     140             : 
     141             : #else
     142             :   void AssertCurrentThreadIn() {}
     143             :   void AssertNotCurrentThreadIn() {}
     144             : 
     145             : #endif  // ifdef DEBUG
     146             : 
     147             : private:
     148             :   ReentrantMonitor();
     149             :   ReentrantMonitor(const ReentrantMonitor&);
     150             :   ReentrantMonitor& operator=(const ReentrantMonitor&);
     151             : 
     152             :   PRMonitor* mReentrantMonitor;
     153             : #ifdef DEBUG
     154             :   int32_t mEntryCount;
     155             : #endif
     156             : };
     157             : 
     158             : 
     159             : /**
     160             :  * ReentrantMonitorAutoEnter
     161             :  * Enters the ReentrantMonitor when it enters scope, and exits it when
     162             :  * it leaves scope.
     163             :  *
     164             :  * MUCH PREFERRED to bare calls to ReentrantMonitor.Enter and Exit.
     165             :  */
     166             : class MOZ_STACK_CLASS ReentrantMonitorAutoEnter
     167             : {
     168             : public:
     169             :   /**
     170             :    * Constructor
     171             :    * The constructor aquires the given lock.  The destructor
     172             :    * releases the lock.
     173             :    *
     174             :    * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*.
     175             :    **/
     176        8398 :   explicit ReentrantMonitorAutoEnter(mozilla::ReentrantMonitor& aReentrantMonitor)
     177        8398 :     : mReentrantMonitor(&aReentrantMonitor)
     178             :   {
     179        8398 :     NS_ASSERTION(mReentrantMonitor, "null monitor");
     180        8398 :     mReentrantMonitor->Enter();
     181        8398 :   }
     182             : 
     183        8398 :   ~ReentrantMonitorAutoEnter(void)
     184        8398 :   {
     185        8398 :     mReentrantMonitor->Exit();
     186        8398 :   }
     187             : 
     188          56 :   nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
     189             :   {
     190          56 :     return mReentrantMonitor->Wait(aInterval);
     191             :   }
     192             : 
     193          56 :   nsresult Notify() { return mReentrantMonitor->Notify(); }
     194           0 :   nsresult NotifyAll() { return mReentrantMonitor->NotifyAll(); }
     195             : 
     196             : private:
     197             :   ReentrantMonitorAutoEnter();
     198             :   ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
     199             :   ReentrantMonitorAutoEnter& operator=(const ReentrantMonitorAutoEnter&);
     200             :   static void* operator new(size_t) CPP_THROW_NEW;
     201             : 
     202             :   friend class ReentrantMonitorAutoExit;
     203             : 
     204             :   mozilla::ReentrantMonitor* mReentrantMonitor;
     205             : };
     206             : 
     207             : /**
     208             :  * ReentrantMonitorAutoExit
     209             :  * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves
     210             :  * scope.
     211             :  *
     212             :  * MUCH PREFERRED to bare calls to ReentrantMonitor.Exit and Enter.
     213             :  */
     214             : class MOZ_STACK_CLASS ReentrantMonitorAutoExit
     215             : {
     216             : public:
     217             :   /**
     218             :    * Constructor
     219             :    * The constructor releases the given lock.  The destructor
     220             :    * acquires the lock. The lock must be held before constructing
     221             :    * this object!
     222             :    *
     223             :    * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. It
     224             :    *                 must be already locked.
     225             :    **/
     226           0 :   explicit ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor)
     227           0 :     : mReentrantMonitor(&aReentrantMonitor)
     228             :   {
     229           0 :     NS_ASSERTION(mReentrantMonitor, "null monitor");
     230           0 :     mReentrantMonitor->AssertCurrentThreadIn();
     231           0 :     mReentrantMonitor->Exit();
     232           0 :   }
     233             : 
     234             :   explicit ReentrantMonitorAutoExit(
     235             :     ReentrantMonitorAutoEnter& aReentrantMonitorAutoEnter)
     236             :     : mReentrantMonitor(aReentrantMonitorAutoEnter.mReentrantMonitor)
     237             :   {
     238             :     NS_ASSERTION(mReentrantMonitor, "null monitor");
     239             :     mReentrantMonitor->AssertCurrentThreadIn();
     240             :     mReentrantMonitor->Exit();
     241             :   }
     242             : 
     243           0 :   ~ReentrantMonitorAutoExit(void)
     244           0 :   {
     245           0 :     mReentrantMonitor->Enter();
     246           0 :   }
     247             : 
     248             : private:
     249             :   ReentrantMonitorAutoExit();
     250             :   ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);
     251             :   ReentrantMonitorAutoExit& operator=(const ReentrantMonitorAutoExit&);
     252             :   static void* operator new(size_t) CPP_THROW_NEW;
     253             : 
     254             :   ReentrantMonitor* mReentrantMonitor;
     255             : };
     256             : 
     257             : } // namespace mozilla
     258             : 
     259             : 
     260             : #endif // ifndef mozilla_ReentrantMonitor_h

Generated by: LCOV version 1.13