xpcom/glue/ReentrantMonitor.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: sw=4 ts=4 et :
     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_ReentrantMonitor_h
     8 #define mozilla_ReentrantMonitor_h
    10 #include "prmon.h"
    12 #ifdef MOZILLA_INTERNAL_API
    13 #include "GeckoProfiler.h"
    14 #endif //MOZILLA_INTERNAL_API
    16 #include "mozilla/BlockingResourceBase.h"
    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 {
    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 NS_COM_GLUE ReentrantMonitor : BlockingResourceBase
    38 {
    39 public:
    40     /**
    41      * ReentrantMonitor
    42      * @param aName A name which can reference this monitor
    43      */
    44     ReentrantMonitor(const char* aName) :
    45         BlockingResourceBase(aName, eReentrantMonitor)
    46 #ifdef DEBUG
    47         , mEntryCount(0)
    48 #endif
    49     {
    50         MOZ_COUNT_CTOR(ReentrantMonitor);
    51         mReentrantMonitor = PR_NewMonitor();
    52         if (!mReentrantMonitor)
    53             NS_RUNTIMEABORT("Can't allocate mozilla::ReentrantMonitor");
    54     }
    56     /**
    57      * ~ReentrantMonitor
    58      **/
    59     ~ReentrantMonitor()
    60     {
    61         NS_ASSERTION(mReentrantMonitor,
    62                      "improperly constructed ReentrantMonitor or double free");
    63         PR_DestroyMonitor(mReentrantMonitor);
    64         mReentrantMonitor = 0;
    65         MOZ_COUNT_DTOR(ReentrantMonitor);
    66     }
    68 #ifndef DEBUG
    69     /** 
    70      * Enter
    71      * @see prmon.h 
    72      **/
    73     void Enter()
    74     {
    75         PR_EnterMonitor(mReentrantMonitor);
    76     }
    78     /** 
    79      * Exit
    80      * @see prmon.h 
    81      **/
    82     void Exit()
    83     {
    84         PR_ExitMonitor(mReentrantMonitor);
    85     }
    87     /**
    88      * Wait
    89      * @see prmon.h
    90      **/      
    91     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
    92     {
    93 #ifdef MOZILLA_INTERNAL_API
    94         GeckoProfilerSleepRAII profiler_sleep;
    95 #endif //MOZILLA_INTERNAL_API
    96         return PR_Wait(mReentrantMonitor, interval) == PR_SUCCESS ?
    97             NS_OK : NS_ERROR_FAILURE;
    98     }
   100 #else // ifndef DEBUG
   101     void Enter();
   102     void Exit();
   103     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
   105 #endif  // ifndef DEBUG
   107     /** 
   108      * Notify
   109      * @see prmon.h 
   110      **/      
   111     nsresult Notify()
   112     {
   113         return PR_Notify(mReentrantMonitor) == PR_SUCCESS
   114             ? NS_OK : NS_ERROR_FAILURE;
   115     }
   117     /** 
   118      * NotifyAll
   119      * @see prmon.h 
   120      **/      
   121     nsresult NotifyAll()
   122     {
   123         return PR_NotifyAll(mReentrantMonitor) == PR_SUCCESS
   124             ? NS_OK : NS_ERROR_FAILURE;
   125     }
   127 #ifdef DEBUG
   128     /**
   129      * AssertCurrentThreadIn
   130      * @see prmon.h
   131      **/
   132     void AssertCurrentThreadIn()
   133     {
   134         PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mReentrantMonitor);
   135     }
   137     /**
   138      * AssertNotCurrentThreadIn
   139      * @see prmon.h
   140      **/
   141     void AssertNotCurrentThreadIn()
   142     {
   143         // FIXME bug 476536
   144     }
   146 #else
   147     void AssertCurrentThreadIn()
   148     {
   149     }
   150     void AssertNotCurrentThreadIn()
   151     {
   152     }
   154 #endif  // ifdef DEBUG
   156 private:
   157     ReentrantMonitor();
   158     ReentrantMonitor(const ReentrantMonitor&);
   159     ReentrantMonitor& operator =(const ReentrantMonitor&);
   161     PRMonitor* mReentrantMonitor;
   162 #ifdef DEBUG
   163     int32_t mEntryCount;
   164 #endif
   165 };
   168 /**
   169  * ReentrantMonitorAutoEnter
   170  * Enters the ReentrantMonitor when it enters scope, and exits it when
   171  * it leaves scope.
   172  *
   173  * MUCH PREFERRED to bare calls to ReentrantMonitor.Enter and Exit.
   174  */ 
   175 class NS_COM_GLUE MOZ_STACK_CLASS ReentrantMonitorAutoEnter
   176 {
   177 public:
   178     /**
   179      * Constructor
   180      * The constructor aquires the given lock.  The destructor
   181      * releases the lock.
   182      * 
   183      * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. 
   184      **/
   185     ReentrantMonitorAutoEnter(mozilla::ReentrantMonitor &aReentrantMonitor) :
   186         mReentrantMonitor(&aReentrantMonitor)
   187     {
   188         NS_ASSERTION(mReentrantMonitor, "null monitor");
   189         mReentrantMonitor->Enter();
   190     }
   192     ~ReentrantMonitorAutoEnter(void)
   193     {
   194         mReentrantMonitor->Exit();
   195     }
   197     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
   198     {
   199        return mReentrantMonitor->Wait(interval);
   200     }
   202     nsresult Notify()
   203     {
   204         return mReentrantMonitor->Notify();
   205     }
   207     nsresult NotifyAll()
   208     {
   209         return mReentrantMonitor->NotifyAll();
   210     }
   212 private:
   213     ReentrantMonitorAutoEnter();
   214     ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
   215     ReentrantMonitorAutoEnter& operator =(const ReentrantMonitorAutoEnter&);
   216     static void* operator new(size_t) CPP_THROW_NEW;
   217     static void operator delete(void*);
   219     mozilla::ReentrantMonitor* mReentrantMonitor;
   220 };
   222 /**
   223  * ReentrantMonitorAutoExit
   224  * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves
   225  * scope.
   226  *
   227  * MUCH PREFERRED to bare calls to ReentrantMonitor.Exit and Enter.
   228  */
   229 class MOZ_STACK_CLASS ReentrantMonitorAutoExit
   230 {
   231 public:
   232     /**
   233      * Constructor
   234      * The constructor releases the given lock.  The destructor
   235      * acquires the lock. The lock must be held before constructing
   236      * this object!
   237      *
   238      * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. It
   239      *                 must be already locked.
   240      **/
   241     ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor) :
   242         mReentrantMonitor(&aReentrantMonitor)
   243     {
   244         NS_ASSERTION(mReentrantMonitor, "null monitor");
   245         mReentrantMonitor->AssertCurrentThreadIn();
   246         mReentrantMonitor->Exit();
   247     }
   249     ~ReentrantMonitorAutoExit(void)
   250     {
   251         mReentrantMonitor->Enter();
   252     }
   254 private:
   255     ReentrantMonitorAutoExit();
   256     ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);
   257     ReentrantMonitorAutoExit& operator =(const ReentrantMonitorAutoExit&);
   258     static void* operator new(size_t) CPP_THROW_NEW;
   259     static void operator delete(void*);
   261     ReentrantMonitor* mReentrantMonitor;
   262 };
   264 } // namespace mozilla
   267 #endif // ifndef mozilla_ReentrantMonitor_h

mercurial