Bug 1374594 - Allow mutex/monitor scoped unlockers to be constructed from their locking counterparts - r=froydnj
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 20 Jun 2017 22:20:49 +1200
changeset 416197 27c66d41a64f2cdf4cfaf8d653fc2540c8000349
parent 416196 de305ad8a8ee6749851369913173b9cf9657e35d
child 416198 bfe1b0bc5aedad91d737103317eb4607915ee5a9
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1374594
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1374594 - Allow mutex/monitor scoped unlockers to be constructed from their locking counterparts - r=froydnj MozReview-Commit-ID: 7PResfLcEeO
xpcom/threads/Monitor.h
xpcom/threads/Mutex.h
xpcom/threads/ReentrantMonitor.h
--- a/xpcom/threads/Monitor.h
+++ b/xpcom/threads/Monitor.h
@@ -92,16 +92,18 @@ public:
   nsresult NotifyAll() { return mMonitor->NotifyAll(); }
 
 private:
   MonitorAutoLock();
   MonitorAutoLock(const MonitorAutoLock&);
   MonitorAutoLock& operator=(const MonitorAutoLock&);
   static void* operator new(size_t) CPP_THROW_NEW;
 
+  friend class MonitorAutoUnlock;
+
   Monitor* mMonitor;
 };
 
 /**
  * Unlock the monitor for the lexical scope instances of this class
  * are bound to (except for MonitorAutoLock in nested scopes).
  *
  * The monitor must be locked by the current thread when instances of
@@ -111,16 +113,22 @@ class MOZ_STACK_CLASS MonitorAutoUnlock
 {
 public:
   explicit MonitorAutoUnlock(Monitor& aMonitor)
     : mMonitor(&aMonitor)
   {
     mMonitor->Unlock();
   }
 
+  explicit MonitorAutoUnlock(MonitorAutoLock& aMonitorLock)
+    : mMonitor(aMonitorLock.mMonitor)
+  {
+    mMonitor->Unlock();
+  }
+
   ~MonitorAutoUnlock()
   {
     mMonitor->Lock();
   }
 
 private:
   MonitorAutoUnlock();
   MonitorAutoUnlock(const MonitorAutoUnlock&);
--- a/xpcom/threads/Mutex.h
+++ b/xpcom/threads/Mutex.h
@@ -131,16 +131,19 @@ public:
   }
 
 private:
   Mutex();
   Mutex(const Mutex&);
   Mutex& operator=(const Mutex&);
 };
 
+template<typename T>
+class MOZ_RAII BaseAutoUnlock;
+
 /**
  * MutexAutoLock
  * Acquires the Mutex when it enters scope, and releases it when it leaves
  * scope.
  *
  * MUCH PREFERRED to bare calls to Mutex.Lock and Unlock.
  */
 template<typename T>
@@ -169,16 +172,18 @@ public:
   }
 
 private:
   BaseAutoLock();
   BaseAutoLock(BaseAutoLock&);
   BaseAutoLock& operator=(BaseAutoLock&);
   static void* operator new(size_t) CPP_THROW_NEW;
 
+  friend class BaseAutoUnlock<T>;
+
   T* mLock;
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 typedef BaseAutoLock<Mutex> MutexAutoLock;
 typedef BaseAutoLock<OffTheBooksMutex> OffTheBooksMutexAutoLock;
 
 /**
@@ -195,16 +200,25 @@ public:
   explicit BaseAutoUnlock(T& aLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     : mLock(&aLock)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     NS_ASSERTION(mLock, "null lock");
     mLock->Unlock();
   }
 
+  explicit BaseAutoUnlock(
+    BaseAutoLock<T>& aAutoLock MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    : mLock(aAutoLock.mLock)
+  {
+    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
+    NS_ASSERTION(mLock, "null lock");
+    mLock->Unlock();
+  }
+
   ~BaseAutoUnlock()
   {
     mLock->Lock();
   }
 
 private:
   BaseAutoUnlock();
   BaseAutoUnlock(BaseAutoUnlock&);
--- a/xpcom/threads/ReentrantMonitor.h
+++ b/xpcom/threads/ReentrantMonitor.h
@@ -194,16 +194,18 @@ public:
   nsresult NotifyAll() { return mReentrantMonitor->NotifyAll(); }
 
 private:
   ReentrantMonitorAutoEnter();
   ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
   ReentrantMonitorAutoEnter& operator=(const ReentrantMonitorAutoEnter&);
   static void* operator new(size_t) CPP_THROW_NEW;
 
+  friend class ReentrantMonitorAutoExit;
+
   mozilla::ReentrantMonitor* mReentrantMonitor;
 };
 
 /**
  * ReentrantMonitorAutoExit
  * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves
  * scope.
  *
@@ -224,16 +226,25 @@ public:
   explicit ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor)
     : mReentrantMonitor(&aReentrantMonitor)
   {
     NS_ASSERTION(mReentrantMonitor, "null monitor");
     mReentrantMonitor->AssertCurrentThreadIn();
     mReentrantMonitor->Exit();
   }
 
+  explicit ReentrantMonitorAutoExit(
+    ReentrantMonitorAutoEnter& aReentrantMonitorAutoEnter)
+    : mReentrantMonitor(aReentrantMonitorAutoEnter.mReentrantMonitor)
+  {
+    NS_ASSERTION(mReentrantMonitor, "null monitor");
+    mReentrantMonitor->AssertCurrentThreadIn();
+    mReentrantMonitor->Exit();
+  }
+
   ~ReentrantMonitorAutoExit(void)
   {
     mReentrantMonitor->Enter();
   }
 
 private:
   ReentrantMonitorAutoExit();
   ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);