Bug 556214, parts 1 and 1.1: Rename Monitor to ReentrantMonitor and fix existing Monitor users. r=roc
authorChris Jones <jones.chris.g@gmail.com>
Fri, 29 Apr 2011 14:21:57 -0500
changeset 68784 0912e048403117c91f5be660c54a810aa7232835
parent 68783 c7f62d818af25b3e62e2f0c35b27214a4209a898
child 68785 54097e09fa359de7fc4851e5ba175612760e64e9
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs556214
milestone6.0a1
Bug 556214, parts 1 and 1.1: Rename Monitor to ReentrantMonitor and fix existing Monitor users. r=roc
content/media/VideoUtils.h
content/media/nsAudioAvailableEventManager.cpp
content/media/nsAudioAvailableEventManager.h
content/media/nsAudioStream.cpp
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoder.h
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderReader.h
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/nsBuiltinDecoderStateMachine.h
content/media/nsMediaCache.cpp
content/media/nsMediaCache.h
content/media/nsMediaDecoder.h
content/media/ogg/nsOggReader.cpp
content/media/ogg/nsOggReader.h
content/media/wave/nsWaveReader.cpp
content/media/webm/nsWebMBufferedParser.cpp
content/media/webm/nsWebMBufferedParser.h
content/media/webm/nsWebMReader.cpp
content/media/webm/nsWebMReader.h
dom/ipc/AudioChild.cpp
dom/ipc/AudioChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/src/threads/nsDOMThreadService.cpp
dom/src/threads/nsDOMThreadService.h
dom/src/threads/nsDOMWorker.cpp
dom/src/threads/nsDOMWorkerPool.cpp
dom/src/threads/nsDOMWorkerPool.h
gfx/layers/ImageLayers.h
gfx/layers/basic/BasicImages.cpp
gfx/layers/d3d10/ImageLayerD3D10.cpp
gfx/layers/d3d9/ImageLayerD3D9.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
intl/strres/src/nsStringBundle.cpp
intl/strres/src/nsStringBundle.h
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
ipc/glue/WindowsMessageLoop.cpp
js/src/xpconnect/src/xpcprivate.h
modules/libpr0n/encoders/jpeg/nsJPEGEncoder.cpp
modules/libpr0n/encoders/jpeg/nsJPEGEncoder.h
modules/libpr0n/encoders/png/nsPNGEncoder.cpp
modules/libpr0n/encoders/png/nsPNGEncoder.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
netwerk/protocol/http/nsHttpConnectionMgr.h
netwerk/system/maemo/nsMaemoNetworkManager.cpp
netwerk/wifi/nsWifiMonitor.cpp
netwerk/wifi/nsWifiMonitor.h
netwerk/wifi/nsWifiScannerMac.cpp
netwerk/wifi/nsWifiScannerUnix.cpp
netwerk/wifi/nsWifiScannerWin.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.cpp
security/manager/boot/src/nsSecureBrowserUIImpl.h
security/manager/ssl/src/nsCertOverrideService.cpp
security/manager/ssl/src/nsCertOverrideService.h
security/manager/ssl/src/nsClientAuthRemember.cpp
security/manager/ssl/src/nsClientAuthRemember.h
security/manager/ssl/src/nsRecentBadCerts.cpp
security/manager/ssl/src/nsRecentBadCerts.h
storage/test/test_deadlock_detector.cpp
storage/test/test_service_init_background_thread.cpp
storage/test/test_true_async.cpp
storage/test/test_unlock_notify.cpp
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/glue/BlockingResourceBase.cpp
xpcom/glue/BlockingResourceBase.h
xpcom/glue/Makefile.in
xpcom/glue/Monitor.h
xpcom/glue/ReentrantMonitor.h
xpcom/io/nsPipe3.cpp
xpcom/proxy/tests/proxy-create-threadsafety.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
xpcom/reflect/xptinfo/src/xptiprivate.h
xpcom/tests/TestDeadlockDetector.cpp
xpcom/tests/TestRacingServiceManager.cpp
xpcom/tests/TestThreadPoolListener.cpp
xpcom/tests/TestTimers.cpp
xpcom/threads/nsEventQueue.cpp
xpcom/threads/nsEventQueue.h
xpcom/threads/nsThread.cpp
xpcom/threads/nsThreadPool.cpp
--- a/content/media/VideoUtils.h
+++ b/content/media/VideoUtils.h
@@ -34,17 +34,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef VideoUtils_h
 #define VideoUtils_h
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 // This file contains stuff we'd rather put elsewhere, but which is
 // dependent on other changes which we don't want to wait for. We plan to
 // remove this file in the near future.
 
 
 // This belongs in prtypes.h
 /************************************************************************
@@ -59,56 +59,55 @@
 #define PR_INT64_MIN (-PR_INT64_MAX - 1)
 #define PR_UINT64_MAX (~(PRUint64)(0))
 
 // This belongs in xpcom/monitor/Monitor.h, once we've made
 // mozilla::Monitor non-reentrant.
 namespace mozilla {
 
 /**
- * MonitorAutoExit
- * Exit the Monitor when it enters scope, and enters it when it leaves 
+ * ReentrantMonitorAutoExit
+ * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves 
  * scope.
  *
- * MUCH PREFERRED to bare calls to Monitor.Exit and Enter.
+ * MUCH PREFERRED to bare calls to ReentrantMonitor.Exit and Enter.
  */ 
-class NS_STACK_CLASS MonitorAutoExit
+class NS_STACK_CLASS ReentrantMonitorAutoExit
 {
 public:
     /**
      * Constructor
      * The constructor releases the given lock.  The destructor
      * acquires the lock. The lock must be held before constructing
      * this object!
      * 
-     * @param aMonitor A valid mozilla::Monitor* returned by 
-     *                 mozilla::Monitor::NewMonitor. It must be
-     *                 already locked.
+     * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. It
+     *                 must be already locked.
      **/
-    MonitorAutoExit(mozilla::Monitor &aMonitor) :
-        mMonitor(&aMonitor)
+    ReentrantMonitorAutoExit(ReentrantMonitor& aReentrantMonitor) :
+        mReentrantMonitor(&aReentrantMonitor)
     {
-        NS_ASSERTION(mMonitor, "null monitor");
-        mMonitor->AssertCurrentThreadIn();
-        mMonitor->Exit();
+        NS_ASSERTION(mReentrantMonitor, "null monitor");
+        mReentrantMonitor->AssertCurrentThreadIn();
+        mReentrantMonitor->Exit();
     }
     
-    ~MonitorAutoExit(void)
+    ~ReentrantMonitorAutoExit(void)
     {
-        mMonitor->Enter();
+        mReentrantMonitor->Enter();
     }
  
 private:
-    MonitorAutoExit();
-    MonitorAutoExit(const MonitorAutoExit&);
-    MonitorAutoExit& operator =(const MonitorAutoExit&);
+    ReentrantMonitorAutoExit();
+    ReentrantMonitorAutoExit(const ReentrantMonitorAutoExit&);
+    ReentrantMonitorAutoExit& operator =(const ReentrantMonitorAutoExit&);
     static void* operator new(size_t) CPP_THROW_NEW;
     static void operator delete(void*);
 
-    mozilla::Monitor* mMonitor;
+    ReentrantMonitor* mReentrantMonitor;
 };
 
 } // namespace mozilla
 
 // Adds two 32bit unsigned numbers, retuns PR_TRUE if addition succeeded,
 // or PR_FALSE the if addition would result in an overflow.
 PRBool AddOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult);
  
--- a/content/media/nsAudioAvailableEventManager.cpp
+++ b/content/media/nsAudioAvailableEventManager.cpp
@@ -79,17 +79,17 @@ public:
 
 
 nsAudioAvailableEventManager::nsAudioAvailableEventManager(nsBuiltinDecoder* aDecoder) :
   mDecoder(aDecoder),
   mSignalBuffer(new float[mDecoder->GetFrameBufferLength()]),
   mSignalBufferLength(mDecoder->GetFrameBufferLength()),
   mNewSignalBufferLength(mSignalBufferLength),
   mSignalBufferPosition(0),
-  mMonitor("media.audioavailableeventmanager")
+  mReentrantMonitor("media.audioavailableeventmanager")
 {
   MOZ_COUNT_CTOR(nsAudioAvailableEventManager);
 }
 
 nsAudioAvailableEventManager::~nsAudioAvailableEventManager()
 {
   MOZ_COUNT_DTOR(nsAudioAvailableEventManager);
 }
@@ -97,17 +97,17 @@ nsAudioAvailableEventManager::~nsAudioAv
 void nsAudioAvailableEventManager::Init(PRUint32 aChannels, PRUint32 aRate)
 {
   NS_ASSERTION(aChannels != 0 && aRate != 0, "Audio metadata not known.");
   mSamplesPerSecond = static_cast<float>(aChannels * aRate);
 }
 
 void nsAudioAvailableEventManager::DispatchPendingEvents(PRUint64 aCurrentTime)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   while (mPendingEvents.Length() > 0) {
     nsAudioAvailableEventRunner* e =
       (nsAudioAvailableEventRunner*)mPendingEvents[0].get();
     if (e->mTime * USECS_PER_S > aCurrentTime) {
       break;
     }
     nsCOMPtr<nsIRunnable> event = mPendingEvents[0];
@@ -115,17 +115,17 @@ void nsAudioAvailableEventManager::Dispa
     NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   }
 }
 
 void nsAudioAvailableEventManager::QueueWrittenAudioData(SoundDataValue* aAudioData,
                                                          PRUint32 aAudioDataLength,
                                                          PRUint64 aEndTimeSampleOffset)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   PRUint32 currentBufferSize = mNewSignalBufferLength;
   if (currentBufferSize == 0) {
     NS_WARNING("Decoder framebuffer length not set.");
     return;
   }
 
   if (!mSignalBuffer ||
@@ -197,25 +197,25 @@ void nsAudioAvailableEventManager::Queue
       signalBuffer[i] = MOZ_CONVERT_SOUND_SAMPLE(audioData[i]);
     }
     mSignalBufferPosition += audioDataLength;
   }
 }
 
 void nsAudioAvailableEventManager::Clear()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mPendingEvents.Clear();
   mSignalBufferPosition = 0;
 }
 
 void nsAudioAvailableEventManager::Drain(PRUint64 aEndTime)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   // Force all pending events to go now.
   for (PRUint32 i = 0; i < mPendingEvents.Length(); ++i) {
     nsCOMPtr<nsIRunnable> event = mPendingEvents[i];
     NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
   }
   mPendingEvents.Clear();
 
@@ -235,13 +235,13 @@ void nsAudioAvailableEventManager::Drain
                                     mSignalBufferLength, time);
   NS_DispatchToMainThread(lastEvent, NS_DISPATCH_NORMAL);
 
   mSignalBufferPosition = 0;
 }
 
 void nsAudioAvailableEventManager::SetSignalBufferLength(PRUint32 aLength)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mNewSignalBufferLength = aLength;
 }
 
--- a/content/media/nsAudioAvailableEventManager.h
+++ b/content/media/nsAudioAvailableEventManager.h
@@ -100,13 +100,14 @@ private:
 
   // The position of the first available item in mSignalBuffer
   PRUint32 mSignalBufferPosition;
 
   // The MozAudioAvailable events to be dispatched.  This queue is shared
   // between the state machine and audio threads.
   nsTArray< nsCOMPtr<nsIRunnable> > mPendingEvents;
 
-  // Monitor for shared access to mPendingEvents queue or buffer length.
-  Monitor mMonitor;
+  // ReentrantMonitor for shared access to mPendingEvents queue or
+  // buffer length.
+  ReentrantMonitor mReentrantMonitor;
 };
 
 #endif
--- a/content/media/nsAudioStream.cpp
+++ b/content/media/nsAudioStream.cpp
@@ -35,17 +35,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/PAudioChild.h"
 #include "mozilla/dom/AudioChild.h"
-#include "mozilla/Monitor.h"
 #include "nsXULAppAPI.h"
 using namespace mozilla::dom;
 
 #include <stdio.h>
 #include <math.h>
 #include "prlog.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -56,17 +56,17 @@ PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg)
 #endif
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsBuiltinDecoder, nsIObserver)
 
 void nsBuiltinDecoder::Pause() 
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (mPlayState == PLAY_STATE_SEEKING || mPlayState == PLAY_STATE_ENDED) {
     mNextState = PLAY_STATE_PAUSED;
     return;
   }
 
   ChangeState(PLAY_STATE_PAUSED);
 }
 
@@ -91,17 +91,17 @@ double nsBuiltinDecoder::GetDuration()
 nsBuiltinDecoder::nsBuiltinDecoder() :
   mDecoderPosition(0),
   mPlaybackPosition(0),
   mCurrentTime(0.0),
   mInitialVolume(0.0),
   mRequestedSeekTime(-1.0),
   mDuration(-1),
   mSeekable(PR_TRUE),
-  mMonitor("media.decoder"),
+  mReentrantMonitor("media.decoder"),
   mPlayState(PLAY_STATE_PAUSED),
   mNextState(PLAY_STATE_PAUSED),
   mResourceLoaded(PR_FALSE),
   mIgnoreProgressData(PR_FALSE)
 {
   MOZ_COUNT_CTOR(nsBuiltinDecoder);
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 #ifdef PR_LOGGING
@@ -190,17 +190,17 @@ nsresult nsBuiltinDecoder::Load(nsMediaS
   if (aStreamListener) {
     *aStreamListener = nsnull;
   }
 
   {
     // Hold the lock while we do this to set proper lock ordering
     // expectations for dynamic deadlock detectors: decoder lock(s)
     // should be grabbed before the cache lock
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     nsresult rv = aStream->Open(aStreamListener);
     if (NS_FAILED(rv)) {
       delete aStream;
       return rv;
     }
 
     mStream = aStream;
@@ -212,17 +212,17 @@ nsresult nsBuiltinDecoder::Load(nsMediaS
   }
 
   nsBuiltinDecoder* cloneDonor = static_cast<nsBuiltinDecoder*>(aCloneDonor);
   if (NS_FAILED(mDecoderStateMachine->Init(cloneDonor ?
                                            cloneDonor->mDecoderStateMachine : nsnull))) {
     return NS_ERROR_FAILURE;
   }
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->SetSeekable(mSeekable);
     mDecoderStateMachine->SetDuration(mDuration);
     
     if (mFrameBufferLength > 0) {
       // The valid mFrameBufferLength value was specified earlier
       mDecoderStateMachine->SetFrameBufferLength(mFrameBufferLength);
     }
   }
@@ -232,17 +232,17 @@ nsresult nsBuiltinDecoder::Load(nsMediaS
   return StartStateMachineThread();
 }
 
 nsresult nsBuiltinDecoder::RequestFrameBufferLength(PRUint32 aLength)
 {
   nsresult res = nsMediaDecoder::RequestFrameBufferLength(aLength);
   NS_ENSURE_SUCCESS(res,res);
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (mDecoderStateMachine) {
       mDecoderStateMachine->SetFrameBufferLength(aLength);
   }
   return res;
 }
 
 nsresult nsBuiltinDecoder::StartStateMachineThread()
 {
@@ -254,34 +254,34 @@ nsresult nsBuiltinDecoder::StartStateMac
   nsresult rv = NS_NewThread(getter_AddRefs(mStateMachineThread));
   NS_ENSURE_SUCCESS(rv, rv);
   return mStateMachineThread->Dispatch(mDecoderStateMachine, NS_DISPATCH_NORMAL);
 }
 
 nsresult nsBuiltinDecoder::Play()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   nsresult res = StartStateMachineThread();
   NS_ENSURE_SUCCESS(res,res);
   if (mPlayState == PLAY_STATE_SEEKING) {
     mNextState = PLAY_STATE_PLAYING;
     return NS_OK;
   }
   if (mPlayState == PLAY_STATE_ENDED)
     return Seek(0);
 
   ChangeState(PLAY_STATE_PLAYING);
   return NS_OK;
 }
 
 nsresult nsBuiltinDecoder::Seek(double aTime)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   if (aTime < 0.0)
     return NS_ERROR_FAILURE;
 
   mRequestedSeekTime = aTime;
   mCurrentTime = aTime;
 
   // If we are already in the seeking state, then setting mRequestedSeekTime
@@ -351,17 +351,17 @@ void nsBuiltinDecoder::MetadataLoaded(PR
   if (mShuttingDown) {
     return;
   }
 
   // Only inform the element of MetadataLoaded if not doing a load() in order
   // to fulfill a seek, otherwise we'll get multiple metadataloaded events.
   PRBool notifyElement = PR_TRUE;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1;
     // Duration has changed so we should recompute playback rate
     UpdatePlaybackRate();
 
     notifyElement = mNextState != PLAY_STATE_SEEKING;
   }
 
   if (mElement && notifyElement) {
@@ -377,17 +377,17 @@ void nsBuiltinDecoder::MetadataLoaded(PR
   else if (mElement) {
     // Resource was loaded during metadata loading, when progress
     // events are being ignored. Fire the final progress event.
     mElement->DispatchAsyncEvent(NS_LITERAL_STRING("progress"));
   }
 
   // Only inform the element of FirstFrameLoaded if not doing a load() in order
   // to fulfill a seek, otherwise we'll get multiple loadedfirstframe events.
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   PRBool resourceIsLoaded = !mResourceLoaded && mStream &&
     mStream->IsDataCachedToEndOfStream(mDecoderPosition);
   if (mElement && notifyElement) {
     mElement->FirstFrameLoaded(resourceIsLoaded);
   }
 
   // The element can run javascript via events
   // before reaching here, so only change the
@@ -416,17 +416,17 @@ void nsBuiltinDecoder::ResourceLoaded()
   // that the seek results in reaching end of file, we get a bogus call
   // to ResourceLoaded).
   if (mShuttingDown)
     return;
 
   {
     // If we are seeking or loading then the resource loaded notification we get
     // should be ignored, since it represents the end of the seek request.
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     if (mIgnoreProgressData || mResourceLoaded || mPlayState == PLAY_STATE_LOADING)
       return;
 
     Progress(PR_FALSE);
 
     mResourceLoaded = PR_TRUE;
     StopProgress();
   }
@@ -499,17 +499,17 @@ NS_IMETHODIMP nsBuiltinDecoder::Observe(
 
 nsMediaDecoder::Statistics
 nsBuiltinDecoder::GetStatistics()
 {
   NS_ASSERTION(NS_IsMainThread() || OnStateMachineThread(),
                "Should be on main or state machine thread.");
   Statistics result;
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (mStream) {
     result.mDownloadRate = 
       mStream->GetDownloadRate(&result.mDownloadRateReliable);
     result.mDownloadPosition =
       mStream->GetCachedDataEnd(mDecoderPosition);
     result.mTotalBytes = mStream->GetLength();
     result.mPlaybackRate = ComputePlaybackRate(&result.mPlaybackRateReliable);
     result.mDecoderPosition = mDecoderPosition;
@@ -526,33 +526,33 @@ nsBuiltinDecoder::GetStatistics()
     result.mTotalBytes = 0;
   }
 
   return result;
 }
 
 double nsBuiltinDecoder::ComputePlaybackRate(PRPackedBool* aReliable)
 {
-  GetMonitor().AssertCurrentThreadIn();
+  GetReentrantMonitor().AssertCurrentThreadIn();
   NS_ASSERTION(NS_IsMainThread() || IsCurrentThread(mStateMachineThread),
                "Should be on main or state machine thread.");
 
   PRInt64 length = mStream ? mStream->GetLength() : -1;
   if (mDuration >= 0 && length >= 0) {
     *aReliable = PR_TRUE;
     return length * static_cast<double>(USECS_PER_S) / mDuration;
   }
   return mPlaybackStatistics.GetRateAtLastStop(aReliable);
 }
 
 void nsBuiltinDecoder::UpdatePlaybackRate()
 {
   NS_ASSERTION(NS_IsMainThread() || IsCurrentThread(mStateMachineThread),
                "Should be on main or state machine thread.");
-  GetMonitor().AssertCurrentThreadIn();
+  GetReentrantMonitor().AssertCurrentThreadIn();
   if (!mStream)
     return;
   PRPackedBool reliable;
   PRUint32 rate = PRUint32(ComputePlaybackRate(&reliable));
   if (reliable) {
     // Avoid passing a zero rate
     rate = NS_MAX(rate, 1u);
   }
@@ -589,32 +589,32 @@ void nsBuiltinDecoder::NotifyDownloadEnd
 
   if (aStatus == NS_BINDING_ABORTED) {
     // Download has been cancelled by user.
     mElement->LoadAborted();
     return;
   }
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     UpdatePlaybackRate();
   }
 
   if (NS_SUCCEEDED(aStatus)) {
     ResourceLoaded();
   }
   else if (aStatus != NS_BASE_STREAM_CLOSED) {
     NetworkError();
   }
   UpdateReadyStateForData();
 }
 
 void nsBuiltinDecoder::NotifyBytesConsumed(PRInt64 aBytes)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(OnStateMachineThread() || mDecoderStateMachine->OnDecodeThread(),
                "Should be on play state machine or decode thread.");
   if (!mIgnoreProgressData) {
     mDecoderPosition += aBytes;
     mPlaybackStatistics.AddBytes(aBytes);
   }
 }
 
@@ -658,17 +658,17 @@ void nsBuiltinDecoder::SeekingStopped()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   if (mShuttingDown)
     return;
 
   PRBool seekWasAborted = PR_FALSE;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // An additional seek was requested while the current seek was
     // in operation.
     if (mRequestedSeekTime >= 0.0) {
       ChangeState(PLAY_STATE_SEEKING);
       seekWasAborted = PR_TRUE;
     } else {
       UnpinForSeek();
@@ -691,17 +691,17 @@ void nsBuiltinDecoder::SeekingStoppedAtE
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   if (mShuttingDown)
     return;
 
   PRBool fireEnded = PR_FALSE;
   PRBool seekWasAborted = PR_FALSE;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // An additional seek was requested while the current seek was
     // in operation.
     if (mRequestedSeekTime >= 0.0) {
       ChangeState(PLAY_STATE_SEEKING);
       seekWasAborted = PR_TRUE;
     } else {
       UnpinForSeek();
@@ -731,24 +731,24 @@ void nsBuiltinDecoder::SeekingStarted()
     UpdateReadyStateForData();
     mElement->SeekStarted();
   }
 }
 
 void nsBuiltinDecoder::ChangeState(PlayState aState)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");   
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   if (mNextState == aState) {
     mNextState = PLAY_STATE_PAUSED;
   }
 
   if (mPlayState == PLAY_STATE_SHUTDOWN) {
-    mMonitor.NotifyAll();
+    mReentrantMonitor.NotifyAll();
     return;
   }
 
   mPlayState = aState;
   switch (aState) {
   case PLAY_STATE_PAUSED:
     /* No action needed */
     break;
@@ -767,31 +767,31 @@ void nsBuiltinDecoder::ChangeState(PlayS
     break;
   case PLAY_STATE_ENDED:
     /* No action needed */
     break;
   case PLAY_STATE_SHUTDOWN:
     /* No action needed */
     break;
   }
-  mMonitor.NotifyAll();
+  mReentrantMonitor.NotifyAll();
 }
 
 void nsBuiltinDecoder::PlaybackPositionChanged()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mShuttingDown)
     return;
 
   double lastTime = mCurrentTime;
 
   // Control the scope of the monitor so it is not
   // held while the timeupdate and the invalidate is run.
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     if (mDecoderStateMachine) {
       mCurrentTime = mDecoderStateMachine->GetCurrentTime();
       mDecoderStateMachine->ClearPositionChangeFlag();
     }
   }
 
   // Invalidate the frame so any video data is displayed.
   // Do this before the timeupdate event so that if that
@@ -802,48 +802,48 @@ void nsBuiltinDecoder::PlaybackPositionC
   if (mElement && lastTime != mCurrentTime) {
     FireTimeUpdate();
   }
 }
 
 void nsBuiltinDecoder::DurationChanged()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   PRInt64 oldDuration = mDuration;
   mDuration = mDecoderStateMachine ? mDecoderStateMachine->GetDuration() : -1;
   // Duration has changed so we should recompute playback rate
   UpdatePlaybackRate();
 
   if (mElement && oldDuration != mDuration) {
     LOG(PR_LOG_DEBUG, ("%p duration changed to %lld", this, mDuration));
     mElement->DispatchEvent(NS_LITERAL_STRING("durationchange"));
   }
 }
 
 void nsBuiltinDecoder::SetDuration(double aDuration)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   mDuration = static_cast<PRInt64>(NS_round(aDuration * static_cast<double>(USECS_PER_S)));
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (mDecoderStateMachine) {
     mDecoderStateMachine->SetDuration(mDuration);
   }
 
   // Duration has changed so we should recompute playback rate
   UpdatePlaybackRate();
 }
 
 void nsBuiltinDecoder::SetSeekable(PRBool aSeekable)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   mSeekable = aSeekable;
   if (mDecoderStateMachine) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->SetSeekable(aSeekable);
   }
 }
 
 PRBool nsBuiltinDecoder::GetSeekable()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   return mSeekable;
@@ -859,17 +859,17 @@ void nsBuiltinDecoder::Suspend()
 
 void nsBuiltinDecoder::Resume(PRBool aForceBuffering)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mStream) {
     mStream->Resume();
   }
   if (aForceBuffering) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->StartBuffering();
   }
 }
 
 void nsBuiltinDecoder::StopProgressUpdates()
 {
   NS_ASSERTION(IsCurrentThread(mStateMachineThread), "Should be on state machine thread.");
   mIgnoreProgressData = PR_TRUE;
@@ -893,11 +893,11 @@ void nsBuiltinDecoder::MoveLoadsToBackgr
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   if (mStream) {
     mStream->MoveLoadsToBackground();
   }
 }
 
 void nsBuiltinDecoder::UpdatePlaybackOffset(PRInt64 aOffset)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mPlaybackPosition = NS_MAX(aOffset, mPlaybackPosition);
 }
--- a/content/media/nsBuiltinDecoder.h
+++ b/content/media/nsBuiltinDecoder.h
@@ -207,17 +207,17 @@ Shutdown when destroying the nsBuiltinDe
 #include "nsAutoPtr.h"
 #include "nsSize.h"
 #include "prlog.h"
 #include "gfxContext.h"
 #include "gfxRect.h"
 #include "nsMediaStream.h"
 #include "nsMediaDecoder.h"
 #include "nsHTMLMediaElement.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 class nsAudioStream;
 
 static inline PRBool IsCurrentThread(nsIThread* aThread) {
   return NS_GetCurrentThread() == aThread;
 }
 
 // Decoder backends must implement this class to perform the codec
@@ -314,17 +314,17 @@ class nsBuiltinDecoder : public nsMediaD
 {
   // ISupports
   NS_DECL_ISUPPORTS
 
   // nsIObserver
   NS_DECL_NSIOBSERVER
 
  public:
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
   // Enumeration for the valid play states (see mPlayState)
   enum PlayState {
     PLAY_STATE_START,
     PLAY_STATE_LOADING,
     PLAY_STATE_PAUSED,
     PLAY_STATE_PLAYING,
     PLAY_STATE_SEEKING,
@@ -429,18 +429,18 @@ class nsBuiltinDecoder : public nsMediaD
   }
 
   PRBool OnDecodeThread() const {
     return mDecoderStateMachine->OnDecodeThread();
   }
 
   // Returns the monitor for other threads to synchronise access to
   // state.
-  Monitor& GetMonitor() { 
-    return mMonitor; 
+  ReentrantMonitor& GetReentrantMonitor() { 
+    return mReentrantMonitor; 
   }
 
   // Constructs the time ranges representing what segments of the media
   // are buffered and playable.
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered) {
     if (mDecoderStateMachine) {
       return mDecoderStateMachine->GetBuffered(aBuffered);
     }
@@ -589,17 +589,17 @@ public:
   double mCurrentTime;
 
   // Volume that playback should start at.  0.0 = muted. 1.0 = full
   // volume.  Readable/Writeable from the main thread.
   double mInitialVolume;
 
   // Position to seek to when the seek notification is received by the
   // decode thread. Written by the main thread and read via the
-  // decode thread. Synchronised using mMonitor. If the
+  // decode thread. Synchronised using mReentrantMonitor. If the
   // value is negative then no seek has been requested. When a seek is
   // started this is reset to negative.
   double mRequestedSeekTime;
 
   // Duration of the media resource. Set to -1 if unknown.
   // Set when the metadata is loaded. Accessed on the main thread
   // only.
   PRInt64 mDuration;
@@ -617,23 +617,23 @@ public:
   // is synchronised on a monitor. The lifetime of this object is
   // after mPlayState is LOADING and before mPlayState is SHUTDOWN. It
   // is safe to access it during this period.
   nsCOMPtr<nsDecoderStateMachine> mDecoderStateMachine;
 
   // Stream of media data.
   nsAutoPtr<nsMediaStream> mStream;
 
-  // Monitor for detecting when the video play state changes. A call
+  // ReentrantMonitor for detecting when the video play state changes. A call
   // to Wait on this monitor will block the thread until the next
   // state change.
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 
   // Set to one of the valid play states. It is protected by the
-  // monitor mMonitor. This monitor must be acquired when reading or
+  // monitor mReentrantMonitor. This monitor must be acquired when reading or
   // writing the state. Any change to the state on the main thread
   // must call NotifyAll on the monitor so the decode thread can wake up.
   PlayState mPlayState;
 
   // The state to change to after a seek or load operation. It must only
   // be changed from the main thread. The decoder monitor must be acquired
   // when writing to the state, or when reading from a non-main thread.
   // Any change to the state must call NotifyAll on the monitor.
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -202,17 +202,17 @@ VideoData* VideoData::Create(nsVideoInfo
   data.mPicSize = picSize;
   data.mStereoMode = aInfo.mStereoMode;
 
   videoImage->SetData(data); // Copies buffer
   return v.forget();
 }
 
 nsBuiltinDecoderReader::nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder)
-  : mMonitor("media.decoderreader"),
+  : mReentrantMonitor("media.decoderreader"),
     mDecoder(aDecoder)
 {
   MOZ_COUNT_CTOR(nsBuiltinDecoderReader);
 }
 
 nsBuiltinDecoderReader::~nsBuiltinDecoderReader()
 {
   ResetDecode();
@@ -274,17 +274,17 @@ PRInt64 nsBuiltinDecoderReader::FindEndT
 
 template<class Data>
 Data* nsBuiltinDecoderReader::DecodeToFirstData(DecodeFn aDecodeFn,
                                                 MediaQueue<Data>& aQueue)
 {
   PRBool eof = PR_FALSE;
   while (!eof && aQueue.GetSize() == 0) {
     {
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       if (mDecoder->GetDecodeState() == nsDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
         return nsnull;
       }
     }
     eof = !(this->*aDecodeFn)();
   }
   Data* d = nsnull;
   return (d = aQueue.PeekFront()) ? d : nsnull;
@@ -296,18 +296,18 @@ nsresult nsBuiltinDecoderReader::DecodeT
   if (HasVideo()) {
     PRBool eof = PR_FALSE;
     PRInt64 startTime = -1;
     while (HasVideo() && !eof) {
       while (mVideoQueue.GetSize() == 0 && !eof) {
         PRBool skip = PR_FALSE;
         eof = !DecodeVideoFrame(skip, 0);
         {
-          MonitorAutoExit exitReaderMon(mMonitor);
-          MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+          ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+          ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
           if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
             return NS_ERROR_FAILURE;
           }
         }
       }
       if (mVideoQueue.GetSize() == 0) {
         break;
       }
@@ -321,34 +321,34 @@ nsresult nsBuiltinDecoderReader::DecodeT
         mVideoQueue.PopFront();
         video = nsnull;
       } else {
         video.forget();
         break;
       }
     }
     {
-      MonitorAutoExit exitReaderMon(mMonitor);
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
         return NS_ERROR_FAILURE;
       }
     }
     LOG(PR_LOG_DEBUG, ("First video frame after decode is %lld", startTime));
   }
 
   if (HasAudio()) {
     // Decode audio forward to the seek target.
     PRBool eof = PR_FALSE;
     while (HasAudio() && !eof) {
       while (!eof && mAudioQueue.GetSize() == 0) {
         eof = !DecodeAudioData();
         {
-          MonitorAutoExit exitReaderMon(mMonitor);
-          MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+          ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+          ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
           if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
             return NS_ERROR_FAILURE;
           }
         }
       }
       nsAutoPtr<SoundData> audio(mAudioQueue.PeekFront());
       if (audio && audio->mTime + audio->mDuration <= aTarget) {
         mAudioQueue.PopFront();
--- a/content/media/nsBuiltinDecoderReader.h
+++ b/content/media/nsBuiltinDecoderReader.h
@@ -41,17 +41,17 @@
 
 #include <nsDeque.h>
 #include "Layers.h"
 #include "ImageLayers.h"
 #include "nsClassHashtable.h"
 #include "mozilla/TimeStamp.h"
 #include "nsSize.h"
 #include "nsRect.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 class nsBuiltinDecoderStateMachine;
 
 // Stores info relevant to presenting media samples.
 class nsVideoInfo {
 public:
   nsVideoInfo()
     : mPixelAspectRatio(1.0),
@@ -292,131 +292,131 @@ class MediaQueueDeallocator : public nsD
   virtual void* operator() (void* anObject) {
     delete static_cast<T*>(anObject);
     return nsnull;
   }
 };
 
 template <class T> class MediaQueue : private nsDeque {
  public:
-   typedef mozilla::MonitorAutoEnter MonitorAutoEnter;
-   typedef mozilla::Monitor Monitor;
+   typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
+   typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
    MediaQueue()
      : nsDeque(new MediaQueueDeallocator<T>()),
-       mMonitor("mediaqueue"),
+       mReentrantMonitor("mediaqueue"),
        mEndOfStream(0)
    {}
   
   ~MediaQueue() {
     Reset();
   }
 
   inline PRInt32 GetSize() { 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return nsDeque::GetSize();
   }
   
   inline void Push(T* aItem) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::Push(aItem);
   }
   
   inline void PushFront(T* aItem) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::PushFront(aItem);
   }
   
   inline T* Pop() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::Pop());
   }
 
   inline T* PopFront() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::PopFront());
   }
   
   inline T* Peek() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::Peek());
   }
   
   inline T* PeekFront() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return static_cast<T*>(nsDeque::PeekFront());
   }
 
   inline void Empty() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::Empty();
   }
 
   inline void Erase() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsDeque::Erase();
   }
 
   void Reset() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     while (GetSize() > 0) {
       T* x = PopFront();
       delete x;
     }
     mEndOfStream = PR_FALSE;
   }
 
   PRBool AtEndOfStream() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return GetSize() == 0 && mEndOfStream;    
   }
 
   // Returns PR_TRUE if the media queue has had it last sample added to it.
   // This happens when the media stream has been completely decoded. Note this
   // does not mean that the corresponding stream has finished playback.
   PRBool IsFinished() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mEndOfStream;    
   }
 
   // Informs the media queue that it won't be receiving any more samples.
   void Finish() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mEndOfStream = PR_TRUE;    
   }
 
   // Returns the approximate number of microseconds of samples in the queue.
   PRInt64 Duration() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     if (GetSize() < 2) {
       return 0;
     }
     T* last = Peek();
     T* first = PeekFront();
     return last->mTime - first->mTime;
   }
 
 private:
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 
   // PR_TRUE when we've decoded the last frame of data in the
   // bitstream for which we're queueing sample-data.
   PRBool mEndOfStream;
 };
 
 // Encapsulates the decoding and reading of media data. Reading can be done
 // on either the state machine thread (when loading and seeking) or on
 // the reader thread (when it's reading and decoding). The reader encapsulates
 // the reading state and maintains it's own monitor to ensure thread safety
 // and correctness. Never hold the nsBuiltinDecoder's monitor when calling into
 // this class.
 class nsBuiltinDecoderReader : public nsRunnable {
 public:
-  typedef mozilla::Monitor Monitor;
-  typedef mozilla::MonitorAutoEnter MonitorAutoEnter;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
+  typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
 
   nsBuiltinDecoderReader(nsBuiltinDecoder* aDecoder);
   ~nsBuiltinDecoderReader();
 
   // Initializes the reader, returns NS_OK on success, or NS_ERROR_FAILURE
   // on failure.
   virtual nsresult Init(nsBuiltinDecoderReader* aCloneDonor) = 0;
 
@@ -498,17 +498,17 @@ protected:
   // DecodeToFirstData().
   PRBool DecodeVideoFrame() {
     PRBool f = PR_FALSE;
     return DecodeVideoFrame(f, 0);
   }
 
   // The lock which we hold whenever we read or decode. This ensures the thread
   // safety of the reader and its data fields.
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 
   // Reference to the owning decoder object. Do not hold the
   // reader's monitor when accessing this.
   nsBuiltinDecoder* mDecoder;
 
   // Stores presentation info required for playback. The reader's monitor
   // must be held when accessing this.
   nsVideoInfo mInfo;
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -170,17 +170,17 @@ public:
   const PRUint32 mChannels;
   const PRUint32 mRate;
 };
 
 nsBuiltinDecoderStateMachine::nsBuiltinDecoderStateMachine(nsBuiltinDecoder* aDecoder,
                                                            nsBuiltinDecoderReader* aReader) :
   mDecoder(aDecoder),
   mState(DECODER_STATE_DECODING_METADATA),
-  mAudioMonitor("media.audiostream"),
+  mAudioReentrantMonitor("media.audiostream"),
   mCbCrSize(0),
   mPlayDuration(0),
   mStartTime(-1),
   mEndTime(-1),
   mSeekTime(0),
   mReader(aReader),
   mCurrentFrameTime(0),
   mAudioStartTime(-1),
@@ -199,36 +199,36 @@ nsBuiltinDecoderStateMachine::nsBuiltinD
 }
 
 nsBuiltinDecoderStateMachine::~nsBuiltinDecoderStateMachine()
 {
   MOZ_COUNT_DTOR(nsBuiltinDecoderStateMachine);
 }
 
 PRBool nsBuiltinDecoderStateMachine::HasFutureAudio() const {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   NS_ASSERTION(HasAudio(), "Should only call HasFutureAudio() when we have audio");
   // We've got audio ready to play if:
   // 1. We've not completed playback of audio, and
   // 2. we either have more than the threshold of decoded audio available, or
   //    we've completely decoded all audio (but not finished playing it yet
   //    as per 1).
   return !mAudioCompleted &&
          (AudioDecodedUsecs() > LOW_AUDIO_USECS || mReader->mAudioQueue.IsFinished());
 }
 
 PRBool nsBuiltinDecoderStateMachine::HaveNextFrameData() const {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   return (!HasAudio() || HasFutureAudio()) &&
          (!HasVideo() || mReader->mVideoQueue.GetSize() > 0);
 }
 
 PRInt64 nsBuiltinDecoderStateMachine::GetDecodedAudioDuration() {
   NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   PRInt64 audioDecoded = mReader->mAudioQueue.Duration();
   if (mAudioEndTime != -1) {
     audioDecoded += mAudioEndTime - GetMediaTime();
   }
   return audioDecoded;
 }
 
 void nsBuiltinDecoderStateMachine::DecodeLoop()
@@ -262,17 +262,17 @@ void nsBuiltinDecoderStateMachine::Decod
   // Our local ample audio threshold. If we increase lowAudioThreshold, we'll
   // also increase this too appropriately (we don't want lowAudioThreshold to
   // be greater than ampleAudioThreshold, else we'd stop decoding!).
   PRInt64 ampleAudioThreshold = AMPLE_AUDIO_USECS;
 
   MediaQueue<VideoData>& videoQueue = mReader->mVideoQueue;
   MediaQueue<SoundData>& audioQueue = mReader->mAudioQueue;
 
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   PRBool videoPlaying = HasVideo();
   PRBool audioPlaying = HasAudio();
 
   // Main decode loop.
   while (mState != DECODER_STATE_SHUTDOWN &&
          !mStopDecodeThreads &&
          (videoPlaying || audioPlaying))
@@ -318,17 +318,17 @@ void nsBuiltinDecoderStateMachine::Decod
         static_cast<PRUint32>(videoQueue.GetSize()) < AMPLE_VIDEO_FRAMES)
     {
       // Time the video decode, so that if it's slow, we can increase our low
       // audio threshold to reduce the chance of an audio underrun while we're
       // waiting for a video decode to complete.
       TimeDuration decodeTime;
       {
         PRInt64 currentTime = GetMediaTime();
-        MonitorAutoExit exitMon(mDecoder->GetMonitor());
+        ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
         TimeStamp start = TimeStamp::Now();
         videoPlaying = mReader->DecodeVideoFrame(skipToNextKeyframe, currentTime);
         decodeTime = TimeStamp::Now() - start;
       }
       if (THRESHOLD_FACTOR * DurationToUsecs(decodeTime) > lowAudioThreshold &&
           !HasLowUndecodedData())
       {
         lowAudioThreshold =
@@ -340,23 +340,23 @@ void nsBuiltinDecoderStateMachine::Decod
              lowAudioThreshold, ampleAudioThreshold));
       }
     }
 
     // Audio decode.
     if (audioPlaying &&
         (GetDecodedAudioDuration() < ampleAudioThreshold || audioQueue.GetSize() == 0))
     {
-      MonitorAutoExit exitMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       audioPlaying = mReader->DecodeAudioData();
     }
     
     // Notify to ensure that the AudioLoop() is not waiting, in case it was
     // waiting for more audio to be decoded.
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
 
     if (!IsPlaying()) {
       // Update the ready state, so that the play DOM events fire. We only
       // need to do this if we're not playing; if we're playing the playback
       // code will do an update whenever it advances a frame.
       UpdateReadyState();
     }
 
@@ -382,54 +382,54 @@ void nsBuiltinDecoderStateMachine::Decod
 
   } // End decode loop.
 
   if (!mStopDecodeThreads &&
       mState != DECODER_STATE_SHUTDOWN &&
       mState != DECODER_STATE_SEEKING)
   {
     mState = DECODER_STATE_COMPLETED;
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
   }
 
   LOG(PR_LOG_DEBUG, ("Shutting down DecodeLoop this=%p", this));
 }
 
 PRBool nsBuiltinDecoderStateMachine::IsPlaying()
 {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   return !mPlayStartTime.IsNull();
 }
 
 void nsBuiltinDecoderStateMachine::AudioLoop()
 {
   NS_ASSERTION(OnAudioThread(), "Should be on audio thread.");
   LOG(PR_LOG_DEBUG, ("Begun audio thread/loop"));
   PRInt64 audioDuration = 0;
   PRInt64 audioStartTime = -1;
   PRUint32 channels, rate;
   double volume = -1;
   PRBool setVolume;
   PRInt32 minWriteSamples = -1;
   PRInt64 samplesAtLastSleep = 0;
   {
-    MonitorAutoEnter mon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mAudioCompleted = PR_FALSE;
     audioStartTime = mAudioStartTime;
     channels = mInfo.mAudioChannels;
     rate = mInfo.mAudioRate;
     NS_ASSERTION(audioStartTime != -1, "Should have audio start time by now");
   }
   while (1) {
 
     // Wait while we're not playing, and we're not shutting down, or we're
     // playing and we've got no audio to play.
     {
-      MonitorAutoEnter mon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       NS_ASSERTION(mState != DECODER_STATE_DECODING_METADATA,
                    "Should have meta data before audio started playing.");
       while (mState != DECODER_STATE_SHUTDOWN &&
              !mStopDecodeThreads &&
              (!IsPlaying() ||
               mState == DECODER_STATE_BUFFERING ||
               (mReader->mAudioQueue.GetSize() == 0 &&
                !mReader->mAudioQueue.AtEndOfStream())))
@@ -450,17 +450,17 @@ void nsBuiltinDecoderStateMachine::Audio
       // changing the volume if it's the first time we've entered the loop
       // (as we must sync the volume in case it's changed since the
       // nsAudioStream was created) or if the volume has changed.
       setVolume = volume != mVolume;
       volume = mVolume;
     }
 
     if (setVolume || minWriteSamples == -1) {
-      MonitorAutoEnter audioMon(mAudioMonitor);
+      ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
       if (mAudioStream) {
         if (setVolume) {
           mAudioStream->SetVolume(volume);
         }
         if (minWriteSamples == -1) {
           minWriteSamples = mAudioStream->GetMinWriteSamples();
         }
       }
@@ -503,17 +503,17 @@ void nsBuiltinDecoderStateMachine::Audio
       // time.
       missingSamples = NS_MIN(static_cast<PRInt64>(PR_UINT32_MAX), missingSamples);
       audioDuration += PlaySilence(static_cast<PRUint32>(missingSamples),
                                    channels, playedSamples);
     } else {
       audioDuration += PlayFromAudioQueue(sampleTime, channels);
     }
     {
-      MonitorAutoEnter mon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
       PRInt64 playedUsecs;
       if (!SamplesToUsecs(audioDuration, rate, playedUsecs)) {
         NS_WARNING("Int overflow calculating playedUsecs");
         break;
       }
       if (!AddOverflow(audioStartTime, playedUsecs, mAudioEndTime)) {
         NS_WARNING("Int overflow calculating audio end time");
         break;
@@ -540,24 +540,24 @@ void nsBuiltinDecoderStateMachine::Audio
     }
   }
   if (mReader->mAudioQueue.AtEndOfStream() &&
       mState != DECODER_STATE_SHUTDOWN &&
       !mStopDecodeThreads)
   {
     // Last sample pushed to audio hardware, wait for the audio to finish,
     // before the audio thread terminates.
-    MonitorAutoEnter audioMon(mAudioMonitor);
+    ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
     if (mAudioStream) {
       PRBool seeking = PR_FALSE;
       PRInt64 oldPosition = -1;
 
       {
-        MonitorAutoExit audioExit(mAudioMonitor);
-        MonitorAutoEnter mon(mDecoder->GetMonitor());
+        ReentrantMonitorAutoExit audioExit(mAudioReentrantMonitor);
+        ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
         PRInt64 position = GetMediaTime();
         while (oldPosition != position &&
                mAudioEndTime - position > 0 &&
                mState != DECODER_STATE_SEEKING &&
                mState != DECODER_STATE_SHUTDOWN)
         {
           const PRInt64 DRAIN_BLOCK_USECS = 100000;
           Wait(NS_MIN(mAudioEndTime - position, DRAIN_BLOCK_USECS));
@@ -574,32 +574,32 @@ void nsBuiltinDecoderStateMachine::Audio
 
         // Fire one last event for any extra samples that didn't fill a framebuffer.
         mEventManager.Drain(mAudioEndTime);
       }
     }
     LOG(PR_LOG_DEBUG, ("%p Reached audio stream end.", mDecoder));
   }
   {
-    MonitorAutoEnter mon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     mAudioCompleted = PR_TRUE;
     UpdateReadyState();
     // Kick the decode and state machine threads; they may be sleeping waiting
     // for this to finish.
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
   }
   LOG(PR_LOG_DEBUG, ("Audio stream finished playing, audio thread exit"));
 }
 
 PRUint32 nsBuiltinDecoderStateMachine::PlaySilence(PRUint32 aSamples,
                                                    PRUint32 aChannels,
                                                    PRUint64 aSampleOffset)
 
 {
-  MonitorAutoEnter audioMon(mAudioMonitor);
+  ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
   if (!mAudioStream || mAudioStream->IsPaused()) {
     // The state machine has paused since we've released the decoder
     // monitor and acquired the audio monitor. Don't write any audio.
     return 0;
   }
   PRUint32 maxSamples = SILENCE_BYTES_CHUNK / aChannels;
   PRUint32 samples = NS_MIN(aSamples, maxSamples);
   PRUint32 numValues = samples * aChannels;
@@ -612,26 +612,26 @@ PRUint32 nsBuiltinDecoderStateMachine::P
   return samples;
 }
 
 PRUint32 nsBuiltinDecoderStateMachine::PlayFromAudioQueue(PRUint64 aSampleOffset,
                                                           PRUint32 aChannels)
 {
   nsAutoPtr<SoundData> sound(mReader->mAudioQueue.PopFront());
   {
-    MonitorAutoEnter mon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     NS_WARN_IF_FALSE(IsPlaying(), "Should be playing");
     // Awaken the decode loop if it's waiting for space to free up in the
     // audio queue.
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
   }
   PRInt64 offset = -1;
   PRUint32 samples = 0;
   {
-    MonitorAutoEnter audioMon(mAudioMonitor);
+    ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
     if (!mAudioStream) {
       return 0;
     }
     // The state machine could have paused since we've released the decoder
     // monitor and acquired the audio monitor. Rather than acquire both
     // monitors, the audio stream also maintains whether its paused or not.
     // This prevents us from doing a blocking write while holding the audio
     // monitor while paused; we would block, and the state machine won't be
@@ -668,32 +668,32 @@ nsresult nsBuiltinDecoderStateMachine::I
   }
   return mReader->Init(cloneReader);
 }
 
 void nsBuiltinDecoderStateMachine::StopPlayback(eStopMode aMode)
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   mDecoder->mPlaybackStatistics.Stop(TimeStamp::Now());
 
   // Reset mPlayStartTime before we pause/shutdown the nsAudioStream. This is
   // so that if the audio loop is about to write audio, it will have the chance
   // to check to see if we're paused and not write the audio. If not, the
   // audio thread can block in the write, and we deadlock trying to acquire
   // the audio monitor upon resume playback.
   if (IsPlaying()) {
     mPlayDuration += DurationToUsecs(TimeStamp::Now() - mPlayStartTime);
     mPlayStartTime = TimeStamp();
   }
   if (HasAudio()) {
-    MonitorAutoExit exitMon(mDecoder->GetMonitor());
-    MonitorAutoEnter audioMon(mAudioMonitor);
+    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
+    ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
     if (mAudioStream) {
       if (aMode == AUDIO_PAUSE) {
         mAudioStream->Pause();
       } else if (aMode == AUDIO_SHUTDOWN) {
         mAudioStream->Shutdown();
         mAudioStream = nsnull;
         mEventManager.Clear();
       }
@@ -701,47 +701,47 @@ void nsBuiltinDecoderStateMachine::StopP
   }
 }
 
 void nsBuiltinDecoderStateMachine::StartPlayback()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
   NS_ASSERTION(!IsPlaying(), "Shouldn't be playing when StartPlayback() is called");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   LOG(PR_LOG_DEBUG, ("%p StartPlayback", mDecoder));
   mDecoder->mPlaybackStatistics.Start(TimeStamp::Now());
   if (HasAudio()) {
     PRInt32 rate = mInfo.mAudioRate;
     PRInt32 channels = mInfo.mAudioChannels;
 
     {
-      MonitorAutoExit exitMon(mDecoder->GetMonitor());
-      MonitorAutoEnter audioMon(mAudioMonitor);
+      ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
+      ReentrantMonitorAutoEnter audioMon(mAudioReentrantMonitor);
       if (mAudioStream) {
         // We have an audiostream, so it must have been paused the last time
         // StopPlayback() was called.
         mAudioStream->Resume();
       } else {
         // No audiostream, create one.
         mAudioStream = nsAudioStream::AllocateStream();
         mAudioStream->Init(channels, rate, MOZ_SOUND_DATA_FORMAT);
         mAudioStream->SetVolume(mVolume);
       }
     }
   }
   mPlayStartTime = TimeStamp::Now();
-  mDecoder->GetMonitor().NotifyAll();
+  mDecoder->GetReentrantMonitor().NotifyAll();
 }
 
 void nsBuiltinDecoderStateMachine::UpdatePlaybackPositionInternal(PRInt64 aTime)
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   NS_ASSERTION(mStartTime >= 0, "Should have positive mStartTime");
   mCurrentFrameTime = aTime - mStartTime;
   NS_ASSERTION(mCurrentFrameTime >= 0, "CurrentTime should be positive!");
   if (aTime > mEndTime) {
     NS_ASSERTION(mCurrentFrameTime > GetDuration(),
                  "CurrentTime must be after duration if aTime > endTime!");
     mEndTime = aTime;
@@ -764,134 +764,134 @@ void nsBuiltinDecoderStateMachine::Updat
 
   // Notify DOM of any queued up audioavailable events
   mEventManager.DispatchPendingEvents(GetMediaTime());
 }
 
 void nsBuiltinDecoderStateMachine::ClearPositionChangeFlag()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   mPositionChangeQueued = PR_FALSE;
 }
 
 nsHTMLMediaElement::NextFrameStatus nsBuiltinDecoderStateMachine::GetNextFrameStatus()
 {
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   if (IsBuffering() || IsSeeking()) {
     return nsHTMLMediaElement::NEXT_FRAME_UNAVAILABLE_BUFFERING;
   } else if (HaveNextFrameData()) {
     return nsHTMLMediaElement::NEXT_FRAME_AVAILABLE;
   }
   return nsHTMLMediaElement::NEXT_FRAME_UNAVAILABLE;
 }
 
 void nsBuiltinDecoderStateMachine::SetVolume(double volume)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   mVolume = volume;
 }
 
 double nsBuiltinDecoderStateMachine::GetCurrentTime() const
 {
   NS_ASSERTION(NS_IsMainThread() ||
                mDecoder->OnStateMachineThread() ||
                OnDecodeThread(),
                "Should be on main, decode, or state machine thread.");
 
   return static_cast<double>(mCurrentFrameTime) / static_cast<double>(USECS_PER_S);
 }
 
 PRInt64 nsBuiltinDecoderStateMachine::GetDuration()
 {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (mEndTime == -1 || mStartTime == -1)
     return -1;
   return mEndTime - mStartTime;
 }
 
 void nsBuiltinDecoderStateMachine::SetDuration(PRInt64 aDuration)
 {
   NS_ASSERTION(NS_IsMainThread() || mDecoder->OnStateMachineThread(),
     "Should be on main or state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (mStartTime != -1) {
     mEndTime = mStartTime + aDuration;
   } else {
     mStartTime = 0;
     mEndTime = aDuration;
   }
 }
 
 void nsBuiltinDecoderStateMachine::SetSeekable(PRBool aSeekable)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   mSeekable = aSeekable;
 }
 
 void nsBuiltinDecoderStateMachine::Shutdown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
 
   // Once we've entered the shutdown state here there's no going back.
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   // Change state before issuing shutdown request to threads so those
   // threads can start exiting cleanly during the Shutdown call.
   LOG(PR_LOG_DEBUG, ("%p Changed state to SHUTDOWN", mDecoder));
   mState = DECODER_STATE_SHUTDOWN;
-  mDecoder->GetMonitor().NotifyAll();
+  mDecoder->GetReentrantMonitor().NotifyAll();
 }
 
 void nsBuiltinDecoderStateMachine::StartDecoding()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   if (mState != DECODER_STATE_DECODING) {
     mDecodeStartTime = TimeStamp::Now();
   }
   mState = DECODER_STATE_DECODING;
 }
 
 void nsBuiltinDecoderStateMachine::Play()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
   // When asked to play, switch to decoding state only if
   // we are currently buffering. In other cases, we'll start playing anyway
   // when the state machine notices the decoder's state change to PLAYING.
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   if (mState == DECODER_STATE_BUFFERING) {
     LOG(PR_LOG_DEBUG, ("%p Changed state from BUFFERING to DECODING", mDecoder));
     mState = DECODER_STATE_DECODING;
     mDecodeStartTime = TimeStamp::Now();
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
   }
 }
 
 void nsBuiltinDecoderStateMachine::ResetPlayback()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
   mVideoFrameEndTime = -1;
   mAudioStartTime = -1;
   mAudioEndTime = -1;
   mAudioCompleted = PR_FALSE;
 }
 
 void nsBuiltinDecoderStateMachine::Seek(double aTime)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  MonitorAutoEnter mon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   // nsBuiltinDecoder::mPlayState should be SEEKING while we seek, and
   // in that case nsBuiltinDecoder shouldn't be calling us.
   NS_ASSERTION(mState != DECODER_STATE_SEEKING,
                "We shouldn't already be seeking");
   NS_ASSERTION(mState >= DECODER_STATE_DECODING,
                "We should have loaded metadata");
   double t = aTime * static_cast<double>(USECS_PER_S);
   if (t > PR_INT64_MAX) {
@@ -911,41 +911,41 @@ void nsBuiltinDecoderStateMachine::Seek(
   LOG(PR_LOG_DEBUG, ("%p Changed state to SEEKING (to %f)", mDecoder, aTime));
   mState = DECODER_STATE_SEEKING;
 }
 
 void nsBuiltinDecoderStateMachine::StopDecodeThreads()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   mStopDecodeThreads = PR_TRUE;
-  mDecoder->GetMonitor().NotifyAll();
+  mDecoder->GetReentrantMonitor().NotifyAll();
   if (mDecodeThread) {
     {
-      MonitorAutoExit exitMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       mDecodeThread->Shutdown();
     }
     mDecodeThread = nsnull;
   }
   if (mAudioThread) {
     {
-      MonitorAutoExit exitMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
       mAudioThread->Shutdown();
     }
     mAudioThread = nsnull;
   }
 }
 
 nsresult
 nsBuiltinDecoderStateMachine::StartDecodeThreads()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   mStopDecodeThreads = PR_FALSE;
   if (!mDecodeThread && mState < DECODER_STATE_COMPLETED) {
     nsresult rv = NS_NewThread(getter_AddRefs(mDecodeThread));
     if (NS_FAILED(rv)) {
       mState = DECODER_STATE_SHUTDOWN;
       return rv;
     }
     nsCOMPtr<nsIRunnable> event =
@@ -973,17 +973,17 @@ PRInt64 nsBuiltinDecoderStateMachine::Au
   // already decoded and pushed to the hardware, plus the amount of audio
   // data waiting to be pushed to the hardware.
   PRInt64 pushed = (mAudioEndTime != -1) ? (mAudioEndTime - GetMediaTime()) : 0;
   return pushed + mReader->mAudioQueue.Duration();
 }
 
 PRBool nsBuiltinDecoderStateMachine::HasLowDecodedData(PRInt64 aAudioUsecs) const
 {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   // We consider ourselves low on decoded data if we're low on audio,
   // provided we've not decoded to the end of the audio stream, or
   // if we're only playing video and we're low on video frames, provided
   // we've not decoded to the end of the video stream.
   return ((HasAudio() &&
            !mReader->mAudioQueue.IsFinished() &&
            AudioDecodedUsecs() < aAudioUsecs)
           ||
@@ -995,17 +995,17 @@ PRBool nsBuiltinDecoderStateMachine::Has
 
 PRBool nsBuiltinDecoderStateMachine::HasLowUndecodedData() const
 {
   return GetUndecodedData() < LOW_DATA_THRESHOLD_USECS;
 }
 
 PRInt64 nsBuiltinDecoderStateMachine::GetUndecodedData() const
 {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   NS_ASSERTION(mState > DECODER_STATE_DECODING_METADATA,
                "Must have loaded metadata for GetBuffered() to work");
   nsTimeRanges buffered;
   
   nsresult res = mDecoder->GetBuffered(&buffered);
   NS_ENSURE_SUCCESS(res, 0);
   double currentTime = GetCurrentTime();
 
@@ -1028,29 +1028,29 @@ PRInt64 nsBuiltinDecoderStateMachine::Ge
   }
   return 0;
 }
 
 void nsBuiltinDecoderStateMachine::SetFrameBufferLength(PRUint32 aLength)
 {
   NS_ASSERTION(aLength >= 512 && aLength <= 16384,
                "The length must be between 512 and 16384");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   mEventManager.SetSignalBufferLength(aLength);
 }
 
 nsresult nsBuiltinDecoderStateMachine::Run()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   NS_ENSURE_TRUE(stream, NS_ERROR_NULL_POINTER);
 
   while (PR_TRUE) {
-    MonitorAutoEnter mon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
     switch (mState) {
     case DECODER_STATE_SHUTDOWN:
       if (IsPlaying()) {
         StopPlayback(AUDIO_SHUTDOWN);
       }
       StopDecodeThreads();
       NS_ASSERTION(mState == DECODER_STATE_SHUTDOWN,
                    "How did we escape from the shutdown state???");
@@ -1063,17 +1063,17 @@ nsresult nsBuiltinDecoderStateMachine::R
           continue;
         }
 
         VideoData* videoData = FindStartTime();
         if (videoData) {
           nsIntSize display = mInfo.mDisplay;
           float aspect = mInfo.mPixelAspectRatio;
           {
-            MonitorAutoExit exitMon(mDecoder->GetMonitor());
+            ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
             RenderVideoFrame(videoData, TimeStamp::Now(), display, aspect);
           }
         }
 
         // Start the decode threads, so that we can pre buffer the streams.
         // and calculate the start time in order to determine the duration.
         if (NS_FAILED(StartDecodeThreads())) {
           continue;
@@ -1152,32 +1152,32 @@ nsresult nsBuiltinDecoderStateMachine::R
           currentTimeChanged = true;
           UpdatePlaybackPositionInternal(seekTime);
         }
 
         // SeekingStarted will do a UpdateReadyStateForData which will
         // inform the element and its users that we have no frames
         // to display
         {
-          MonitorAutoExit exitMon(mDecoder->GetMonitor());
+          ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
           nsCOMPtr<nsIRunnable> startEvent =
             NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::SeekingStarted);
           NS_DispatchToMainThread(startEvent, NS_DISPATCH_SYNC);
         }
 
         if (currentTimeChanged) {
           // The seek target is different than the current playback position,
           // we'll need to seek the playback position, so shutdown our decode
           // and audio threads.
           StopPlayback(AUDIO_SHUTDOWN);
           StopDecodeThreads();
           ResetPlayback();
           nsresult res;
           {
-            MonitorAutoExit exitMon(mDecoder->GetMonitor());
+            ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
             // Now perform the seek. We must not hold the state machine monitor
             // while we seek, since the seek decodes.
             res = mReader->Seek(seekTime,
                                 mStartTime,
                                 mEndTime,
                                 mediaTime);
           }
           if (NS_SUCCEEDED(res)){
@@ -1191,17 +1191,17 @@ nsresult nsBuiltinDecoderStateMachine::R
             if (HasVideo()) {
               nsAutoPtr<VideoData> video(mReader->mVideoQueue.PeekFront());
               if (video) {
                 NS_ASSERTION(video->mTime <= seekTime && seekTime <= video->mEndTime,
                              "Seek target should lie inside the first frame after seek");
                 nsIntSize display = mInfo.mDisplay;
                 float aspect = mInfo.mPixelAspectRatio;
                 {
-                  MonitorAutoExit exitMon(mDecoder->GetMonitor());
+                  ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
                   RenderVideoFrame(video, TimeStamp::Now(), display, aspect);
                 }
                 mReader->mVideoQueue.PopFront();
                 nsCOMPtr<nsIRunnable> event =
                   NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::Invalidate);
                 NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
               }
             }
@@ -1225,35 +1225,35 @@ nsresult nsBuiltinDecoderStateMachine::R
           stopEvent = NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::SeekingStoppedAtEnd);
           mState = DECODER_STATE_COMPLETED;
         } else {
           LOG(PR_LOG_DEBUG, ("%p Changed state from SEEKING (to %lld) to DECODING",
                              mDecoder, seekTime));
           stopEvent = NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::SeekingStopped);
           StartDecoding();
         }
-        mDecoder->GetMonitor().NotifyAll();
+        mDecoder->GetReentrantMonitor().NotifyAll();
 
         {
-          MonitorAutoExit exitMon(mDecoder->GetMonitor());
+          ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
           NS_DispatchToMainThread(stopEvent, NS_DISPATCH_SYNC);
         }
 
         // Reset quick buffering status. This ensures that if we began the
         // seek while quick-buffering, we won't bypass quick buffering mode
         // if we need to buffer after the seek.
         mQuickBuffering = PR_FALSE;
       }
       break;
 
     case DECODER_STATE_BUFFERING:
       {
         if (IsPlaying()) {
           StopPlayback(AUDIO_PAUSE);
-          mDecoder->GetMonitor().NotifyAll();
+          mDecoder->GetReentrantMonitor().NotifyAll();
         }
 
         TimeStamp now = TimeStamp::Now();
         NS_ASSERTION(!mBufferingStart.IsNull(), "Must know buffering start time.");
 
         // We will remain in the buffering state if we've not decoded enough
         // data to begin playback, or if we've not downloaded a reasonable
         // amount of data inside our buffering time.
@@ -1280,17 +1280,17 @@ nsresult nsBuiltinDecoderStateMachine::R
           LOG(PR_LOG_DEBUG, ("%p Buffered for %.3lfs",
                              mDecoder,
                              (now - mBufferingStart).ToSeconds()));
           StartDecoding();
         }
 
         if (mState != DECODER_STATE_BUFFERING) {
           // Notify to allow blocked decoder thread to continue
-          mDecoder->GetMonitor().NotifyAll();
+          mDecoder->GetReentrantMonitor().NotifyAll();
           UpdateReadyState();
           if (mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING) {
             if (!IsPlaying()) {
               StartPlayback();
             }
           }
         }
         break;
@@ -1324,17 +1324,17 @@ nsresult nsBuiltinDecoderStateMachine::R
         LOG(PR_LOG_DEBUG, ("Shutting down the state machine thread"));
         StopDecodeThreads();
 
         if (mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING) {
           PRInt64 videoTime = HasVideo() ? mVideoFrameEndTime : 0;
           PRInt64 clockTime = NS_MAX(mEndTime, NS_MAX(videoTime, GetAudioClock()));
           UpdatePlaybackPosition(clockTime);
           {
-            MonitorAutoExit exitMon(mDecoder->GetMonitor());
+            ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
             nsCOMPtr<nsIRunnable> event =
               NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::PlaybackEnded);
             NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
           }
         }
 
         if (mState == DECODER_STATE_COMPLETED) {
           // We've finished playback. Shutdown the state machine thread, 
@@ -1354,17 +1354,17 @@ nsresult nsBuiltinDecoderStateMachine::R
 }
 
 void nsBuiltinDecoderStateMachine::RenderVideoFrame(VideoData* aData,
                                                     TimeStamp aTarget,
                                                     nsIntSize aDisplaySize,
                                                     float aAspectRatio)
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread), "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertNotCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
 
   if (aData->mDuplicate) {
     return;
   }
 
   nsRefPtr<Image> image = aData->mImage;
   if (image) {
     mDecoder->SetVideoData(gfxIntSize(aDisplaySize.width, aDisplaySize.height),
@@ -1380,17 +1380,17 @@ nsBuiltinDecoderStateMachine::GetAudioCl
     return -1;
   PRInt64 t = mAudioStream->GetPosition();
   return (t == -1) ? -1 : t + mAudioStartTime;
 }
 
 void nsBuiltinDecoderStateMachine::AdvanceFrame()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread), "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   // When it's time to display a frame, decode the frame and display it.
   if (mDecoder->GetState() == nsBuiltinDecoder::PLAY_STATE_PLAYING) {
     if (HasAudio() && mAudioStartTime == -1 && !mAudioCompleted) {
       // We've got audio (so we should sync off the audio clock), but we've not
       // played a sample on the audio thread, so we can't get a time from the
       // audio clock. Just wait and then return, to give the audio clock time
       // to tick.  This should really wait for a specific signal from the audio
@@ -1464,43 +1464,43 @@ void nsBuiltinDecoderStateMachine::Advan
       StartBuffering();
       return;
     }
 
     // We've got enough data to keep playing until at least the next frame.
     // Start playing now if need be.
     if (!IsPlaying()) {
       StartPlayback();
-      mDecoder->GetMonitor().NotifyAll();
+      mDecoder->GetReentrantMonitor().NotifyAll();
     }
 
     if (currentFrame) {
       // Decode one frame and display it.
       TimeStamp presTime = mPlayStartTime - UsecsToDuration(mPlayDuration) +
                            UsecsToDuration(currentFrame->mTime - mStartTime);
       NS_ASSERTION(currentFrame->mTime >= mStartTime, "Should have positive frame time");
       {
         nsIntSize display = mInfo.mDisplay;
         float aspect = mInfo.mPixelAspectRatio;
         {
-          MonitorAutoExit exitMon(mDecoder->GetMonitor());
+          ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
           // If we have video, we want to increment the clock in steps of the frame
           // duration.
           RenderVideoFrame(currentFrame, presTime, display, aspect);
         }
       }
       mDecoder->GetFrameStatistics().NotifyPresentedFrame();
       PRInt64 now = DurationToUsecs(TimeStamp::Now() - mPlayStartTime) + mPlayDuration;
       remainingTime = currentFrame->mEndTime - mStartTime - now;
       currentFrame = nsnull;
     }
 
     // Kick the decode thread in case it filled its buffers and put itself
     // to sleep.
-    mDecoder->GetMonitor().NotifyAll();
+    mDecoder->GetReentrantMonitor().NotifyAll();
 
     // Cap the current time to the larger of the audio and video end time.
     // This ensures that if we're running off the system clock, we don't
     // advance the clock to after the media end time.
     if (mVideoFrameEndTime != -1 || mAudioEndTime != -1) {
       // These will be non -1 if we've displayed a video frame, or played an audio sample.
       clock_time = NS_MIN(clock_time, NS_MAX(mVideoFrameEndTime, mAudioEndTime));
       if (clock_time > GetMediaTime()) {
@@ -1519,51 +1519,51 @@ void nsBuiltinDecoderStateMachine::Advan
     UpdateReadyState();
 
     if (remainingTime > 0) {
       Wait(remainingTime);
     }
   } else {
     if (IsPlaying()) {
       StopPlayback(AUDIO_PAUSE);
-      mDecoder->GetMonitor().NotifyAll();
+      mDecoder->GetReentrantMonitor().NotifyAll();
     }
 
     if (mState == DECODER_STATE_DECODING ||
         mState == DECODER_STATE_COMPLETED) {
-      mDecoder->GetMonitor().Wait();
+      mDecoder->GetReentrantMonitor().Wait();
     }
   }
 }
 
 void nsBuiltinDecoderStateMachine::Wait(PRInt64 aUsecs) {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   TimeStamp end = TimeStamp::Now() + UsecsToDuration(aUsecs);
   TimeStamp now;
   while ((now = TimeStamp::Now()) < end &&
          mState != DECODER_STATE_SHUTDOWN &&
          mState != DECODER_STATE_SEEKING)
   {
     PRInt64 ms = static_cast<PRInt64>(NS_round((end - now).ToSeconds() * 1000));
     if (ms == 0 || ms > PR_UINT32_MAX) {
       break;
     }
-    mDecoder->GetMonitor().Wait(PR_MillisecondsToInterval(static_cast<PRUint32>(ms)));
+    mDecoder->GetReentrantMonitor().Wait(PR_MillisecondsToInterval(static_cast<PRUint32>(ms)));
   }
 }
 
 VideoData* nsBuiltinDecoderStateMachine::FindStartTime()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread), "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
   PRInt64 startTime = 0;
   mStartTime = 0;
   VideoData* v = nsnull;
   {
-    MonitorAutoExit exitMon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
     v = mReader->FindStartTime(0, startTime);
   }
   if (startTime != 0) {
     mStartTime = startTime;
     if (mGotDurationFromMetaData) {
       NS_ASSERTION(mEndTime != -1,
                    "We should have mEndTime as supplied duration here");
       // We were specified a duration from a Content-Duration HTTP header.
@@ -1578,39 +1578,39 @@ VideoData* nsBuiltinDecoderStateMachine:
   mAudioStartTime = mStartTime;
   LOG(PR_LOG_DEBUG, ("%p Media start time is %lld", mDecoder, mStartTime));
   return v;
 }
 
 void nsBuiltinDecoderStateMachine::FindEndTime() 
 {
   NS_ASSERTION(OnStateMachineThread(), "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   nsMediaStream* stream = mDecoder->GetCurrentStream();
 
   // Seek to the end of file to find the length and duration.
   PRInt64 length = stream->GetLength();
   NS_ASSERTION(length > 0, "Must have a content length to get end time");
 
   mEndTime = 0;
   PRInt64 endTime = 0;
   {
-    MonitorAutoExit exitMon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
     endTime = mReader->FindEndTime(length);
   }
   if (endTime != -1) {
     mEndTime = endTime;
   }
 
   LOG(PR_LOG_DEBUG, ("%p Media end time is %lld", mDecoder, mEndTime));   
 }
 
 void nsBuiltinDecoderStateMachine::UpdateReadyState() {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   nsCOMPtr<nsIRunnable> event;
   switch (GetNextFrameStatus()) {
     case nsHTMLMediaElement::NEXT_FRAME_UNAVAILABLE_BUFFERING:
       event = NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::NextFrameUnavailableBuffering);
       break;
     case nsHTMLMediaElement::NEXT_FRAME_AVAILABLE:
       event = NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::NextFrameAvailable);
@@ -1624,23 +1624,23 @@ void nsBuiltinDecoderStateMachine::Updat
 
   NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
 }
 
 void nsBuiltinDecoderStateMachine::LoadMetadata()
 {
   NS_ASSERTION(IsCurrentThread(mDecoder->mStateMachineThread),
                "Should be on state machine thread.");
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   LOG(PR_LOG_DEBUG, ("Loading Media Headers"));
   nsresult res;
   nsVideoInfo info;
   {
-    MonitorAutoExit exitMon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
     res = mReader->ReadMetadata(&info);
   }
   mInfo = info;
 
   if (NS_FAILED(res) || (!info.mHasVideo && !info.mHasAudio)) {
     mState = DECODER_STATE_SHUTDOWN;      
     nsCOMPtr<nsIRunnable> event =
       NS_NewRunnableMethod(mDecoder, &nsBuiltinDecoder::DecodeError);
@@ -1655,17 +1655,17 @@ PRBool nsBuiltinDecoderStateMachine::Jus
 {
   return !mDecodeStartTime.IsNull() &&
     mQuickBuffering &&
     (TimeStamp::Now() - mDecodeStartTime) < TimeDuration::FromSeconds(QUICK_BUFFER_THRESHOLD_USECS);
 }
 
 void nsBuiltinDecoderStateMachine::StartBuffering()
 {
-  mDecoder->GetMonitor().AssertCurrentThreadIn();
+  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
   TimeDuration decodeDuration = TimeStamp::Now() - mDecodeStartTime;
   // Go into quick buffering mode provided we've not just left buffering using
   // a "quick exit". This stops us flip-flopping between playing and buffering
   // when the download speed is similar to the decode speed.
   mQuickBuffering =
     !JustExitedQuickBuffering() &&
     decodeDuration < UsecsToDuration(QUICK_BUFFER_THRESHOLD_USECS);
--- a/content/media/nsBuiltinDecoderStateMachine.h
+++ b/content/media/nsBuiltinDecoderStateMachine.h
@@ -113,17 +113,17 @@ not yet time to display the next frame.
 #define nsBuiltinDecoderStateMachine_h__
 
 #include "prmem.h"
 #include "nsThreadUtils.h"
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderReader.h"
 #include "nsAudioAvailableEventManager.h"
 #include "nsHTMLMediaElement.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 /*
   The playback state machine class. This manages the decoding in the
   nsBuiltinDecoderReader on the decode thread, seeking and in-sync-playback on the
   state machine thread, and controls the audio "push" thread.
 
   All internal state is synchronised via the decoder monitor. NotifyAll
   on the monitor is called when the state of the state machine is changed
@@ -135,28 +135,28 @@ not yet time to display the next frame.
     Frame decoded
     data pushed or popped from the video and audio queues
 
   See nsBuiltinDecoder.h for more details.
 */
 class nsBuiltinDecoderStateMachine : public nsDecoderStateMachine
 {
 public:
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::TimeDuration TimeDuration;
 
   nsBuiltinDecoderStateMachine(nsBuiltinDecoder* aDecoder, nsBuiltinDecoderReader* aReader);
   ~nsBuiltinDecoderStateMachine();
 
   // nsDecoderStateMachine interface
   virtual nsresult Init(nsDecoderStateMachine* aCloneDonor);
   State GetState()
   { 
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mState; 
   }
   virtual void SetVolume(double aVolume);
   virtual void Shutdown();
   virtual PRInt64 GetDuration();
   virtual void SetDuration(PRInt64 aDuration);
   virtual PRBool OnDecodeThread() const {
     return IsCurrentThread(mDecodeThread);
@@ -178,40 +178,40 @@ public:
 
   // State machine thread run function. Polls the state, sends frames to be
   // displayed at appropriate times, and generally manages the decode.
   NS_IMETHOD Run();
 
   // This is called on the state machine thread and audio thread.
   // The decoder monitor must be obtained before calling this.
   PRBool HasAudio() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mInfo.mHasAudio;
   }
 
   // This is called on the state machine thread and audio thread.
   // The decoder monitor must be obtained before calling this.
   PRBool HasVideo() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mInfo.mHasVideo;
   }
 
   // Should be called by main thread.
   PRBool HaveNextFrameData() const;
 
   // Must be called with the decode monitor held.
   PRBool IsBuffering() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
     return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_BUFFERING;
   }
 
   // Must be called with the decode monitor held.
   PRBool IsSeeking() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
 
     return mState == nsBuiltinDecoderStateMachine::DECODER_STATE_SEEKING;
   }
 
   // Functions used by assertions to ensure we're calling things
   // on the appropriate threads.
   PRBool OnAudioThread() {
     return IsCurrentThread(mAudioThread);
@@ -238,17 +238,17 @@ public:
   nsresult GetBuffered(nsTimeRanges* aBuffered);
 
   void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset) {
     NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
     mReader->NotifyDataArrived(aBuffer, aLength, aOffset);
   }
 
   PRInt64 GetEndMediaTime() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mEndTime;
   }
 
   // Sets the current frame buffer length for the MozAudioAvailable event.
   // Accessed on the main and state machine threads.
   virtual void SetFrameBufferLength(PRUint32 aLength);
 
 protected:
@@ -273,17 +273,17 @@ protected:
 
   // Returns PR_TRUE when there's decoded audio waiting to play.
   // The decoder monitor must be held.
   PRBool HasFutureAudio() const;
 
   // Returns PR_TRUE if we recently exited "quick buffering" mode.
   PRBool JustExitedQuickBuffering();
 
-  // Waits on the decoder Monitor for aUsecs microseconds. If the decoder
+  // Waits on the decoder ReentrantMonitor for aUsecs microseconds. If the decoder
   // monitor is awoken by a Notify() call, we'll continue waiting, unless
   // we've moved into shutdown state. This enables us to ensure that we
   // wait for a specified time, and that the myriad of Notify()s we do an
   // the decoder monitor don't cause the audio thread to be starved. The
   // decoder monitor must be locked.
   void Wait(PRInt64 aUsecs);
 
   // Dispatches an asynchronous event to update the media element's ready state.
@@ -384,34 +384,34 @@ protected:
   PRBool IsPlaying();
 
   // Returns the "media time". This is the absolute time which the media
   // playback has reached. i.e. this returns values in the range
   // [mStartTime, mEndTime], and mStartTime will not be 0 if the media does
   // not start at 0. Note this is different to the value returned
   // by GetCurrentTime(), which is in the range [0,duration].
   PRInt64 GetMediaTime() const {
-    mDecoder->GetMonitor().AssertCurrentThreadIn();
+    mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
     return mStartTime + mCurrentFrameTime;
   }
 
   // Returns an upper bound on the number of microseconds of audio that is
   // decoded and playable. This is the sum of the number of usecs of audio which
   // is decoded and in the reader's audio queue, and the usecs of unplayed audio
   // which has been pushed to the audio hardware for playback. Note that after
   // calling this, the audio hardware may play some of the audio pushed to
   // hardware, so this can only be used as a upper bound. The decoder monitor
   // must be held when calling this. Called on the decoder thread.
   PRInt64 GetDecodedAudioDuration();
 
-  // Monitor on mAudioStream. This monitor must be held in order to delete
-  // or use the audio stream. This stops us destroying the audio stream
-  // while it's being used on another thread (typically when it's being
-  // written to on the audio thread).
-  Monitor mAudioMonitor;
+  // ReentrantMonitor on mAudioStream. This monitor must be held in
+  // order to delete or use the audio stream. This stops us destroying
+  // the audio stream while it's being used on another thread
+  // (typically when it's being written to on the audio thread).
+  ReentrantMonitor mAudioReentrantMonitor;
 
   // The size of the decoded YCbCr frame.
   // Accessed on state machine thread.
   PRUint32 mCbCrSize;
 
   // Accessed on state machine thread.
   nsAutoArrayPtr<unsigned char> mCbCrBuffer;
 
@@ -449,19 +449,19 @@ protected:
   // machine and main thread. Access controlled by decoder monitor.
   PRInt64 mEndTime;
 
   // Position to seek to in microseconds when the seek state transition occurs.
   // The decoder monitor lock must be obtained before reading or writing
   // this value. Accessed on main and state machine thread.
   PRInt64 mSeekTime;
 
-  // The audio stream resource. Used on the state machine, audio, and main
-  // threads. You must hold the mAudioMonitor, and must NOT hold the decoder
-  // monitor when using the audio stream!
+  // The audio stream resource. Used on the state machine, audio, and
+  // main threads. You must hold the mAudioReentrantMonitor, and must
+  // NOT hold the decoder monitor when using the audio stream!
   nsRefPtr<nsAudioStream> mAudioStream;
 
   // The reader, don't call its methods with the decoder monitor held.
   // This is created in the play state machine's constructor, and destroyed
   // in the play state machine's destructor.
   nsAutoPtr<nsBuiltinDecoderReader> mReader;
 
   // The time of the current frame in microseconds. This is referenced from
--- a/content/media/nsMediaCache.cpp
+++ b/content/media/nsMediaCache.cpp
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/XPCOM.h"
 
 #include "nsMediaCache.h"
 #include "nsContentUtils.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsNetUtil.h"
 #include "prio.h"
@@ -129,17 +129,17 @@ class nsMediaCache {
 public:
   friend class nsMediaCacheStream::BlockList;
   typedef nsMediaCacheStream::BlockList BlockList;
   enum {
     BLOCK_SIZE = nsMediaCacheStream::BLOCK_SIZE
   };
 
   nsMediaCache() : mNextResourceID(1),
-    mMonitor("nsMediaCache.mMonitor"),
+    mReentrantMonitor("nsMediaCache.mReentrantMonitor"),
     mFD(nsnull), mFDCurrentPos(0), mUpdateQueued(PR_FALSE)
 #ifdef DEBUG
     , mInUpdate(PR_FALSE)
 #endif
   {
     MOZ_COUNT_CTOR(nsMediaCache);
   }
   ~nsMediaCache() {
@@ -163,39 +163,39 @@ public:
   // shutting it down cleans things up and releases disk space.
   static void MaybeShutdown();
 
   // Brutally flush the cache contents. Main thread only.
   static void Flush();
   void FlushInternal();
 
   // Cache-file access methods. These are the lowest-level cache methods.
-  // mMonitor must be held; these can be called on any thread.
+  // mReentrantMonitor must be held; these can be called on any thread.
   // This can return partial reads.
   nsresult ReadCacheFile(PRInt64 aOffset, void* aData, PRInt32 aLength,
                          PRInt32* aBytes);
   // This will fail if all aLength bytes are not read
   nsresult ReadCacheFileAllBytes(PRInt64 aOffset, void* aData, PRInt32 aLength);
   // This will fail if all aLength bytes are not written
   nsresult WriteCacheFile(PRInt64 aOffset, const void* aData, PRInt32 aLength);
 
-  // mMonitor must be held, called on main thread.
+  // mReentrantMonitor must be held, called on main thread.
   // These methods are used by the stream to set up and tear down streams,
   // and to handle reads and writes.
   // Add aStream to the list of streams.
   void OpenStream(nsMediaCacheStream* aStream);
   // Remove aStream from the list of streams.
   void ReleaseStream(nsMediaCacheStream* aStream);
   // Free all blocks belonging to aStream.
   void ReleaseStreamBlocks(nsMediaCacheStream* aStream);
   // Find a cache entry for this data, and write the data into it
   void AllocateAndWriteBlock(nsMediaCacheStream* aStream, const void* aData,
                              nsMediaCacheStream::ReadMode aMode);
 
-  // mMonitor must be held; can be called on any thread
+  // mReentrantMonitor must be held; can be called on any thread
   // Notify the cache that a seek has been requested. Some blocks may
   // need to change their class between PLAYED_BLOCK and READAHEAD_BLOCK.
   // This does not trigger channel seeks directly, the next Update()
   // will do that if necessary. The caller will call QueueUpdate().
   void NoteSeek(nsMediaCacheStream* aStream, PRInt64 aOldOffset);
   // Notify the cache that a block has been read from. This is used
   // to update last-use times. The block may not actually have a
   // cache entry yet since Read can read data from a stream's
@@ -222,17 +222,17 @@ public:
 
 #ifdef DEBUG_VERIFY_CACHE
   // Verify invariants, especially block list invariants
   void Verify();
 #else
   void Verify() {}
 #endif
 
-  Monitor& GetMonitor() { return mMonitor; }
+  ReentrantMonitor& GetReentrantMonitor() { return mReentrantMonitor; }
 
   /**
    * An iterator that makes it easy to iterate through all streams that
    * have a given resource ID and are not closed.
    */
   class ResourceStreamIterator {
   public:
     ResourceStreamIterator(PRInt64 aResourceID) :
@@ -345,17 +345,17 @@ protected:
   // resource IDs to streams.
   PRInt64                       mNextResourceID;
   // This member is main-thread only. It contains all the streams.
   nsTArray<nsMediaCacheStream*> mStreams;
 
   // The monitor protects all the data members here. Also, off-main-thread
   // readers that need to block will Wait() on this monitor. When new
   // data becomes available in the cache, we NotifyAll() on this monitor.
-  Monitor         mMonitor;
+  ReentrantMonitor         mReentrantMonitor;
   // The Blocks describing the cache entries.
   nsTArray<Block> mIndex;
   // The file descriptor of the cache file. The file will be deleted
   // by the operating system when this is closed.
   PRFileDesc*     mFD;
   // The current file offset in the cache file.
   PRInt64         mFDCurrentPos;
   // The list of free blocks; they are not ordered.
@@ -603,17 +603,17 @@ nsMediaCache::Flush()
     return;
 
   gMediaCache->FlushInternal();
 }
 
 void
 nsMediaCache::FlushInternal()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   for (PRUint32 blockIndex = 0; blockIndex < mIndex.Length(); ++blockIndex) {
     FreeBlock(blockIndex);
   }
 
   // Truncate file, close it, and reopen
   Truncate();
   NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
@@ -658,17 +658,17 @@ InitMediaCache()
     gMediaCache = nsnull;
   }
 }
 
 nsresult
 nsMediaCache::ReadCacheFile(PRInt64 aOffset, void* aData, PRInt32 aLength,
                             PRInt32* aBytes)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (!mFD)
     return NS_ERROR_FAILURE;
 
   if (mFDCurrentPos != aOffset) {
     PROffset64 offset = PR_Seek64(mFD, aOffset, PR_SEEK_SET);
     if (offset != aOffset)
       return NS_ERROR_FAILURE;
@@ -680,17 +680,17 @@ nsMediaCache::ReadCacheFile(PRInt64 aOff
   mFDCurrentPos += amount;
   *aBytes = amount;
   return NS_OK;
 }
 
 nsresult
 nsMediaCache::ReadCacheFileAllBytes(PRInt64 aOffset, void* aData, PRInt32 aLength)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRInt64 offset = aOffset;
   PRInt32 count = aLength;
   // Cast to char* so we can do byte-wise pointer arithmetic
   char* data = static_cast<char*>(aData);
   while (count > 0) {
     PRInt32 bytes;
     nsresult rv = ReadCacheFile(offset, data, count, &bytes);
@@ -703,17 +703,17 @@ nsMediaCache::ReadCacheFileAllBytes(PRIn
     offset += bytes;
   }
   return NS_OK;
 }
 
 nsresult
 nsMediaCache::WriteCacheFile(PRInt64 aOffset, const void* aData, PRInt32 aLength)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (!mFD)
     return NS_ERROR_FAILURE;
 
   if (mFDCurrentPos != aOffset) {
     PROffset64 offset = PR_Seek64(mFD, aOffset, PR_SEEK_SET);
     if (offset != aOffset)
       return NS_ERROR_FAILURE;
@@ -744,17 +744,17 @@ static PRInt32 GetMaxBlocks()
   maxBlocks = PR_MAX(maxBlocks, 1);
   return PRInt32(PR_MIN(maxBlocks, PR_INT32_MAX));
 }
 
 PRInt32
 nsMediaCache::FindBlockForIncomingData(TimeStamp aNow,
                                        nsMediaCacheStream* aStream)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRInt32 blockIndex = FindReusableBlock(aNow, aStream,
       aStream->mChannelOffset/BLOCK_SIZE, PR_INT32_MAX);
 
   if (blockIndex < 0 || !IsBlockFree(blockIndex)) {
     // The block returned is already allocated.
     // Don't reuse it if a) there's room to expand the cache or
     // b) the data we're going to store in the free block is not higher
@@ -787,17 +787,17 @@ nsMediaCache::BlockIsReusable(PRInt32 aB
   return PR_TRUE;
 }
 
 void
 nsMediaCache::AppendMostReusableBlock(BlockList* aBlockList,
                                       nsTArray<PRUint32>* aResult,
                                       PRInt32 aBlockIndexLimit)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRInt32 blockIndex = aBlockList->GetLastBlock();
   if (blockIndex < 0)
     return;
   do {
     // Don't consider blocks for pinned streams, or blocks that are
     // beyond the specified limit, or a block that contains a stream's
     // current read position (such a block contains both played data
@@ -811,17 +811,17 @@ nsMediaCache::AppendMostReusableBlock(Bl
 }
 
 PRInt32
 nsMediaCache::FindReusableBlock(TimeStamp aNow,
                                 nsMediaCacheStream* aForStream,
                                 PRInt32 aForStreamBlock,
                                 PRInt32 aMaxSearchBlockIndex)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRUint32 length = PR_MIN(PRUint32(aMaxSearchBlockIndex), mIndex.Length());
 
   if (aForStream && aForStreamBlock > 0 &&
       PRUint32(aForStreamBlock) <= aForStream->mBlocks.Length()) {
     PRInt32 prevCacheBlock = aForStream->mBlocks[aForStreamBlock - 1];
     if (prevCacheBlock >= 0) {
       PRUint32 freeBlockScanEnd =
@@ -905,17 +905,17 @@ nsMediaCache::GetBlockOwner(PRInt32 aBlo
       return &block->mOwners[i];
   }
   return nsnull;
 }
 
 void
 nsMediaCache::SwapBlocks(PRInt32 aBlockIndex1, PRInt32 aBlockIndex2)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   Block* block1 = &mIndex[aBlockIndex1];
   Block* block2 = &mIndex[aBlockIndex2];
 
   block1->mOwners.SwapElements(block2->mOwners);
 
   // Now all references to block1 have to be replaced with block2 and
   // vice versa.
@@ -985,17 +985,17 @@ nsMediaCache::AddBlockOwnerAsReadahead(P
   aStream->mBlocks[aStreamBlockIndex] = aBlockIndex;
   bo->mClass = READAHEAD_BLOCK;
   InsertReadaheadBlock(bo, aBlockIndex);
 }
 
 void
 nsMediaCache::FreeBlock(PRInt32 aBlock)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   Block* block = &mIndex[aBlock];
   if (block->mOwners.IsEmpty()) {
     // already free
     return;
   }
 
   LOG(PR_LOG_DEBUG, ("Released block %d", aBlock));
@@ -1008,17 +1008,17 @@ nsMediaCache::FreeBlock(PRInt32 aBlock)
   block->mOwners.Clear();
   mFreeBlocks.AddFirstBlock(aBlock);
   Verify();
 }
 
 TimeDuration
 nsMediaCache::PredictNextUse(TimeStamp aNow, PRInt32 aBlock)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
   NS_ASSERTION(!IsBlockFree(aBlock), "aBlock is free");
 
   Block* block = &mIndex[aBlock];
   // Blocks can be belong to multiple streams. The predicted next use
   // time is the earliest time predicted by any of the streams.
   TimeDuration result;
   for (PRUint32 i = 0; i < block->mOwners.Length(); ++i) {
     BlockOwner* bo = &block->mOwners[i];
@@ -1058,17 +1058,17 @@ nsMediaCache::PredictNextUse(TimeStamp a
     }
   }
   return result;
 }
 
 TimeDuration
 nsMediaCache::PredictNextUseForIncomingData(nsMediaCacheStream* aStream)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRInt64 bytesAhead = aStream->mChannelOffset - aStream->mStreamOffset;
   if (bytesAhead <= -BLOCK_SIZE) {
     // Hmm, no idea when data behind us will be used. Guess 24 hours.
     return TimeDuration::FromSeconds(24*60*60);
   }
   if (bytesAhead <= 0)
     return TimeDuration(0);
@@ -1086,17 +1086,17 @@ nsMediaCache::Update()
 
   // The action to use for each stream. We store these so we can make
   // decisions while holding the cache lock but implement those decisions
   // without holding the cache lock, since we need to call out to
   // stream, decoder and element code.
   nsAutoTArray<StreamAction,10> actions;
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mUpdateQueued = PR_FALSE;
 #ifdef DEBUG
     mInUpdate = PR_TRUE;
 #endif
 
     PRInt32 maxBlocks = GetMaxBlocks();
     TimeStamp now = TimeStamp::Now();
 
@@ -1368,17 +1368,17 @@ nsMediaCache::Update()
     default:
       break;
     }
 
     if (NS_FAILED(rv)) {
       // Close the streams that failed due to error. This will cause all
       // client Read and Seek operations on those streams to fail. Blocked
       // Reads will also be woken up.
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       stream->CloseInternal(mon);
     }
   }
 }
 
 class UpdateEvent : public nsRunnable
 {
 public:
@@ -1389,34 +1389,34 @@ public:
     }
     return NS_OK;
   }
 };
 
 void
 nsMediaCache::QueueUpdate()
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   // Queuing an update while we're in an update raises a high risk of
   // triggering endless events
   NS_ASSERTION(!mInUpdate,
                "Queuing an update while we're in an update");
   if (mUpdateQueued)
     return;
   mUpdateQueued = PR_TRUE;
   nsCOMPtr<nsIRunnable> event = new UpdateEvent();
   NS_DispatchToMainThread(event);
 }
 
 #ifdef DEBUG_VERIFY_CACHE
 void
 nsMediaCache::Verify()
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   mFreeBlocks.Verify();
   for (PRUint32 i = 0; i < mStreams.Length(); ++i) {
     nsMediaCacheStream* stream = mStreams[i];
     stream->mReadaheadBlocks.Verify();
     stream->mPlayedBlocks.Verify();
     stream->mMetadataBlocks.Verify();
 
@@ -1438,17 +1438,17 @@ nsMediaCache::Verify()
   }
 }
 #endif
 
 void
 nsMediaCache::InsertReadaheadBlock(BlockOwner* aBlockOwner,
                                    PRInt32 aBlockIndex)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   // Find the last block whose stream block is before aBlockIndex's
   // stream block, and insert after it
   nsMediaCacheStream* stream = aBlockOwner->mStream;
   PRInt32 readaheadIndex = stream->mReadaheadBlocks.GetLastBlock();
   while (readaheadIndex >= 0) {
     BlockOwner* bo = GetBlockOwner(readaheadIndex, stream);
     NS_ASSERTION(bo, "stream must own its blocks");
@@ -1464,17 +1464,17 @@ nsMediaCache::InsertReadaheadBlock(Block
   stream->mReadaheadBlocks.AddFirstBlock(aBlockIndex);
   Verify();
 }
 
 void
 nsMediaCache::AllocateAndWriteBlock(nsMediaCacheStream* aStream, const void* aData,
                                     nsMediaCacheStream::ReadMode aMode)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRInt32 streamBlockIndex = aStream->mChannelOffset/BLOCK_SIZE;
 
   // Remove all cached copies of this block
   ResourceStreamIterator iter(aStream->mResourceID);
   while (nsMediaCacheStream* stream = iter.Next()) {
     while (streamBlockIndex >= PRInt32(stream->mBlocks.Length())) {
       stream->mBlocks.AppendElement(-1);
@@ -1542,39 +1542,39 @@ nsMediaCache::AllocateAndWriteBlock(nsMe
   QueueUpdate();
 }
 
 void
 nsMediaCache::OpenStream(nsMediaCacheStream* aStream)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   LOG(PR_LOG_DEBUG, ("Stream %p opened", aStream));
   mStreams.AppendElement(aStream);
   aStream->mResourceID = mNextResourceID++;
 
   // Queue an update since a new stream has been opened.
   gMediaCache->QueueUpdate();
 }
 
 void
 nsMediaCache::ReleaseStream(nsMediaCacheStream* aStream)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   LOG(PR_LOG_DEBUG, ("Stream %p closed", aStream));
   mStreams.RemoveElement(aStream);
 }
 
 void
 nsMediaCache::ReleaseStreamBlocks(nsMediaCacheStream* aStream)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   // XXX scanning the entire stream doesn't seem great, if not much of it
   // is cached, but the only easy alternative is to scan the entire cache
   // which isn't better
   PRUint32 length = aStream->mBlocks.Length();
   for (PRUint32 i = 0; i < length; ++i) {
     PRInt32 blockIndex = aStream->mBlocks[i];
     if (blockIndex >= 0) {
@@ -1604,17 +1604,17 @@ nsMediaCache::Truncate()
   }
 }
 
 void
 nsMediaCache::NoteBlockUsage(nsMediaCacheStream* aStream, PRInt32 aBlockIndex,
                              nsMediaCacheStream::ReadMode aMode,
                              TimeStamp aNow)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (aBlockIndex < 0) {
     // this block is not in the cache yet
     return;
   }
 
   BlockOwner* bo = GetBlockOwner(aBlockIndex, aStream);
   if (!bo) {
@@ -1636,17 +1636,17 @@ nsMediaCache::NoteBlockUsage(nsMediaCach
   GetListForBlock(bo)->AddFirstBlock(aBlockIndex);
   bo->mLastUseTime = aNow;
   Verify();
 }
 
 void
 nsMediaCache::NoteSeek(nsMediaCacheStream* aStream, PRInt64 aOldOffset)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (aOldOffset < aStream->mStreamOffset) {
     // We seeked forward. Convert blocks from readahead to played.
     // Any readahead block that intersects the seeked-over range must
     // be converted.
     PRInt32 blockIndex = aOldOffset/BLOCK_SIZE;
     PRInt32 endIndex =
       PR_MIN((aStream->mStreamOffset + BLOCK_SIZE - 1)/BLOCK_SIZE,
@@ -1692,26 +1692,26 @@ nsMediaCache::NoteSeek(nsMediaCacheStrea
   }
 }
 
 void
 nsMediaCacheStream::NotifyDataLength(PRInt64 aLength)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   mStreamLength = aLength;
 }
 
 void
 nsMediaCacheStream::NotifyDataStarted(PRInt64 aOffset)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   NS_WARN_IF_FALSE(aOffset == mChannelOffset,
                    "Server is giving us unexpected offset");
   mChannelOffset = aOffset;
   if (mStreamLength >= 0) {
     // If we started reading at a certain offset, then for sure
     // the stream is at least that long.
     mStreamLength = PR_MAX(mStreamLength, mChannelOffset);
   }
@@ -1752,17 +1752,17 @@ nsMediaCacheStream::UpdatePrincipal(nsIP
 }
 
 void
 nsMediaCacheStream::NotifyDataReceived(PRInt64 aSize, const char* aData,
     nsIPrincipal* aPrincipal)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   PRInt64 size = aSize;
   const char* data = aData;
 
   LOG(PR_LOG_DEBUG, ("Stream %p DataReceived at %lld count=%lld",
       this, (long long)mChannelOffset, (long long)aSize));
 
   // We process the data one block (or part of a block) at a time
   while (size > 0) {
@@ -1821,17 +1821,17 @@ nsMediaCacheStream::NotifyDataReceived(P
   mon.NotifyAll();
 }
 
 void
 nsMediaCacheStream::NotifyDataEnded(nsresult aStatus)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
 
   PRInt32 blockOffset = PRInt32(mChannelOffset%BLOCK_SIZE);
   if (blockOffset > 0) {
     // Write back the partial block
     memset(reinterpret_cast<char*>(mPartialBlockBuffer) + blockOffset, 0,
            BLOCK_SIZE - blockOffset);
     gMediaCache->AllocateAndWriteBlock(this, mPartialBlockBuffer,
         mMetadataInPartialBlockBuffer ? MODE_METADATA : MODE_PLAYBACK);
@@ -1859,113 +1859,113 @@ nsMediaCacheStream::~nsMediaCacheStream(
     gMediaCache->ReleaseStream(this);
     nsMediaCache::MaybeShutdown();
   }
 }
 
 void
 nsMediaCacheStream::SetSeekable(PRBool aIsSeekable)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   NS_ASSERTION(mIsSeekable || aIsSeekable ||
                mChannelOffset == 0, "channel offset must be zero when we become non-seekable");
   mIsSeekable = aIsSeekable;
   // Queue an Update since we may change our strategy for dealing
   // with this stream
   gMediaCache->QueueUpdate();
 }
 
 PRBool
 nsMediaCacheStream::IsSeekable()
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return mIsSeekable;
 }
 
 void
 nsMediaCacheStream::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   CloseInternal(mon);
   // Queue an Update since we may have created more free space. Don't do
   // it from CloseInternal since that gets called by Update() itself
   // sometimes, and we try to not to queue updates from Update().
   gMediaCache->QueueUpdate();
 }
 
 void
-nsMediaCacheStream::CloseInternal(MonitorAutoEnter& aMonitor)
+nsMediaCacheStream::CloseInternal(ReentrantMonitorAutoEnter& aReentrantMonitor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   if (mClosed)
     return;
   mClosed = PR_TRUE;
   gMediaCache->ReleaseStreamBlocks(this);
   // Wake up any blocked readers
-  aMonitor.NotifyAll();
+  aReentrantMonitor.NotifyAll();
 }
 
 void
 nsMediaCacheStream::Pin()
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   ++mPinCount;
   // Queue an Update since we may no longer want to read more into the
   // cache, if this stream's block have become non-evictable
   gMediaCache->QueueUpdate();
 }
 
 void
 nsMediaCacheStream::Unpin()
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   NS_ASSERTION(mPinCount > 0, "Unbalanced Unpin");
   --mPinCount;
   // Queue an Update since we may be able to read more into the
   // cache, if this stream's block have become evictable
   gMediaCache->QueueUpdate();
 }
 
 PRInt64
 nsMediaCacheStream::GetLength()
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return mStreamLength;
 }
 
 PRInt64
 nsMediaCacheStream::GetNextCachedData(PRInt64 aOffset)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return GetNextCachedDataInternal(aOffset);
 }
 
 PRInt64
 nsMediaCacheStream::GetCachedDataEnd(PRInt64 aOffset)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return GetCachedDataEndInternal(aOffset);
 }
 
 PRBool
 nsMediaCacheStream::IsDataCachedToEndOfStream(PRInt64 aOffset)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (mStreamLength < 0)
     return PR_FALSE;
   return GetCachedDataEndInternal(aOffset) >= mStreamLength;
 }
 
 PRInt64
 nsMediaCacheStream::GetCachedDataEndInternal(PRInt64 aOffset)
 {
-  gMediaCache->GetMonitor().AssertCurrentThreadIn();
+  gMediaCache->GetReentrantMonitor().AssertCurrentThreadIn();
   PRUint32 startBlockIndex = aOffset/BLOCK_SIZE;
   PRUint32 blockIndex = startBlockIndex;
   while (blockIndex < mBlocks.Length() && mBlocks[blockIndex] != -1) {
     ++blockIndex;
   }
   PRInt64 result = blockIndex*BLOCK_SIZE;
   if (blockIndex == mChannelOffset/BLOCK_SIZE) {
     // The block containing mChannelOffset may be partially read but not
@@ -1978,17 +1978,17 @@ nsMediaCacheStream::GetCachedDataEndInte
     result = PR_MIN(result, mStreamLength);
   }
   return PR_MAX(result, aOffset);
 }
 
 PRInt64
 nsMediaCacheStream::GetNextCachedDataInternal(PRInt64 aOffset)
 {
-  gMediaCache->GetMonitor().AssertCurrentThreadIn();
+  gMediaCache->GetReentrantMonitor().AssertCurrentThreadIn();
   if (aOffset == mStreamLength)
     return -1;
 
   PRUint32 startBlockIndex = aOffset/BLOCK_SIZE;
   PRUint32 channelBlockIndex = mChannelOffset/BLOCK_SIZE;
 
   if (startBlockIndex == channelBlockIndex &&
       aOffset < mChannelOffset) {
@@ -2025,40 +2025,40 @@ nsMediaCacheStream::GetNextCachedDataInt
 
   NS_NOTREACHED("Should return in loop");
   return -1;
 }
 
 void
 nsMediaCacheStream::SetReadMode(ReadMode aMode)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (aMode == mCurrentMode)
     return;
   mCurrentMode = aMode;
   gMediaCache->QueueUpdate();
 }
 
 void
 nsMediaCacheStream::SetPlaybackRate(PRUint32 aBytesPerSecond)
 {
   NS_ASSERTION(aBytesPerSecond > 0, "Zero playback rate not allowed");
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (aBytesPerSecond == mPlaybackBytesPerSecond)
     return;
   mPlaybackBytesPerSecond = aBytesPerSecond;
   gMediaCache->QueueUpdate();
 }
 
 nsresult
 nsMediaCacheStream::Seek(PRInt32 aWhence, PRInt64 aOffset)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (mClosed)
     return NS_ERROR_FAILURE;
 
   PRInt64 oldOffset = mStreamOffset;
   switch (aWhence) {
   case PR_SEEK_END:
     if (mStreamLength < 0)
       return NS_ERROR_FAILURE;
@@ -2082,26 +2082,26 @@ nsMediaCacheStream::Seek(PRInt32 aWhence
   return NS_OK;
 }
 
 PRInt64
 nsMediaCacheStream::Tell()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return mStreamOffset;
 }
 
 nsresult
 nsMediaCacheStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (mClosed)
     return NS_ERROR_FAILURE;
 
   PRUint32 count = 0;
   // Read one block (or part of a block) at a time
   while (count < aCount) {
     PRUint32 streamBlock = PRUint32(mStreamOffset/BLOCK_SIZE);
     PRUint32 offsetInStreamBlock =
@@ -2176,17 +2176,17 @@ nsMediaCacheStream::Read(char* aBuffer, 
   return NS_OK;
 }
 
 nsresult
 nsMediaCacheStream::ReadFromCache(char* aBuffer,
                                   PRInt64 aOffset,
                                   PRInt64 aCount)
 {
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   if (mClosed)
     return NS_ERROR_FAILURE;
 
   // Read one block (or part of a block) at a time
   PRUint32 count = 0;
   PRInt64 streamOffset = aOffset;
   while (count < aCount) {
     PRUint32 streamBlock = PRUint32(streamOffset/BLOCK_SIZE);
@@ -2254,17 +2254,17 @@ nsMediaCacheStream::InitAsClone(nsMediaC
     return NS_OK;
 
   nsresult rv = Init();
   if (NS_FAILED(rv))
     return rv;
   mResourceID = aOriginal->mResourceID;
 
   // Grab cache blocks from aOriginal as readahead blocks for our stream
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
 
   mPrincipal = aOriginal->mPrincipal;
   mStreamLength = aOriginal->mStreamLength;
   mIsSeekable = aOriginal->mIsSeekable;
 
   // Cloned streams are initially suspended, since there is no channel open
   // initially for a clone.
   mCacheSuspended = PR_TRUE;
@@ -2284,17 +2284,17 @@ nsMediaCacheStream::InitAsClone(nsMediaC
 
   return NS_OK;
 }
 
 nsresult nsMediaCacheStream::GetCachedRanges(nsTArray<nsByteRange>& aRanges)
 {
   // Take the monitor, so that the cached data ranges can't grow while we're
   // trying to loop over them.
-  MonitorAutoEnter mon(gMediaCache->GetMonitor());
+  ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
 
   // We must be pinned while running this, otherwise the cached data ranges may
   // shrink while we're trying to loop over them.
   NS_ASSERTION(mPinCount > 0, "Must be pinned");
 
   PRInt64 startOffset = GetNextCachedData(0);
   while (startOffset >= 0) {
     PRInt64 endOffset = GetCachedDataEnd(startOffset);
--- a/content/media/nsMediaCache.h
+++ b/content/media/nsMediaCache.h
@@ -40,17 +40,17 @@
 #define nsMediaCache_h_
 
 #include "nsTArray.h"
 #include "nsIPrincipal.h"
 #include "nsCOMPtr.h"
 
 class nsByteRange;
 namespace mozilla {
-class MonitorAutoEnter;
+class ReentrantMonitorAutoEnter;
 }
 
 /**
  * Media applications want fast, "on demand" random access to media data,
  * for pausing, seeking, etc. But we are primarily interested
  * in transporting media data using HTTP over the Internet, which has
  * high latency to open a connection, requires a new connection for every
  * seek, may not even support seeking on some connections (especially
@@ -206,17 +206,17 @@ class nsMediaChannelStream;
 
 /**
  * If the cache fails to initialize then Init will fail, so nonstatic
  * methods of this class can assume gMediaCache is non-null.
  * 
  * This class can be directly embedded as a value.
  */
 class nsMediaCacheStream {
-  typedef mozilla::MonitorAutoEnter MonitorAutoEnter;
+  typedef mozilla::ReentrantMonitorAutoEnter ReentrantMonitorAutoEnter;
 
 public:
   enum {
     // This needs to be a power of two
     BLOCK_SIZE = 32768
   };
   enum ReadMode {
     MODE_METADATA,
@@ -425,20 +425,20 @@ private:
   PRInt64 GetCachedDataEndInternal(PRInt64 aOffset);
   // Returns the offset of the first byte of cached data at or after aOffset,
   // or -1 if there is no such cached data.
   // This method assumes that the cache monitor is held and can be called on
   // any thread.
   PRInt64 GetNextCachedDataInternal(PRInt64 aOffset);
   // A helper function to do the work of closing the stream. Assumes
   // that the cache monitor is held. Main thread only.
-  // aMonitor is the nsAutoMonitor wrapper holding the cache monitor.
+  // aReentrantMonitor is the nsAutoReentrantMonitor wrapper holding the cache monitor.
   // This is used to NotifyAll to wake up threads that might be
   // blocked on reading from this stream.
-  void CloseInternal(MonitorAutoEnter& aMonitor);
+  void CloseInternal(ReentrantMonitorAutoEnter& aReentrantMonitor);
   // Update mPrincipal given that data has been received from aPrincipal
   void UpdatePrincipal(nsIPrincipal* aPrincipal);
 
   // These fields are main-thread-only.
   nsMediaChannelStream*  mClient;
   nsCOMPtr<nsIPrincipal> mPrincipal;
   // This is a unique ID representing the resource we're loading.
   // All streams with the same mResourceID are loading the same
--- a/content/media/nsMediaDecoder.h
+++ b/content/media/nsMediaDecoder.h
@@ -42,17 +42,17 @@
 
 #include "nsIPrincipal.h"
 #include "nsSize.h"
 #include "prlog.h"
 #include "gfxContext.h"
 #include "gfxRect.h"
 #include "nsITimer.h"
 #include "ImageLayers.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 
 class nsHTMLMediaElement;
 class nsMediaStream;
 class nsIStreamListener;
 class nsTimeRanges;
 
 // The size to use for audio data frames in MozAudioAvailable events.
@@ -84,17 +84,17 @@ private:
 // which can be called from any thread.
 class nsMediaDecoder : public nsIObserver
 {
 public:
   typedef mozilla::TimeStamp TimeStamp;
   typedef mozilla::TimeDuration TimeDuration;
   typedef mozilla::layers::ImageContainer ImageContainer;
   typedef mozilla::layers::Image Image;
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
   typedef mozilla::Mutex Mutex;
 
   nsMediaDecoder();
   virtual ~nsMediaDecoder();
 
   // Create a new decoder of the same type as this one.
   virtual nsMediaDecoder* Clone() = 0;
 
@@ -185,75 +185,75 @@ public:
   };
 
   // Frame decoding/painting related performance counters.
   // Threadsafe.
   class FrameStatistics {
   public:
     
     FrameStatistics() :
-        mMonitor("nsMediaDecoder::FrameStats"),
+        mReentrantMonitor("nsMediaDecoder::FrameStats"),
         mParsedFrames(0),
         mDecodedFrames(0),
         mPresentedFrames(0) {}
 
     // Returns number of frames which have been parsed from the media.
     // Can be called on any thread.
     PRUint32 GetParsedFrames() {
-      mozilla::MonitorAutoEnter mon(mMonitor);
+      mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       return mParsedFrames;
     }
 
     // Returns the number of parsed frames which have been decoded.
     // Can be called on any thread.
     PRUint32 GetDecodedFrames() {
-      mozilla::MonitorAutoEnter mon(mMonitor);
+      mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       return mDecodedFrames;
     }
 
     // Returns the number of decoded frames which have been sent to the rendering
     // pipeline for painting ("presented").
     // Can be called on any thread.
     PRUint32 GetPresentedFrames() {
-      mozilla::MonitorAutoEnter mon(mMonitor);
+      mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       return mPresentedFrames;
     }
 
     // Increments the parsed and decoded frame counters by the passed in counts.
     // Can be called on any thread.
     void NotifyDecodedFrames(PRUint32 aParsed, PRUint32 aDecoded) {
       if (aParsed == 0 && aDecoded == 0)
         return;
-      mozilla::MonitorAutoEnter mon(mMonitor);
+      mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       mParsedFrames += aParsed;
       mDecodedFrames += aDecoded;
     }
 
     // Increments the presented frame counters.
     // Can be called on any thread.
     void NotifyPresentedFrame() {
-      mozilla::MonitorAutoEnter mon(mMonitor);
+      mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       ++mPresentedFrames;
     }
 
   private:
 
-    // Monitor to protect access of playback statistics.
-    Monitor mMonitor;
+    // ReentrantMonitor to protect access of playback statistics.
+    ReentrantMonitor mReentrantMonitor;
 
     // Number of frames parsed and demuxed from media.
-    // Access protected by mStatsMonitor.
+    // Access protected by mStatsReentrantMonitor.
     PRUint32 mParsedFrames;
 
     // Number of parsed frames which were actually decoded.
-    // Access protected by mStatsMonitor.
+    // Access protected by mStatsReentrantMonitor.
     PRUint32 mDecodedFrames;
 
     // Number of decoded frames which were actually sent down the rendering
-    // pipeline to be painted ("presented"). Access protected by mStatsMonitor.
+    // pipeline to be painted ("presented"). Access protected by mStatsReentrantMonitor.
     PRUint32 mPresentedFrames;
   };
 
   // Stack based class to assist in notifying the frame statistics of
   // parsed and decoded frames. Use inside video demux & decode functions
   // to ensure all parsed and decoded frames are reported on all return paths.
   class AutoNotifyDecoded {
   public:
--- a/content/media/ogg/nsOggReader.cpp
+++ b/content/media/ogg/nsOggReader.cpp
@@ -139,17 +139,17 @@ nsresult nsOggReader::ResetDecode()
   mTheoraGranulepos = -1;
   mVorbisGranulepos = -1;
 
   if (NS_FAILED(nsBuiltinDecoderReader::ResetDecode())) {
     res = NS_ERROR_FAILURE;
   }
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // Discard any previously buffered packets/pages.
     ogg_sync_reset(&mOggState);
     if (mVorbisState && NS_FAILED(mVorbisState->Reset())) {
       res = NS_ERROR_FAILURE;
     }
     if (mTheoraState && NS_FAILED(mTheoraState->Reset())) {
       res = NS_ERROR_FAILURE;
@@ -168,17 +168,17 @@ static PRBool DoneReadingHeaders(nsTArra
     }
   }
   return PR_TRUE;
 }
 
 nsresult nsOggReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on play state machine thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   // We read packets until all bitstreams have read all their header packets.
   // We record the offset of the first non-header page so that we know
   // what page to seek to when seeking to the media start.
 
   ogg_page page;
   PRInt64 pageOffset;
   nsAutoTArray<nsOggCodecState*,4> bitstreams;
@@ -333,18 +333,18 @@ nsresult nsOggReader::ReadMetadata(nsVid
     if (HasVideo()) {
       tracks.AppendElement(mTheoraState->mSerial);
     }
     if (HasAudio()) {
       tracks.AppendElement(mVorbisState->mSerial);
     }
     PRInt64 duration = 0;
     if (NS_SUCCEEDED(mSkeletonState->GetDuration(tracks, duration))) {
-      MonitorAutoExit exitReaderMon(mMonitor);
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       mDecoder->GetStateMachine()->SetDuration(duration);
       LOG(PR_LOG_DEBUG, ("Got duration from Skeleton index %lld", duration));
     }
   }
 
   // Copy Vorbis and Theora info data for time computations on other threads.
   if (mVorbisState) {
     memcpy(&mVorbisInfo, &mVorbisState->mInfo, sizeof(mVorbisInfo));
@@ -407,17 +407,17 @@ nsresult nsOggReader::DecodeVorbis(nsTAr
       return NS_ERROR_FAILURE;
     }
   }
   return NS_OK;
 }
 
 PRBool nsOggReader::DecodeAudioData()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on playback or decode thread.");
   NS_ASSERTION(mVorbisState!=0, "Need Vorbis state to decode audio");
   ogg_packet packet;
   packet.granulepos = -1;
 
   PRBool endOfStream = PR_FALSE;
 
@@ -563,17 +563,17 @@ nsresult nsOggReader::DecodeTheora(nsTAr
       b.mPlanes[i].mData = buffer[i].data;
       b.mPlanes[i].mHeight = buffer[i].height;
       b.mPlanes[i].mWidth = buffer[i].width;
       b.mPlanes[i].mStride = buffer[i].stride;
     }
 
     // Need the monitor to be held to be able to use mInfo. This
     // is held by our caller.
-    mMonitor.AssertCurrentThreadIn();
+    mReentrantMonitor.AssertCurrentThreadIn();
     VideoData *v = VideoData::Create(mInfo,
                                      mDecoder->GetImageContainer(),
                                      mPageOffset,
                                      time,
                                      endTime,
                                      b,
                                      isKeyframe,
                                      aPacket->granulepos);
@@ -588,17 +588,17 @@ nsresult nsOggReader::DecodeTheora(nsTAr
     }
   }
   return NS_OK;
 }
 
 PRBool nsOggReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                      PRInt64 aTimeThreshold)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or AV thread.");
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   PRUint32 parsed = 0, decoded = 0;
   nsMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
 
@@ -796,17 +796,17 @@ PRBool nsOggReader::DecodeVideoFrame(PRB
 
   return !endOfStream;
 }
 
 PRInt64 nsOggReader::ReadOggPage(ogg_page* aPage)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on play state machine or decode thread.");
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   int ret = 0;
   while((ret = ogg_sync_pageseek(&mOggState, aPage)) <= 0) {
     if (ret < 0) {
       // Lost page sync, have to skip up to next page.
       mPageOffset += -ret;
       continue;
     }
@@ -837,17 +837,17 @@ PRInt64 nsOggReader::ReadOggPage(ogg_pag
   return offset;
 }
 
 PRBool nsOggReader::ReadOggPacket(nsOggCodecState* aCodecState,
                                   ogg_packet* aPacket)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on play state machine or decode thread.");
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   if (!aCodecState || !aCodecState->mActive) {
     return PR_FALSE;
   }
 
   int ret = 0;
   while ((ret = ogg_stream_packetout(&aCodecState->mState, aPacket)) != 1) {
     ogg_page page;
@@ -912,17 +912,17 @@ VideoData* nsOggReader::FindStartTime(PR
   PRInt64 offset = NS_MAX(mDataOffset, aOffset);
   nsresult res = stream->Seek(nsISeekableStream::NS_SEEK_SET, offset);
   NS_ENSURE_SUCCESS(res, nsnull);
   return nsBuiltinDecoderReader::FindStartTime(offset, aOutStartTime);
 }
 
 PRInt64 nsOggReader::FindEndTime(PRInt64 aEndOffset)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
   NS_ASSERTION(mDataOffset > 0,
                "Should have offset of first non-header page");
   PRInt64 offset = NS_MAX(mDataOffset, aEndOffset);
   PRInt64 endTime = FindEndTime(mDataOffset, offset, PR_FALSE, &mOggState);
   // Reset read head to start of media data.
   nsMediaStream* stream = mDecoder->GetCurrentStream();
@@ -1051,17 +1051,17 @@ PRInt64 nsOggReader::FindEndTime(PRInt64
 
   return endTime;
 }
 
 nsresult nsOggReader::GetSeekRanges(nsTArray<SeekRange>& aRanges)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
   nsTArray<nsByteRange> cached;
   nsresult res = mDecoder->GetCurrentStream()->GetCachedRanges(cached);
   NS_ENSURE_SUCCESS(res, res);
 
   for (PRUint32 index = 0; index < cached.Length(); index++) {
     nsByteRange& range = cached[index];
     PRInt64 startTime = -1;
     PRInt64 endTime = -1;
@@ -1231,18 +1231,18 @@ nsresult nsOggReader::SeekInBufferedRang
 
   // We have an active Theora bitstream. Decode the next Theora frame, and
   // extract its keyframe's time.
   PRBool eof;
   do {
     PRBool skip = PR_FALSE;
     eof = !DecodeVideoFrame(skip, 0);
     {
-      MonitorAutoExit exitReaderMon(mMonitor);
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       if (mDecoder->GetDecodeState() == nsBuiltinDecoderStateMachine::DECODER_STATE_SHUTDOWN) {
         return NS_ERROR_FAILURE;
       }
     }
   } while (!eof &&
            mVideoQueue.GetSize() == 0);
 
   VideoData* video = mVideoQueue.PeekFront();
@@ -1311,17 +1311,17 @@ nsresult nsOggReader::SeekInUnbuffered(P
   return res;
 }
 
 nsresult nsOggReader::Seek(PRInt64 aTarget,
                            PRInt64 aStartTime,
                            PRInt64 aEndTime,
                            PRInt64 aCurrentTime)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
   nsresult res;
   nsMediaStream* stream = mDecoder->GetCurrentStream();
   NS_ENSURE_TRUE(stream != nsnull, NS_ERROR_FAILURE);
 
   if (aTarget == aStartTime) {
@@ -1331,18 +1331,18 @@ nsresult nsOggReader::Seek(PRInt64 aTarg
     NS_ENSURE_SUCCESS(res,res);
 
     mPageOffset = mDataOffset;
     res = ResetDecode();
     NS_ENSURE_SUCCESS(res,res);
 
     NS_ASSERTION(aStartTime != -1, "mStartTime should be known");
     {
-      MonitorAutoExit exitReaderMon(mMonitor);
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       mDecoder->UpdatePlaybackPosition(aStartTime);
     }
   } else if (CanDecodeToTarget(aTarget, aCurrentTime)) {
     LOG(PR_LOG_DEBUG, ("%p Seek target (%lld) is close to current time (%lld), "
         "will just decode to it", mDecoder, aCurrentTime, aTarget));
   } else {
     IndexedSeekResult sres = SeekToKeyframeUsingIndex(aTarget);
     NS_ENSURE_TRUE(sres != SEEK_FATAL_ERROR, NS_ERROR_FAILURE);
--- a/content/media/ogg/nsOggReader.h
+++ b/content/media/ogg/nsOggReader.h
@@ -75,35 +75,35 @@ public:
                                    PRInt64& aOutStartTime);
 
   // Get the end time of aEndOffset. This is the playback position we'd reach
   // after playback finished at aEndOffset.
   virtual PRInt64 FindEndTime(PRInt64 aEndOffset);
 
   virtual PRBool HasAudio()
   {
-    mozilla::MonitorAutoEnter mon(mMonitor);
+    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mVorbisState != 0 && mVorbisState->mActive;
   }
 
   virtual PRBool HasVideo()
   {
-    mozilla::MonitorAutoEnter mon(mMonitor);
+    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mTheoraState != 0 && mTheoraState->mActive;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
 
 private:
 
   PRBool HasSkeleton()
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mSkeletonState != 0 && mSkeletonState->mActive;
   }
 
   // Returns PR_TRUE if we should decode up to the seek target rather than
   // seeking to the target using a bisection search or index-assisted seek.
   // We should do this if the seek target (aTarget, in usecs), lies not too far
   // ahead of the current playback position (aCurrentTime, in usecs).
   PRBool CanDecodeToTarget(PRInt64 aTarget,
--- a/content/media/wave/nsWaveReader.cpp
+++ b/content/media/wave/nsWaveReader.cpp
@@ -148,42 +148,42 @@ nsWaveReader::~nsWaveReader()
 nsresult nsWaveReader::Init(nsBuiltinDecoderReader* aCloneDonor)
 {
   return NS_OK;
 }
 
 nsresult nsWaveReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on state machine thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   PRBool loaded = LoadRIFFChunk() && LoadFormatChunk() && FindDataOffset();
   if (!loaded) {
     return NS_ERROR_FAILURE;
   }
 
   mInfo.mHasAudio = PR_TRUE;
   mInfo.mHasVideo = PR_FALSE;
   mInfo.mAudioRate = mSampleRate;
   mInfo.mAudioChannels = mChannels;
 
   *aInfo = mInfo;
 
-  MonitorAutoExit exitReaderMon(mMonitor);
-  MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+  ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+  ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
 
   mDecoder->GetStateMachine()->SetDuration(
     static_cast<PRInt64>(BytesToTime(GetDataLength()) * USECS_PER_S));
 
   return NS_OK;
 }
 
 PRBool nsWaveReader::DecodeAudioData()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine thread or decode thread.");
 
   PRInt64 pos = GetPosition() - mWavePCMOffset;
   PRInt64 len = GetDataLength();
   PRInt64 remaining = len - pos;
   NS_ASSERTION(remaining >= 0, "Current wave position is greater than wave file length");
 
@@ -241,26 +241,26 @@ PRBool nsWaveReader::DecodeAudioData()
                                  mChannels));
 
   return PR_TRUE;
 }
 
 PRBool nsWaveReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                       PRInt64 aTimeThreshold)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   return PR_FALSE;
 }
 
 nsresult nsWaveReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lld", mDecoder, aTarget));
   if (NS_FAILED(ResetDecode())) {
     return NS_ERROR_FAILURE;
   }
   double d = BytesToTime(GetDataLength());
   NS_ASSERTION(d < PR_INT64_MAX / USECS_PER_S, "Duration overflow"); 
@@ -472,17 +472,17 @@ nsWaveReader::LoadFormatChunk()
   if (rate < 100 || rate > 96000 ||
       channels < 1 || channels > MAX_CHANNELS ||
       (sampleSize != 1 && sampleSize != 2 && sampleSize != 4) ||
       (sampleFormat != 8 && sampleFormat != 16)) {
     NS_WARNING("Invalid WAVE metadata");
     return PR_FALSE;
   }
 
-  MonitorAutoEnter monitor(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter monitor(mDecoder->GetReentrantMonitor());
   mSampleRate = rate;
   mChannels = channels;
   mSampleSize = sampleSize;
   if (sampleFormat == 8) {
     mSampleFormat = nsAudioStream::FORMAT_U8;
   } else {
     mSampleFormat = nsAudioStream::FORMAT_S16_LE;
   }
@@ -504,17 +504,17 @@ nsWaveReader::FindDataOffset()
   }
 
   PRInt64 offset = mDecoder->GetCurrentStream()->Tell();
   if (offset <= 0 || offset > PR_UINT32_MAX) {
     NS_WARNING("PCM data offset out of range");
     return PR_FALSE;
   }
 
-  MonitorAutoEnter monitor(mDecoder->GetMonitor());
+  ReentrantMonitorAutoEnter monitor(mDecoder->GetReentrantMonitor());
   mWaveLength = length;
   mWavePCMOffset = PRUint32(offset);
   return PR_TRUE;
 }
 
 double
 nsWaveReader::BytesToTime(PRInt64 aBytes) const
 {
--- a/content/media/webm/nsWebMBufferedParser.cpp
+++ b/content/media/webm/nsWebMBufferedParser.cpp
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsAlgorithm.h"
 #include "nsWebMBufferedParser.h"
 #include "nsTimeRanges.h"
 #include "nsThreadUtils.h"
 
-using mozilla::MonitorAutoEnter;
+using mozilla::ReentrantMonitorAutoEnter;
 
 static const double NS_PER_S = 1e9;
 
 static PRUint32
 VIntLength(unsigned char aFirstByte, PRUint32* aMask)
 {
   PRUint32 count = 1;
   PRUint32 mask = 1 << 7;
@@ -61,17 +61,17 @@ VIntLength(unsigned char aFirstByte, PRU
     *aMask = mask;
   }
   NS_ASSERTION(count >= 1 && count <= 8, "Insane VInt length.");
   return count;
 }
 
 void nsWebMBufferedParser::Append(const unsigned char* aBuffer, PRUint32 aLength,
                                   nsTArray<nsWebMTimeDataOffset>& aMapping,
-                                  Monitor& aMonitor)
+                                  ReentrantMonitor& aReentrantMonitor)
 {
   static const unsigned char CLUSTER_ID[] = { 0x1f, 0x43, 0xb6, 0x75 };
   static const unsigned char TIMECODE_ID = 0xe7;
   static const unsigned char BLOCKGROUP_ID = 0xa0;
   static const unsigned char BLOCK_ID = 0xa1;
   static const unsigned char SIMPLEBLOCK_ID = 0xa3;
 
   const unsigned char* p = aBuffer;
@@ -166,17 +166,17 @@ void nsWebMBufferedParser::Append(const 
       if (mBlockTimecodeLength) {
         mBlockTimecode <<= 8;
         mBlockTimecode |= *p++;
         mBlockTimecodeLength -= 1;
       } else {
         // It's possible we've parsed this data before, so avoid inserting
         // duplicate nsWebMTimeDataOffset entries.
         {
-          MonitorAutoEnter mon(aMonitor);
+          ReentrantMonitorAutoEnter mon(aReentrantMonitor);
           PRUint32 idx;
           if (!aMapping.GreatestIndexLtEq(mBlockOffset, idx)) {
             nsWebMTimeDataOffset entry(mBlockOffset, mClusterTimecode + mBlockTimecode);
             aMapping.InsertElementAt(idx, entry);
           }
         }
 
         // Skip rest of block header and the block's payload.
@@ -209,17 +209,17 @@ void nsWebMBufferedParser::Append(const 
   mCurrentOffset += aLength;
 }
 
 void nsWebMBufferedState::CalculateBufferedForRange(nsTimeRanges* aBuffered,
                                                     PRInt64 aStartOffset, PRInt64 aEndOffset,
                                                     PRUint64 aTimecodeScale,
                                                     PRInt64 aStartTimeOffsetNS)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   // Find the first nsWebMTimeDataOffset at or after aStartOffset.
   PRUint32 start;
   mTimeMapping.GreatestIndexLtEq(aStartOffset, start);
   if (start == mTimeMapping.Length()) {
     return;
   }
 
@@ -281,17 +281,17 @@ void nsWebMBufferedState::NotifyDataArri
     } else {
       mRangeParsers.InsertElementAt(idx, nsWebMBufferedParser(aOffset));
     }
   }
 
   mRangeParsers[idx].Append(reinterpret_cast<const unsigned char*>(aBuffer),
                             aLength,
                             mTimeMapping,
-                            mMonitor);
+                            mReentrantMonitor);
 
   // Merge parsers with overlapping regions and clean up the remnants.
   PRUint32 i = 0;
   while (i + 1 < mRangeParsers.Length()) {
     if (mRangeParsers[i].mCurrentOffset >= mRangeParsers[i + 1].mStartOffset) {
       mRangeParsers[i + 1].mStartOffset = mRangeParsers[i].mStartOffset;
       mRangeParsers.RemoveElementAt(i);
     } else {
--- a/content/media/webm/nsWebMBufferedParser.h
+++ b/content/media/webm/nsWebMBufferedParser.h
@@ -35,20 +35,20 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 #if !defined(nsWebMBufferedParser_h_)
 #define nsWebMBufferedParser_h_
 
 #include "nsISupportsImpl.h"
 #include "nsTArray.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 class nsTimeRanges;
-using mozilla::Monitor;
+using mozilla::ReentrantMonitor;
 
 // Stores a stream byte offset and the scaled timecode of the block at
 // that offset.  The timecode must be scaled by the stream's timecode
 // scale before use.
 struct nsWebMTimeDataOffset
 {
   nsWebMTimeDataOffset(PRInt64 aOffset, PRUint64 aTimecode)
     : mOffset(aOffset), mTimecode(aTimecode)
@@ -75,20 +75,20 @@ struct nsWebMTimeDataOffset
 struct nsWebMBufferedParser
 {
   nsWebMBufferedParser(PRInt64 aOffset)
     : mStartOffset(aOffset), mCurrentOffset(aOffset), mState(CLUSTER_SYNC), mClusterIDPos(0)
   {}
 
   // Steps the parser through aLength bytes of data.  Always consumes
   // aLength bytes.  Updates mCurrentOffset before returning.  Acquires
-  // aMonitor before using aMapping.
+  // aReentrantMonitor before using aMapping.
   void Append(const unsigned char* aBuffer, PRUint32 aLength,
               nsTArray<nsWebMTimeDataOffset>& aMapping,
-              Monitor& aMonitor);
+              ReentrantMonitor& aReentrantMonitor);
 
   bool operator==(PRInt64 aOffset) const {
     return mCurrentOffset == aOffset;
   }
 
   bool operator<(PRInt64 aOffset) const {
     return mCurrentOffset < aOffset;
   }
@@ -211,33 +211,33 @@ private:
   PRUint32 mSkipBytes;
 };
 
 class nsWebMBufferedState
 {
   NS_INLINE_DECL_REFCOUNTING(nsWebMBufferedState)
 
 public:
-  nsWebMBufferedState() : mMonitor("nsWebMBufferedState") {
+  nsWebMBufferedState() : mReentrantMonitor("nsWebMBufferedState") {
     MOZ_COUNT_CTOR(nsWebMBufferedState);
   }
 
   ~nsWebMBufferedState() {
     MOZ_COUNT_DTOR(nsWebMBufferedState);
   }
 
   void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset);
   void CalculateBufferedForRange(nsTimeRanges* aBuffered,
                                  PRInt64 aStartOffset, PRInt64 aEndOffset,
                                  PRUint64 aTimecodeScale,
                                  PRInt64 aStartTimeOffsetNS);
 
 private:
   // Synchronizes access to the mTimeMapping array.
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 
   // Sorted (by offset) map of data offsets to timecodes.  Populated
   // on the main thread as data is received and parsed by nsWebMBufferedParsers.
   nsTArray<nsWebMTimeDataOffset> mTimeMapping;
 
   // Sorted (by offset) live parser instances.  Main thread only.
   nsTArray<nsWebMBufferedParser> mRangeParsers;
 };
--- a/content/media/webm/nsWebMReader.cpp
+++ b/content/media/webm/nsWebMReader.cpp
@@ -206,33 +206,33 @@ void nsWebMReader::Cleanup()
     nestegg_destroy(mContext);
     mContext = nsnull;
   }
 }
 
 nsresult nsWebMReader::ReadMetadata(nsVideoInfo* aInfo)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread(), "Should be on state machine thread.");
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nestegg_io io;
   io.read = webm_read;
   io.seek = webm_seek;
   io.tell = webm_tell;
   io.userdata = static_cast<nsBuiltinDecoder*>(mDecoder);
   int r = nestegg_init(&mContext, io, NULL);
   if (r == -1) {
     return NS_ERROR_FAILURE;
   }
 
   uint64_t duration = 0;
   r = nestegg_duration(mContext, &duration);
   if (r == 0) {
-    MonitorAutoExit exitReaderMon(mMonitor);
-    MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+    ReentrantMonitorAutoExit exitReaderMon(mReentrantMonitor);
+    ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
     mDecoder->GetStateMachine()->SetDuration(duration / NS_PER_USEC);
   }
 
   unsigned int ntracks = 0;
   r = nestegg_track_count(mContext, &ntracks);
   if (r == -1) {
     Cleanup();
     return NS_ERROR_FAILURE;
@@ -408,17 +408,17 @@ ogg_packet nsWebMReader::InitOggPacket(u
   packet.e_o_s = aEOS;
   packet.granulepos = aGranulepos;
   packet.packetno = mPacketCount++;
   return packet;
 }
  
 PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket, PRInt64 aOffset)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   int r = 0;
   unsigned int count = 0;
   r = nestegg_packet_count(aPacket, &count);
   if (r == -1) {
     return PR_FALSE;
   }
 
@@ -586,32 +586,32 @@ nsReturnRef<NesteggPacketHolder> nsWebMR
     } while (PR_TRUE);
   }
 
   return holder.out();
 }
 
 PRBool nsWebMReader::DecodeAudioData()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
     "Should be on state machine thread or decode thread.");
   nsAutoRef<NesteggPacketHolder> holder(NextPacket(AUDIO));
   if (!holder) {
     mAudioQueue.Finish();
     return PR_FALSE;
   }
 
   return DecodeAudioPacket(holder->mPacket, holder->mOffset);
 }
 
 PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip,
                                       PRInt64 aTimeThreshold)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   // Record number of frames decoded and parsed. Automatically update the
   // stats counters using the AutoNotifyDecoded stack-based class.
   PRUint32 parsed = 0, decoded = 0;
   nsMediaDecoder::AutoNotifyDecoded autoNotify(mDecoder, parsed, decoded);
 
@@ -649,18 +649,18 @@ PRBool nsWebMReader::DecodeVideoFrame(PR
     nsAutoRef<NesteggPacketHolder> next_holder(NextPacket(VIDEO));
     if (next_holder) {
       r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
       if (r == -1) {
         return PR_FALSE;
       }
       mVideoPackets.PushFront(next_holder.disown());
     } else {
-      MonitorAutoExit exitMon(mMonitor);
-      MonitorAutoEnter decoderMon(mDecoder->GetMonitor());
+      ReentrantMonitorAutoExit exitMon(mReentrantMonitor);
+      ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
       nsBuiltinDecoderStateMachine* s =
         static_cast<nsBuiltinDecoderStateMachine*>(mDecoder->GetStateMachine());
       PRInt64 endTime = s->GetEndMediaTime();
       if (endTime == -1) {
         return PR_FALSE;
       }
       next_tstamp = endTime * NS_PER_USEC;
     }
@@ -751,17 +751,17 @@ PRBool nsWebMReader::CanDecodeToTarget(P
 {
   return aTarget >= aCurrentTime &&
          aTarget - aCurrentTime < SEEK_DECODE_MARGIN;
 }
 
 nsresult nsWebMReader::Seek(PRInt64 aTarget, PRInt64 aStartTime, PRInt64 aEndTime,
                             PRInt64 aCurrentTime)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   NS_ASSERTION(mDecoder->OnStateMachineThread(),
                "Should be on state machine thread.");
   LOG(PR_LOG_DEBUG, ("%p About to seek to %lldms", mDecoder, aTarget));
   if (CanDecodeToTarget(aTarget, aCurrentTime)) {
     LOG(PR_LOG_DEBUG, ("%p Seek target (%lld) is close to current time (%lld), "
                        "will just decode to it", mDecoder, aCurrentTime, aTarget));
   } else {
     if (NS_FAILED(ResetDecode())) {
--- a/content/media/webm/nsWebMReader.h
+++ b/content/media/webm/nsWebMReader.h
@@ -138,23 +138,23 @@ public:
   // If the Theora granulepos has not been captured, it may read several packets
   // until one with a granulepos has been captured, to ensure that all packets
   // read have valid time info.  
   virtual PRBool DecodeVideoFrame(PRBool &aKeyframeSkip,
                                   PRInt64 aTimeThreshold);
 
   virtual PRBool HasAudio()
   {
-    mozilla::MonitorAutoEnter mon(mMonitor);
+    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mHasAudio;
   }
 
   virtual PRBool HasVideo()
   {
-    mozilla::MonitorAutoEnter mon(mMonitor);
+    mozilla::ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mHasVideo;
   }
 
   virtual nsresult ReadMetadata(nsVideoInfo* aInfo);
   virtual nsresult Seek(PRInt64 aTime, PRInt64 aStartTime, PRInt64 aEndTime, PRInt64 aCurrentTime);
   virtual nsresult GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, PRUint32 aLength, PRUint32 aOffset);
 
--- a/dom/ipc/AudioChild.cpp
+++ b/dom/ipc/AudioChild.cpp
@@ -43,17 +43,17 @@ namespace mozilla {
 namespace dom {
 
 NS_IMPL_THREADSAFE_ADDREF(AudioChild);
 NS_IMPL_THREADSAFE_RELEASE(AudioChild);
 
 AudioChild::AudioChild()
   : mLastSampleOffset(-1),
     mLastSampleOffsetTime(0),
-    mAudioMonitor("media.audiochild.monitor"),
+    mAudioReentrantMonitor("AutoChild.mReentrantMonitor"),
     mIPCOpen(PR_TRUE),
     mDrained(PR_FALSE)
 {
   MOZ_COUNT_CTOR(AudioChild);
 }
 
 AudioChild::~AudioChild()
 {
@@ -73,28 +73,28 @@ AudioChild::RecvSampleOffsetUpdate(const
   mLastSampleOffset = offset;
   mLastSampleOffsetTime = time;
   return true;
 }
 
 bool
 AudioChild::RecvDrainDone()
 {
-  mozilla::MonitorAutoEnter mon(mAudioMonitor);
+  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
   mDrained = PR_TRUE;
-  mAudioMonitor.NotifyAll();
+  mAudioReentrantMonitor.NotifyAll();
   return true;
 }
 
 void
 AudioChild::WaitForDrain()
 {
-  mozilla::MonitorAutoEnter mon(mAudioMonitor);
+  ReentrantMonitorAutoEnter mon(mAudioReentrantMonitor);
   while (!mDrained && mIPCOpen) {
-    mAudioMonitor.Wait();
+    mAudioReentrantMonitor.Wait();
   }
 }
 
 PRInt64
 AudioChild::GetLastKnownSampleOffset()
 {
   return mLastSampleOffset;
 }
--- a/dom/ipc/AudioChild.h
+++ b/dom/ipc/AudioChild.h
@@ -36,17 +36,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef mozilla_dom_AudioChild_h
 #define mozilla_dom_AudioChild_h
 
 #include "mozilla/dom/PAudioChild.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 namespace mozilla {
 namespace dom {
 
 class AudioChild : public PAudioChild
 {
  public:
     NS_IMETHOD_(nsrefcnt) AddRef();
@@ -62,17 +62,17 @@ class AudioChild : public PAudioChild
     PRInt64 GetLastKnownSampleOffset();
     PRInt64 GetLastKnownSampleOffsetTime();
 
     PRBool IsIPCOpen() { return mIPCOpen; };
  private:
     nsAutoRefCnt mRefCnt;
     NS_DECL_OWNINGTHREAD
     PRInt64 mLastSampleOffset, mLastSampleOffsetTime;
-    mozilla::Monitor mAudioMonitor;
+    mozilla::ReentrantMonitor mAudioReentrantMonitor;
     PRPackedBool mIPCOpen;
     PRPackedBool mDrained;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -104,17 +104,16 @@
 #include "nsWidgetsCID.h"
 #include "nsISupportsPrimitives.h"
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using namespace mozilla::ipc;
 using namespace mozilla::net;
 using namespace mozilla::places;
-using mozilla::MonitorAutoEnter;
 using mozilla::unused; // heh
 using base::KillProcess;
 
 namespace mozilla {
 namespace dom {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
@@ -325,18 +324,17 @@ ContentParent::CreateTestShell()
 
 bool
 ContentParent::DestroyTestShell(TestShellParent* aTestShell)
 {
     return PTestShellParent::Send__delete__(aTestShell);
 }
 
 ContentParent::ContentParent()
-    : mMonitor("ContentParent::mMonitor")
-    , mGeolocationWatchID(-1)
+    : mGeolocationWatchID(-1)
     , mRunToCompletionDepth(0)
     , mShouldCallUnblockChild(false)
     , mIsAlive(true)
     , mProcessStartTime(time(NULL))
 {
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     mSubprocess = new GeckoChildProcessHost(GeckoProcessType_Content);
     mSubprocess->AsyncLaunch();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -42,17 +42,16 @@
 #include "base/waitable_event_watcher.h"
 
 #include "mozilla/dom/PContentParent.h"
 #include "mozilla/dom/PMemoryReportRequestParent.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 #include "nsIObserver.h"
 #include "nsIThreadInternal.h"
-#include "mozilla/Monitor.h"
 #include "nsNetUtil.h"
 #include "nsIPrefService.h"
 #include "nsIPermissionManager.h"
 #include "nsIDOMGeoPositionCallback.h"
 #include "nsIAccelerometer.h"
 #include "nsIMemoryReporter.h"
 #include "nsCOMArray.h"
 
@@ -202,18 +201,16 @@ private:
     virtual bool RecvScriptError(const nsString& aMessage,
                                  const nsString& aSourceName,
                                  const nsString& aSourceLine,
                                  const PRUint32& aLineNumber,
                                  const PRUint32& aColNumber,
                                  const PRUint32& aFlags,
                                  const nsCString& aCategory);
 
-    mozilla::Monitor mMonitor;
-
     GeckoChildProcessHost* mSubprocess;
 
     PRInt32 mGeolocationWatchID;
     int mRunToCompletionDepth;
     bool mShouldCallUnblockChild;
     nsCOMPtr<nsIThreadObserver> mOldObserver;
 
     // This is a cache of all of the memory reporters
--- a/dom/src/threads/nsDOMThreadService.cpp
+++ b/dom/src/threads/nsDOMThreadService.cpp
@@ -368,17 +368,17 @@ public:
     ClearQueue();
   }
 
   void PutRunnable(nsIRunnable* aRunnable,
                    PRIntervalTime aTimeoutInterval,
                    PRBool aClearQueue) {
     NS_ASSERTION(aRunnable, "Null pointer!");
 
-    gDOMThreadService->mMonitor.AssertCurrentThreadIn();
+    gDOMThreadService->mReentrantMonitor.AssertCurrentThreadIn();
 
     if (NS_LIKELY(!aTimeoutInterval)) {
       NS_ADDREF(aRunnable);
       mRunnables.Push(aRunnable);
     }
     else {
       NS_ASSERTION(!mCloseRunnable, "More than one close runnable?!");
       if (aClearQueue) {
@@ -461,17 +461,17 @@ public:
           // replaced outside of a request.
           JSAutoRequest ar2(cx);
 
           // This is usually due to a parse error in the worker script...
           JS_SetGlobalObject(cx, NULL);
           JS_SetContextPrivate(cx, NULL);
         }
 
-        MonitorAutoEnter mon(gDOMThreadService->mMonitor);
+        ReentrantMonitorAutoEnter mon(gDOMThreadService->mReentrantMonitor);
         killWorkerWhenDone = mKillWorkerWhenDone;
         gDOMThreadService->WorkerComplete(this);
         mon.NotifyAll();
       }
     }
 
     if (killWorkerWhenDone) {
       nsCOMPtr<nsIRunnable> runnable = new nsDOMWorkerKillRunnable(mWorker);
@@ -491,17 +491,17 @@ protected:
       // Loop until all the runnables are dead.
     }
   }
 
   void RunQueue(JSContext* aCx, PRBool* aCloseRunnableSet) {
     while (1) {
       nsCOMPtr<nsIRunnable> runnable;
       {
-        MonitorAutoEnter mon(gDOMThreadService->mMonitor);
+        ReentrantMonitorAutoEnter mon(gDOMThreadService->mReentrantMonitor);
 
         runnable = dont_AddRef((nsIRunnable*)mRunnables.PopFront());
 
         if (!runnable && mCloseRunnable) {
           PRIntervalTime expirationTime;
           if (mCloseTimeoutInterval == PR_INTERVAL_NO_TIMEOUT) {
             expirationTime = mCloseTimeoutInterval;
           }
@@ -534,17 +534,17 @@ protected:
       runnable->Run();
     }
     NS_NOTREACHED("Shouldn't ever get here!");
   }
 
   // Set at construction
   nsRefPtr<nsDOMWorker> mWorker;
 
-  // Protected by mMonitor
+  // Protected by mReentrantMonitor
   nsDeque mRunnables;
   nsCOMPtr<nsIRunnable> mCloseRunnable;
   PRIntervalTime mCloseTimeoutInterval;
   PRBool mKillWorkerWhenDone;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsDOMWorkerRunnable, nsIRunnable)
 
@@ -568,17 +568,17 @@ DOMWorkerOperationCallback(JSContext* aC
     PRBool extraThreadAllowed =
       NS_SUCCEEDED(gDOMThreadService->ChangeThreadPoolMaxThreads(1));
 
     // Flush JIT caches now before suspending to avoid holding memory that we
     // are not going to use.
     JS_FlushCaches(aCx);
 
     for (;;) {
-      MonitorAutoEnter mon(worker->Pool()->GetMonitor());
+      ReentrantMonitorAutoEnter mon(worker->Pool()->GetReentrantMonitor());
 
       // There's a small chance that the worker was canceled after our check
       // above in which case we shouldn't wait here. We're guaranteed not to
       // race here because the pool reenters its monitor after canceling each
       // worker in order to notify its condition variable.
       canceled = worker->IsCanceled();
       if (!canceled && worker->IsSuspended()) {
         mon.Wait();
@@ -724,17 +724,17 @@ DOMWorkerErrorReporter(JSContext* aCx,
   }
 }
 
 /*******************************************************************************
  * nsDOMThreadService
  */
 
 nsDOMThreadService::nsDOMThreadService()
-: mMonitor("nsDOMThreadServer.mMonitor"),
+: mReentrantMonitor("nsDOMThreadServer.mReentrantMonitor"),
   mNavigatorStringsLoaded(PR_FALSE)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 #ifdef PR_LOGGING
   if (!gDOMThreadsLog) {
     gDOMThreadsLog = PR_NewLogModule("nsDOMThreads");
   }
 #endif
@@ -879,17 +879,17 @@ nsDOMThreadService::Cleanup()
   // This will either be called at 'xpcom-shutdown' or earlier if the call to
   // Init fails somehow. We can therefore assume that all services will still
   // be available here.
 
   // Cancel all workers that weren't tied to a window.
   CancelWorkersForGlobal(nsnull);
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     NS_ASSERTION(!mPools.Count(), "Live workers left!");
     mPools.Clear();
 
     NS_ASSERTION(!mSuspendedWorkers.Length(), "Suspended workers left!");
     mSuspendedWorkers.Clear();
   }
 
@@ -944,17 +944,17 @@ nsDOMThreadService::Dispatch(nsDOMWorker
   if (aWorker->IsClosing() && !aTimeoutInterval) {
     LOG(("Will not dispatch runnable [0x%p] for closing worker [0x%p]",
          static_cast<void*>(aRunnable), static_cast<void*>(aWorker)));
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   nsRefPtr<nsDOMWorkerRunnable> workerRunnable;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (mWorkersInProgress.Get(aWorker, getter_AddRefs(workerRunnable))) {
       workerRunnable->PutRunnable(aRunnable, aTimeoutInterval, aClearQueue);
       return NS_OK;
     }
 
     workerRunnable = new nsDOMWorkerRunnable(aWorker);
     NS_ENSURE_TRUE(workerRunnable, NS_ERROR_OUT_OF_MEMORY);
@@ -967,17 +967,17 @@ nsDOMThreadService::Dispatch(nsDOMWorker
 
   nsresult rv = mThreadPool->Dispatch(workerRunnable, NS_DISPATCH_NORMAL);
 
   // XXX This is a mess and it could probably be removed once we have an
   // infallible malloc implementation.
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch runnable to thread pool!");
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // We exited the monitor after inserting the runnable into the table so make
     // sure we're removing the right one!
     nsRefPtr<nsDOMWorkerRunnable> tableRunnable;
     if (mWorkersInProgress.Get(aWorker, getter_AddRefs(tableRunnable)) &&
         workerRunnable == tableRunnable) {
       mWorkersInProgress.Remove(aWorker);
 
@@ -995,45 +995,45 @@ void
 nsDOMThreadService::SetWorkerTimeout(nsDOMWorker* aWorker,
                                      PRIntervalTime aTimeoutInterval)
 {
   NS_ASSERTION(aWorker, "Null pointer!");
   NS_ASSERTION(aTimeoutInterval, "No timeout specified!");
 
   NS_ASSERTION(mThreadPool, "Dispatch called after 'xpcom-shutdown'!");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nsRefPtr<nsDOMWorkerRunnable> workerRunnable;
   if (mWorkersInProgress.Get(aWorker, getter_AddRefs(workerRunnable))) {
     workerRunnable->SetCloseRunnableTimeout(aTimeoutInterval);
   }
 }
 
 void
 nsDOMThreadService::WorkerComplete(nsDOMWorkerRunnable* aRunnable)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
 #ifdef DEBUG
   nsRefPtr<nsDOMWorker>& debugWorker = aRunnable->mWorker;
 
   nsRefPtr<nsDOMWorkerRunnable> runnable;
   NS_ASSERTION(mWorkersInProgress.Get(debugWorker, getter_AddRefs(runnable)) &&
                runnable == aRunnable,
                "Removing a worker that isn't in our hashtable?!");
 #endif
 
   mWorkersInProgress.Remove(aRunnable->mWorker);
 }
 
 PRBool
 nsDOMThreadService::QueueSuspendedWorker(nsDOMWorkerRunnable* aRunnable)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
 #ifdef DEBUG
     {
       // Make sure that the runnable is in mWorkersInProgress.
       nsRefPtr<nsDOMWorkerRunnable> current;
       mWorkersInProgress.Get(aRunnable->mWorker, getter_AddRefs(current));
       NS_ASSERTION(current == aRunnable, "Something crazy wrong here!");
     }
@@ -1080,49 +1080,49 @@ nsDOMThreadService::CreateJSContext()
 
   return cx.forget();
 }
 
 already_AddRefed<nsDOMWorkerPool>
 nsDOMThreadService::GetPoolForGlobal(nsIScriptGlobalObject* aGlobalObject,
                                      PRBool aRemove)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nsRefPtr<nsDOMWorkerPool> pool;
   mPools.Get(aGlobalObject, getter_AddRefs(pool));
 
   if (aRemove) {
     mPools.Remove(aGlobalObject);
   }
 
   return pool.forget();
 }
 
 void
 nsDOMThreadService::TriggerOperationCallbackForPool(nsDOMWorkerPool* aPool)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   // See if we need to trigger the operation callback on any currently running
   // contexts.
   PRUint32 contextCount = mJSContexts.Length();
   for (PRUint32 index = 0; index < contextCount; index++) {
     JSContext*& cx = mJSContexts[index];
     nsDOMWorker* worker = (nsDOMWorker*)JS_GetContextPrivate(cx);
     if (worker && worker->Pool() == aPool) {
       JS_TriggerOperationCallback(cx);
     }
   }
 }
 
 void
 nsDOMThreadService::RescheduleSuspendedWorkerForPool(nsDOMWorkerPool* aPool)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
 
   PRUint32 count = mSuspendedWorkers.Length();
   if (!count) {
     // Nothing to do here.
     return;
   }
 
   nsTArray<nsDOMWorkerRunnable*> others(count);
@@ -1156,59 +1156,59 @@ nsDOMThreadService::RescheduleSuspendedW
 
 void
 nsDOMThreadService::CancelWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject)
 {
   nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_TRUE);
   if (pool) {
     pool->Cancel();
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     TriggerOperationCallbackForPool(pool);
     RescheduleSuspendedWorkerForPool(pool);
   }
 }
 
 void
 nsDOMThreadService::SuspendWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject)
 {
   NS_ASSERTION(aGlobalObject, "Null pointer!");
 
   nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_FALSE);
   if (pool) {
     pool->Suspend();
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     TriggerOperationCallbackForPool(pool);
   }
 }
 
 void
 nsDOMThreadService::ResumeWorkersForGlobal(nsIScriptGlobalObject* aGlobalObject)
 {
   NS_ASSERTION(aGlobalObject, "Null pointer!");
 
   nsRefPtr<nsDOMWorkerPool> pool = GetPoolForGlobal(aGlobalObject, PR_FALSE);
   if (pool) {
     pool->Resume();
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     TriggerOperationCallbackForPool(pool);
     RescheduleSuspendedWorkerForPool(pool);
   }
 }
 
 void
 nsDOMThreadService::NoteEmptyPool(nsDOMWorkerPool* aPool)
 {
   NS_ASSERTION(aPool, "Null pointer!");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mPools.Remove(aPool->ScriptGlobalObject());
 }
 
 void
 nsDOMThreadService::TimeoutReady(nsDOMWorkerTimeout* aTimeout)
 {
   nsRefPtr<nsDOMWorkerTimeoutRunnable> runnable =
     new nsDOMWorkerTimeoutRunnable(aTimeout);
@@ -1217,17 +1217,17 @@ nsDOMThreadService::TimeoutReady(nsDOMWo
   Dispatch(aTimeout->GetWorker(), runnable);
 }
 
 nsresult
 nsDOMThreadService::ChangeThreadPoolMaxThreads(PRInt16 aDelta)
 {
   NS_ENSURE_ARG(aDelta == 1 || aDelta == -1);
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   PRUint32 currentThreadCount;
   nsresult rv = mThreadPool->GetThreadLimit(&currentThreadCount);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 newThreadCount = (PRInt32)currentThreadCount + (PRInt32)aDelta;
   NS_ASSERTION(newThreadCount >= THREADPOOL_MAX_THREADS,
                "Can't go below initial thread count!");
@@ -1255,17 +1255,17 @@ nsDOMThreadService::ChangeThreadPoolMaxT
 }
 
 void
 nsDOMThreadService::NoteThreadsafeContractId(const nsACString& aContractId,
                                              PRBool aIsThreadsafe)
 {
   NS_ASSERTION(!aContractId.IsEmpty(), "Empty contract id!");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
 #ifdef DEBUG
   {
     PRBool isThreadsafe;
     if (mThreadsafeContractIDs.Get(aContractId, &isThreadsafe)) {
       NS_ASSERTION(aIsThreadsafe == isThreadsafe, "Inconsistent threadsafety!");
     }
   }
@@ -1276,17 +1276,17 @@ nsDOMThreadService::NoteThreadsafeContra
   }
 }
 
 ThreadsafeStatus
 nsDOMThreadService::GetContractIdThreadsafeStatus(const nsACString& aContractId)
 {
   NS_ASSERTION(!aContractId.IsEmpty(), "Empty contract id!");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   PRBool isThreadsafe;
   if (mThreadsafeContractIDs.Get(aContractId, &isThreadsafe)) {
     return isThreadsafe ? Threadsafe : NotThreadsafe;
   }
 
   return Unknown;
 }
@@ -1387,17 +1387,17 @@ nsDOMThreadService::OnThreadCreated()
 
     PRStatus status = PR_SetThreadPrivate(gJSContextIndex, cx);
     if (status != PR_SUCCESS) {
       NS_WARNING("Failed to set context on thread!");
       nsContentUtils::XPConnect()->ReleaseJSContext(cx, PR_TRUE);
       return NS_ERROR_FAILURE;
     }
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
 #ifdef DEBUG
     JSContext** newContext =
 #endif
     mJSContexts.AppendElement(cx);
 
     // We ensure the capacity of this array in Init.
     NS_ASSERTION(newContext, "Should never fail!");
@@ -1416,17 +1416,17 @@ nsDOMThreadService::OnThreadShuttingDown
   LOG(("Thread shutting down"));
 
   NS_ASSERTION(gJSContextIndex != BAD_TLS_INDEX, "No context index!");
 
   JSContext* cx = (JSContext*)PR_GetThreadPrivate(gJSContextIndex);
   NS_WARN_IF_FALSE(cx, "Thread died with no context?");
   if (cx) {
     {
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       mJSContexts.RemoveElement(cx);
     }
 
     JSContext* pushedCx;
     gThreadJSContextStack->Pop(&pushedCx);
     NS_ASSERTION(pushedCx == cx, "Popped the wrong context!");
 
     gThreadJSContextStack->SetSafeJSContext(nsnull);
@@ -1462,17 +1462,17 @@ nsDOMThreadService::RegisterWorker(nsDOM
     nsCOMPtr<nsIScriptGlobalObject> newGlobal(do_QueryInterface(innerWindow));
     NS_ENSURE_TRUE(newGlobal, NS_ERROR_NO_INTERFACE);
 
     aGlobalObject = newGlobal;
   }
 
   nsRefPtr<nsDOMWorkerPool> pool;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (!mThreadPool) {
       // Shutting down!
       return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;
     }
 
     mPools.Get(aGlobalObject, getter_AddRefs(pool));
   }
@@ -1511,17 +1511,17 @@ nsDOMThreadService::RegisterWorker(nsDOM
     }
 
     pool = new nsDOMWorkerPool(aGlobalObject, document);
     NS_ENSURE_TRUE(pool, NS_ERROR_OUT_OF_MEMORY);
 
     rv = pool->Init();
     NS_ENSURE_SUCCESS(rv, rv);
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     PRBool success = mPools.Put(aGlobalObject, pool);
     NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
   }
 
   rv = pool->NoteWorker(aWorker);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/dom/src/threads/nsDOMThreadService.h
+++ b/dom/src/threads/nsDOMThreadService.h
@@ -42,17 +42,17 @@
 
 // Interfaces
 #include "nsIEventTarget.h"
 #include "nsIObserver.h"
 #include "nsIThreadPool.h"
 
 // Other includes
 #include "jsapi.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsDataHashtable.h"
 #include "nsRefPtrHashtable.h"
 #include "nsStringGlue.h"
 #include "nsTPtrArray.h"
 
 #include "prlog.h"
@@ -178,32 +178,32 @@ private:
   PRBool QueueSuspendedWorker(nsDOMWorkerRunnable* aRunnable);
 
   // Our internal thread pool.
   nsCOMPtr<nsIThreadPool> mThreadPool;
 
   // Maps nsIScriptGlobalObject* to nsDOMWorkerPool.
   nsRefPtrHashtable<nsVoidPtrHashKey, nsDOMWorkerPool> mPools;
 
-  // mMonitor protects all access to mWorkersInProgress and
+  // mReentrantMonitor protects all access to mWorkersInProgress and
   // mCreationsInProgress.
-  mozilla::Monitor mMonitor;
+  mozilla::ReentrantMonitor mReentrantMonitor;
 
   // A map from nsDOMWorkerThread to nsDOMWorkerRunnable.
   nsRefPtrHashtable<nsVoidPtrHashKey, nsDOMWorkerRunnable> mWorkersInProgress;
 
   // A list of active JSContexts that we've created. Always protected with
-  // mMonitor.
+  // mReentrantMonitor.
   nsTArray<JSContext*> mJSContexts;
 
   // A list of worker runnables that were never started because the worker was
-  // suspended. Always protected with mMonitor.
+  // suspended. Always protected with mReentrantMonitor.
   nsTArray<nsDOMWorkerRunnable*> mSuspendedWorkers;
 
-  // Always protected with mMonitor.
+  // Always protected with mReentrantMonitor.
   nsDataHashtable<nsCStringHashKey, PRBool> mThreadsafeContractIDs;
 
   nsString mAppName;
   nsString mAppVersion;
   nsString mPlatform;
   nsString mUserAgent;
 
   PRBool mNavigatorStringsLoaded;
--- a/dom/src/threads/nsDOMWorker.cpp
+++ b/dom/src/threads/nsDOMWorker.cpp
@@ -2387,17 +2387,17 @@ nsDOMWorker::FireCloseRunnable(PRInterva
       NS_ASSERTION(mStatus == eCanceled ||
                    (mStatus == eTerminated && aFromFinalize),
                    "How can this happen otherwise?!");
       mSuspended = PR_FALSE;
     }
   }
 
   if (wakeUp) {
-    MonitorAutoEnter mon(mPool->GetMonitor());
+    ReentrantMonitorAutoEnter mon(mPool->GetReentrantMonitor());
     mon.NotifyAll();
   }
 
   nsRefPtr<nsDOMWorkerEvent> event = new nsDOMWorkerEvent();
   NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv =
     event->InitEvent(NS_LITERAL_STRING("close"), PR_FALSE, PR_FALSE);
--- a/dom/src/threads/nsDOMWorkerPool.cpp
+++ b/dom/src/threads/nsDOMWorkerPool.cpp
@@ -62,17 +62,17 @@
 using namespace mozilla;
 
 #define LOG(_args) PR_LOG(gDOMThreadsLog, PR_LOG_DEBUG, _args)
 
 nsDOMWorkerPool::nsDOMWorkerPool(nsIScriptGlobalObject* aGlobalObject,
                                  nsIDocument* aDocument)
 : mParentGlobal(aGlobalObject),
   mParentDocument(aDocument),
-  mMonitor("nsDOMWorkerPool.mMonitor"),
+  mReentrantMonitor("nsDOMWorkerPool.mReentrantMonitor"),
   mCanceled(PR_FALSE),
   mSuspended(PR_FALSE),
   mWindowID(aDocument ? aDocument->OuterWindowID() : 0)
 {
 }
 
 nsDOMWorkerPool::~nsDOMWorkerPool()
 {
@@ -105,17 +105,17 @@ nsDOMWorkerPool::Init()
 nsresult
 nsDOMWorkerPool::NoteWorker(nsDOMWorker* aWorker)
 {
   NS_ASSERTION(aWorker, "Null pointer!");
 
   PRBool suspendWorker;
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (mCanceled) {
       return NS_ERROR_ABORT;
     }
 
     nsDOMWorker** newWorker = mWorkers.AppendElement(aWorker);
     NS_ENSURE_TRUE(newWorker, NS_ERROR_OUT_OF_MEMORY);
 
@@ -132,17 +132,17 @@ nsDOMWorkerPool::NoteWorker(nsDOMWorker*
 void
 nsDOMWorkerPool::NoteDyingWorker(nsDOMWorker* aWorker)
 {
   NS_ASSERTION(aWorker, "Null pointer!");
 
   PRBool removeFromThreadService = PR_FALSE;
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     NS_ASSERTION(mWorkers.Contains(aWorker), "Worker from a different pool?!");
     mWorkers.RemoveElement(aWorker);
 
     if (!mCanceled && !mWorkers.Length()) {
       removeFromThreadService = PR_TRUE;
     }
   }
@@ -151,17 +151,17 @@ nsDOMWorkerPool::NoteDyingWorker(nsDOMWo
     nsRefPtr<nsDOMWorkerPool> kungFuDeathGrip(this);
     nsDOMThreadService::get()->NoteEmptyPool(this);
   }
 }
 
 void
 nsDOMWorkerPool::GetWorkers(nsTArray<nsDOMWorker*>& aArray)
 {
-  mMonitor.AssertCurrentThreadIn();
+  mReentrantMonitor.AssertCurrentThreadIn();
   NS_ASSERTION(!aArray.Length(), "Should be empty!");
 
 #ifdef DEBUG
   nsDOMWorker** newWorkers =
 #endif
   aArray.AppendElements(mWorkers);
   NS_WARN_IF_FALSE(newWorkers, "Out of memory!");
 }
@@ -169,41 +169,41 @@ nsDOMWorkerPool::GetWorkers(nsTArray<nsD
 void
 nsDOMWorkerPool::Cancel()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   NS_ASSERTION(!mCanceled, "Canceled more than once!");
 
   nsAutoTArray<nsDOMWorker*, 10> workers;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     mCanceled = PR_TRUE;
 
     GetWorkers(workers);
   }
 
   PRUint32 count = workers.Length();
   if (count) {
     for (PRUint32 index = 0; index < count; index++) {
       workers[index]->Cancel();
     }
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.NotifyAll();
   }
 }
 
 void
 nsDOMWorkerPool::Suspend()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsAutoTArray<nsDOMWorker*, 10> workers;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     NS_ASSERTION(!mSuspended, "Suspended more than once!");
     mSuspended = PR_TRUE;
 
     GetWorkers(workers);
   }
 
   PRUint32 count = workers.Length();
@@ -214,25 +214,25 @@ nsDOMWorkerPool::Suspend()
 
 void
 nsDOMWorkerPool::Resume()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsAutoTArray<nsDOMWorker*, 10> workers;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     NS_ASSERTION(mSuspended, "Not suspended!");
     mSuspended = PR_FALSE;
 
     GetWorkers(workers);
   }
 
   PRUint32 count = workers.Length();
   if (count) {
     for (PRUint32 index = 0; index < count; index++) {
       workers[index]->Resume();
     }
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.NotifyAll();
   }
 }
--- a/dom/src/threads/nsDOMWorkerPool.h
+++ b/dom/src/threads/nsDOMWorkerPool.h
@@ -37,30 +37,30 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NSDOMWORKERPOOL_H__
 #define __NSDOMWORKERPOOL_H__
 
 // Other includes
 #include "jsapi.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
 
 class nsDOMWorker;
 class nsIDocument;
 class nsIScriptContext;
 class nsIScriptError;
 class nsIScriptGlobalObject;
 
 class nsDOMWorkerPool
 {
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
 public:
   nsDOMWorkerPool(nsIScriptGlobalObject* aGlobalObject,
                   nsIDocument* aDocument);
 
   NS_IMETHOD_(nsrefcnt) AddRef();
   NS_IMETHOD_(nsrefcnt) Release();
 
@@ -76,18 +76,18 @@ public:
 
   void Cancel();
   void Suspend();
   void Resume();
 
   nsresult NoteWorker(nsDOMWorker* aWorker);
   void NoteDyingWorker(nsDOMWorker* aWorker);
 
-  Monitor& GetMonitor() {
-    return mMonitor;
+  ReentrantMonitor& GetReentrantMonitor() {
+    return mReentrantMonitor;
   }
 
   const PRUint64 WindowID() const {
     return mWindowID;
   }
 
 private:
   virtual ~nsDOMWorkerPool();
@@ -101,18 +101,18 @@ private:
 
   // Reference to the document that created this pool.
   nsCOMPtr<nsIDocument> mParentDocument;
 
   // Weak array of workers. The idea is that workers can be garbage collected
   // independently of the owning pool and other workers.
   nsTArray<nsDOMWorker*> mWorkers;
 
-  // Monitor for suspending and resuming workers.
-  Monitor mMonitor;
+  // ReentrantMonitor for suspending and resuming workers.
+  ReentrantMonitor mReentrantMonitor;
 
   PRPackedBool mCanceled;
   PRPackedBool mSuspended;
 
   const PRUint64 mWindowID;
 };
 
 #endif /* __NSDOMWORKERPOOL_H__ */
--- a/gfx/layers/ImageLayers.h
+++ b/gfx/layers/ImageLayers.h
@@ -38,17 +38,17 @@
 #ifndef GFX_IMAGELAYER_H
 #define GFX_IMAGELAYER_H
 
 #include "Layers.h"
 
 #include "gfxPattern.h"
 #include "nsThreadUtils.h"
 #include "nsCoreAnimationSupport.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/TimeStamp.h"
 
 namespace mozilla {
 namespace layers {
 
 enum StereoMode {
   STEREO_MODE_MONO,
   STEREO_MODE_LEFT_RIGHT,
@@ -129,104 +129,104 @@ protected:
  * be able to set the current Image from any thread, to facilitate
  * video playback without involving the main thread, for example.
  */
 class THEBES_API ImageContainer {
   THEBES_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageContainer)
 
 public:
   ImageContainer() :
-    mMonitor("ImageContainer"),
+    mReentrantMonitor("ImageContainer.mReentrantMonitor"),
     mPaintCount(0),
     mPreviousImagePainted(PR_FALSE)
   {}
 
   virtual ~ImageContainer() {}
 
   /**
    * Create an Image in one of the given formats.
    * Picks the "best" format from the list and creates an Image of that
    * format.
    * Returns null if this backend does not support any of the formats.
-   * Can be called on any thread. This method takes mMonitor when accessing
-   * thread-shared state.
+   * Can be called on any thread. This method takes mReentrantMonitor
+   * when accessing thread-shared state.
    */
   virtual already_AddRefed<Image> CreateImage(const Image::Format* aFormats,
                                               PRUint32 aNumFormats) = 0;
 
   /**
    * Set an Image as the current image to display. The Image must have
    * been created by this ImageContainer.
-   * Can be called on any thread. This method takes mMonitor when accessing
-   * thread-shared state.
+   * Can be called on any thread. This method takes mReentrantMonitor
+   * when accessing thread-shared state.
    * 
    * The Image data must not be modified after this method is called!
    */
   virtual void SetCurrentImage(Image* aImage) = 0;
 
   /**
    * Get the current Image.
    * This has to add a reference since otherwise there are race conditions
    * where the current image is destroyed before the caller can add
    * a reference.
-   * Can be called on any thread. This method takes mMonitor when accessing
-   * thread-shared state.
-   * Implementations must call CurrentImageChanged() while holding mMonitor.
-   *
+   * Can be called on any thread. This method takes mReentrantMonitor
+   * when accessing thread-shared state.
+   * Implementations must call CurrentImageChanged() while holding
+   * mReentrantMonitor.
    */
   virtual already_AddRefed<Image> GetCurrentImage() = 0;
 
   /**
    * Get the current image as a gfxASurface. This is useful for fallback
    * rendering.
    * This can only be called from the main thread, since cairo objects
    * can only be used from the main thread.
    * This is defined here and not on Image because it's possible (likely)
    * that some backends will make an Image "ready to draw" only when it
    * becomes the current image for an image container.
    * Returns null if there is no current image.
    * Returns the size in aSize.
    * The returned surface will never be modified. The caller must not
    * modify it.
-   * Can be called on any thread. This method takes mMonitor when accessing
-   * thread-shared state.
+   * Can be called on any thread. This method takes mReentrantMonitor
+   * when accessing thread-shared state.
    */
   virtual already_AddRefed<gfxASurface> GetCurrentAsSurface(gfxIntSize* aSizeResult) = 0;
 
   /**
    * Returns the layer manager for this container. This can only
    * be used on the main thread, since layer managers should only be
    * accessed on the main thread.
    */
   LayerManager* Manager()
   {
     NS_PRECONDITION(NS_IsMainThread(), "Must be called on main thread");
     return mManager;
   }
 
   /**
    * Returns the size of the image in pixels.
-   * Can be called on any thread. This method takes mMonitor when accessing
+   * Can be called on any thread. This method takes mReentrantMonitor when accessing
    * thread-shared state.
    */
   virtual gfxIntSize GetCurrentSize() = 0;
 
   /**
    * Set a new layer manager for this image container.  It must be
    * either of the same type as the container's current layer manager,
    * or null.  TRUE is returned on success. Main thread only.
    */
   virtual PRBool SetLayerManager(LayerManager *aManager) = 0;
 
   /**
    * Sets a size that the image is expected to be rendered at.
    * This is a hint for image backends to optimize scaling.
    * Default implementation in this class is to ignore the hint.
-   * Can be called on any thread. This method takes mMonitor when accessing
-   * thread-shared state.
+   * Can be called on any thread. This method takes mReentrantMonitor
+   * when accessing thread-shared state.
    */
   virtual void SetScaleHint(const gfxIntSize& /* aScaleHint */) { }
 
   /**
    * Get the layer manager type this image container was created with,
    * presumably its users might want to do something special if types do not
    * match. Can be called on any thread.
    */
@@ -234,71 +234,71 @@ public:
 
   /**
    * Returns the time at which the currently contained image was first
    * painted.  This is reset every time a new image is set as the current
    * image.  Note this may return a null timestamp if the current image
    * has not yet been painted.  Can be called from any thread.
    */
   TimeStamp GetPaintTime() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mPaintTime;
   }
 
   /**
    * Returns the number of images which have been contained in this container
    * and painted at least once.  Can be called from any thread.
    */
   PRUint32 GetPaintCount() {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mPaintCount;
   }
 
   /**
    * Increments mPaintCount if this is the first time aPainted has been
    * painted, and sets mPaintTime if the painted image is the current image.
    * current image.  Can be called from any thread.
    */
   void NotifyPaintedImage(Image* aPainted) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     nsRefPtr<Image> current = GetCurrentImage();
     if (aPainted == current) {
       if (mPaintTime.IsNull()) {
         mPaintTime = TimeStamp::Now();
         mPaintCount++;
       }
     } else if (!mPreviousImagePainted) {
       // While we were painting this image, the current image changed. We
       // still must count it as painted, but can't set mPaintTime, since we're
       // no longer the current image.
       mPaintCount++;
       mPreviousImagePainted = PR_TRUE;
     }
   }
 
 protected:
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
   LayerManager* mManager;
 
-  // Monitor to protect thread safe access to the "current image", and any
-  // other state which is shared between threads.
-  Monitor mMonitor;
+  // ReentrantMonitor to protect thread safe access to the "current
+  // image", and any other state which is shared between threads.
+  ReentrantMonitor mReentrantMonitor;
 
   ImageContainer(LayerManager* aManager) :
     mManager(aManager),
-    mMonitor("ImageContainer"),
+    mReentrantMonitor("ImageContainer.mReentrantMonitor"),
     mPaintCount(0),
     mPreviousImagePainted(PR_FALSE)
   {}
 
   // Performs necessary housekeeping to ensure the painted frame statistics
   // are accurate. Must be called by SetCurrentImage() implementations with
-  // mMonitor held.
+  // mReentrantMonitor held.
   void CurrentImageChanged() {
-    mMonitor.AssertCurrentThreadIn();
+    mReentrantMonitor.AssertCurrentThreadIn();
     mPreviousImagePainted = !mPaintTime.IsNull();
     mPaintTime = TimeStamp();
   }
 
   // Number of contained images that have been painted at least once.  It's up
   // to the ImageContainer implementation to ensure accesses to this are
   // threadsafe.
   PRUint32 mPaintCount;
--- a/gfx/layers/basic/BasicImages.cpp
+++ b/gfx/layers/basic/BasicImages.cpp
@@ -30,34 +30,34 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #include "ImageLayers.h"
 #include "BasicLayers.h"
 #include "gfxImageSurface.h"
 
 #ifdef XP_MACOSX
 #include "gfxQuartzImageSurface.h"
 #endif
 
 #include "cairo.h"
 
 #include "yuv_convert.h"
 #include "ycbcr_to_rgb565.h"
 
 #include "gfxPlatform.h"
 
-using mozilla::Monitor;
+using mozilla::ReentrantMonitor;
 
 namespace mozilla {
 namespace layers {
 
 /**
  * All our images can yield up a cairo surface and their size.
  */
 class BasicImageImplData {
@@ -321,17 +321,17 @@ BasicPlanarYCbCrImage::GetAsSurface()
 #endif
   mSurface = result.get();
 
   return result.forget();
 }
 
 /**
  * Our image container is very simple. It's really just a factory
- * for the image objects. We use a Monitor to synchronize access to
+ * for the image objects. We use a ReentrantMonitor to synchronize access to
  * mImage.
  */
 class BasicImageContainer : public ImageContainer {
 public:
   typedef gfxASurface::gfxImageFormat gfxImageFormat;
 
   BasicImageContainer() :
     ImageContainer(nsnull),
@@ -374,68 +374,68 @@ already_AddRefed<Image>
 BasicImageContainer::CreateImage(const Image::Format* aFormats,
                                  PRUint32 aNumFormats)
 {
   nsRefPtr<Image> image;
   // Prefer cairo surfaces because they're native for us
   if (FormatInList(aFormats, aNumFormats, Image::CAIRO_SURFACE)) {
     image = new BasicCairoImage();
   } else if (FormatInList(aFormats, aNumFormats, Image::PLANAR_YCBCR)) {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     image = new BasicPlanarYCbCrImage(mScaleHint);
     static_cast<BasicPlanarYCbCrImage*>(image.get())->SetOffscreenFormat(mOffscreenFormat);
   }
   return image.forget();
 }
 
 void
 BasicImageContainer::SetCurrentImage(Image* aImage)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mImage = aImage;
   CurrentImageChanged();
 }
 
 already_AddRefed<Image>
 BasicImageContainer::GetCurrentImage()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   nsRefPtr<Image> image = mImage;
   return image.forget();
 }
 
 static BasicImageImplData*
 ToImageData(Image* aImage)
 {
   return static_cast<BasicImageImplData*>(aImage->GetImplData());
 }
 
 already_AddRefed<gfxASurface>
 BasicImageContainer::GetCurrentAsSurface(gfxIntSize* aSizeResult)
 {
   NS_PRECONDITION(NS_IsMainThread(), "Must be called on main thread");
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mImage) {
     return nsnull;
   }
   *aSizeResult = ToImageData(mImage)->GetSize();
   return ToImageData(mImage)->GetAsSurface();
 }
 
 gfxIntSize
 BasicImageContainer::GetCurrentSize()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   return !mImage ? gfxIntSize(0,0) : ToImageData(mImage)->GetSize();
 }
 
 void BasicImageContainer::SetScaleHint(const gfxIntSize& aScaleHint)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mScaleHint = aScaleHint;
 }
 
 PRBool
 BasicImageContainer::SetLayerManager(LayerManager *aManager)
 {
   if (aManager &&
       aManager->GetBackendType() != LayerManager::LAYERS_BASIC)
--- a/gfx/layers/d3d10/ImageLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ImageLayerD3D10.cpp
@@ -116,35 +116,35 @@ ImageContainerD3D10::CreateImage(const I
     img = new CairoImageD3D10(mDevice);
   }
   return img.forget();
 }
 
 void
 ImageContainerD3D10::SetCurrentImage(Image *aImage)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mActiveImage = aImage;
   CurrentImageChanged();
 }
 
 already_AddRefed<Image>
 ImageContainerD3D10::GetCurrentImage()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nsRefPtr<Image> retval = mActiveImage;
   return retval.forget();
 }
 
 already_AddRefed<gfxASurface>
 ImageContainerD3D10::GetCurrentAsSurface(gfxIntSize *aSize)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mActiveImage) {
     return nsnull;
   }
 
   if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImageD3D10 *yuvImage =
       static_cast<PlanarYCbCrImageD3D10*>(mActiveImage.get());
     if (yuvImage->HasData()) {
@@ -157,17 +157,17 @@ ImageContainerD3D10::GetCurrentAsSurface
   }
 
   return static_cast<ImageD3D10*>(mActiveImage->GetImplData())->GetAsSurface();
 }
 
 gfxIntSize
 ImageContainerD3D10::GetCurrentSize()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mActiveImage) {
     return gfxIntSize(0,0);
   }
   if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImageD3D10 *yuvImage =
       static_cast<PlanarYCbCrImageD3D10*>(mActiveImage.get());
     if (!yuvImage->HasData()) {
       return gfxIntSize(0,0);
--- a/gfx/layers/d3d9/ImageLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ImageLayerD3D9.cpp
@@ -151,35 +151,35 @@ ImageContainerD3D9::CreateImage(const Im
     img = new CairoImageD3D9(mDevice);
   }
   return img.forget();
 }
 
 void
 ImageContainerD3D9::SetCurrentImage(Image *aImage)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mActiveImage = aImage;
   CurrentImageChanged();
 }
 
 already_AddRefed<Image>
 ImageContainerD3D9::GetCurrentImage()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nsRefPtr<Image> retval = mActiveImage;
   return retval.forget();
 }
 
 already_AddRefed<gfxASurface>
 ImageContainerD3D9::GetCurrentAsSurface(gfxIntSize *aSize)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mActiveImage) {
     return nsnull;
   }
 
   if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImageD3D9 *yuvImage =
       static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
     if (yuvImage->HasData()) {
@@ -192,17 +192,17 @@ ImageContainerD3D9::GetCurrentAsSurface(
   }
 
   return static_cast<ImageD3D9*>(mActiveImage->GetImplData())->GetAsSurface();
 }
 
 gfxIntSize
 ImageContainerD3D9::GetCurrentSize()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mActiveImage) {
     return gfxIntSize(0,0);
   }
   if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImageD3D9 *yuvImage =
       static_cast<PlanarYCbCrImageD3D9*>(mActiveImage.get());
     if (!yuvImage->HasData()) {
       return gfxIntSize(0,0);
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -228,40 +228,40 @@ ImageContainerOGL::CreateImage(const Ima
 }
 
 void
 ImageContainerOGL::SetCurrentImage(Image *aImage)
 {
   nsRefPtr<Image> oldImage;
 
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     oldImage = mActiveImage.forget();
     mActiveImage = aImage;
     CurrentImageChanged();
   }
 
   // Make sure oldImage is released outside the lock, so it can take our
   // lock in RecycleBuffer
 }
 
 already_AddRefed<Image>
 ImageContainerOGL::GetCurrentImage()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   nsRefPtr<Image> retval = mActiveImage;
   return retval.forget();
 }
 
 already_AddRefed<gfxASurface>
 ImageContainerOGL::GetCurrentAsSurface(gfxIntSize *aSize)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   if (!mActiveImage) {
     *aSize = gfxIntSize(0,0);
     return nsnull;
   }
 
   GLContext *gl = nsnull;
   // tex1 will be RGBA or Y, tex2 will Cb, tex3 will be Cr
@@ -309,17 +309,17 @@ ImageContainerOGL::GetCurrentAsSurface(g
   nsRefPtr<gfxImageSurface> s = gl->ReadTextureImage(tex1, size, LOCAL_GL_RGBA);
   *aSize = size;
   return s.forget();
 }
 
 gfxIntSize
 ImageContainerOGL::GetCurrentSize()
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   if (!mActiveImage) {
     return gfxIntSize(0,0);
   }
 
   if (mActiveImage->GetFormat() == Image::PLANAR_YCBCR) {
     PlanarYCbCrImageOGL *yuvImage =
       static_cast<PlanarYCbCrImageOGL*>(mActiveImage.get());
     if (!yuvImage->HasData()) {
--- a/intl/strres/src/nsStringBundle.cpp
+++ b/intl/strres/src/nsStringBundle.cpp
@@ -82,17 +82,17 @@ static NS_DEFINE_CID(kPersistentProperti
 nsStringBundle::~nsStringBundle()
 {
 }
 
 nsStringBundle::nsStringBundle(const char* aURLSpec,
                                nsIStringBundleOverride* aOverrideStrings) :
   mPropertiesURL(aURLSpec),
   mOverrideStrings(aOverrideStrings),
-  mMonitor("nsStringBundle.mMonitor"),
+  mReentrantMonitor("nsStringBundle.mReentrantMonitor"),
   mAttemptedLoad(PR_FALSE),
   mLoaded(PR_FALSE)
 {
 }
 
 nsresult
 nsStringBundle::LoadProperties()
 {
@@ -143,17 +143,17 @@ nsStringBundle::LoadProperties()
   
   return rv;
 }
 
 
 nsresult
 nsStringBundle::GetStringFromID(PRInt32 aID, nsAString& aResult)
 {  
-  MonitorAutoEnter automon(mMonitor);
+  ReentrantMonitorAutoEnter automon(mReentrantMonitor);
   nsCAutoString name;
   name.AppendInt(aID, 10);
 
   nsresult rv;
   
   // try override first
   if (mOverrideStrings) {
     rv = mOverrideStrings->GetStringFromName(mPropertiesURL,
@@ -264,17 +264,17 @@ nsStringBundle::GetStringFromName(const 
 {
   NS_ENSURE_ARG_POINTER(aName);
   NS_ENSURE_ARG_POINTER(aResult);
 
   nsresult rv;
   rv = LoadProperties();
   if (NS_FAILED(rv)) return rv;
 
-  MonitorAutoEnter automon(mMonitor);
+  ReentrantMonitorAutoEnter automon(mReentrantMonitor);
   *aResult = nsnull;
   nsAutoString tmpstr;
   rv = GetStringFromName(nsDependentString(aName), tmpstr);
   if (NS_FAILED(rv))
   {
 #if 0
     // it is not uncommon for apps to request a string name which may not exist
     // so be quiet about it. 
--- a/intl/strres/src/nsStringBundle.h
+++ b/intl/strres/src/nsStringBundle.h
@@ -33,17 +33,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsStringBundle_h__
 #define nsStringBundle_h__
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsIStringBundle.h"
 #include "nsCOMPtr.h"
 #include "nsIPersistentProperties2.h"
 #include "nsString.h"
 #include "nsCOMArray.h"
 #include "nsIStringBundleOverride.h"
 
 class nsStringBundle : public nsIStringBundle
@@ -66,17 +66,17 @@ protected:
     nsresult GetStringFromID(PRInt32 aID, nsAString& aResult);
     nsresult GetStringFromName(const nsAString& aName, nsAString& aResult);
 
     nsresult GetCombinedEnumeration(nsIStringBundleOverride* aOverrideString,
                                     nsISimpleEnumerator** aResult);
 private:
     nsCString              mPropertiesURL;
     nsCOMPtr<nsIStringBundleOverride> mOverrideStrings;
-    mozilla::Monitor             mMonitor;
+    mozilla::ReentrantMonitor    mReentrantMonitor;
     PRPackedBool                 mAttemptedLoad;
     PRPackedBool                 mLoaded;
     
 public:
     static nsresult FormatString(const PRUnichar *formatStr,
                                  const PRUnichar **aParams, PRUint32 aLength,
                                  PRUnichar **aResult);
 };
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -69,17 +69,17 @@
 #include "nsIWinTaskbar.h"
 #define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
 #endif
 
 #ifdef ANDROID
 #include "APKOpen.h"
 #endif
 
-using mozilla::MonitorAutoEnter;
+using mozilla::ReentrantMonitorAutoEnter;
 using mozilla::ipc::GeckoChildProcessHost;
 
 #ifdef ANDROID
 // Like its predecessor in nsExceptionHandler.cpp, this is
 // the magic number of a file descriptor remapping we must
 // preserve for the child process.
 static const int kMagicAndroidSystemPropFd = 5;
 #endif
@@ -90,17 +90,17 @@ struct RunnableMethodTraits<GeckoChildPr
     static void RetainCallee(GeckoChildProcessHost* obj) { }
     static void ReleaseCallee(GeckoChildProcessHost* obj) { }
 };
 
 GeckoChildProcessHost::GeckoChildProcessHost(GeckoProcessType aProcessType,
                                              base::WaitableEventWatcher::Delegate* aDelegate)
   : ChildProcessHost(RENDER_PROCESS), // FIXME/cjones: we should own this enum
     mProcessType(aProcessType),
-    mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
+    mReentrantMonitor("mozilla.ipc.GeckChildProcessHost.mReentrantMonitor"),
     mLaunched(false),
     mChannelInitialized(false),
     mDelegate(aDelegate),
     mChildProcessHandle(0)
 #if defined(XP_MACOSX)
   , mChildTask(MACH_PORT_NULL)
 #endif
 {
@@ -284,17 +284,17 @@ GeckoChildProcessHost::SyncLaunch(std::v
   NS_ASSERTION(MessageLoop::current() != ioLoop, "sync launch from the IO thread NYI");
 
   ioLoop->PostTask(FROM_HERE,
                    NewRunnableMethod(this,
                                      &GeckoChildProcessHost::PerformAsyncLaunch,
                                      aExtraOpts, arch));
   // NB: this uses a different mechanism than the chromium parent
   // class.
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   PRIntervalTime waitStart = PR_IntervalNow();
   PRIntervalTime current;
 
   // We'll receive several notifications, we need to exit when we
   // have either successfully launched or have timed out.
   while (!mLaunched) {
     mon.Wait(timeoutTicks);
 
@@ -322,30 +322,30 @@ GeckoChildProcessHost::AsyncLaunch(std::
   MessageLoop* ioLoop = XRE_GetIOMessageLoop();
   ioLoop->PostTask(FROM_HERE,
                    NewRunnableMethod(this,
                                      &GeckoChildProcessHost::PerformAsyncLaunch,
                                      aExtraOpts, base::GetCurrentProcessArchitecture()));
 
   // This may look like the sync launch wait, but we only delay as
   // long as it takes to create the channel.
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   while (!mChannelInitialized) {
     mon.Wait();
   }
 
   return true;
 }
 
 void
 GeckoChildProcessHost::InitializeChannel()
 {
   CreateChannel();
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mChannelInitialized = true;
   mon.Notify();
 }
 
 PRInt32 GeckoChildProcessHost::mChildCounter = 0;
 
 //
 // Wrapper function for handling GECKO_SEPARATE_NSPR_LOGS
@@ -639,17 +639,17 @@ GeckoChildProcessHost::PerformAsyncLaunc
 #endif
 
   return true;
 }
 
 void
 GeckoChildProcessHost::OnChannelConnected(int32 peer_pid)
 {
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
   mLaunched = true;
 
   if (!base::OpenPrivilegedProcessHandle(peer_pid, &mChildProcessHandle))
       NS_RUNTIMEABORT("can't open handle to child process");
 
   mon.Notify();
 }
 
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -38,28 +38,28 @@
 #define __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
 
 #include "base/file_path.h"
 #include "base/process_util.h"
 #include "base/scoped_ptr.h"
 #include "base/waitable_event.h"
 #include "chrome/common/child_process_host.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #include "nsXULAppAPI.h"        // for GeckoProcessType
 #include "nsString.h"
 
 namespace mozilla {
 namespace ipc {
 
 class GeckoChildProcessHost : public ChildProcessHost
 {
 protected:
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
 public:
   typedef base::ProcessHandle ProcessHandle;
 
   GeckoChildProcessHost(GeckoProcessType aProcessType=GeckoProcessType_Default,
                         base::WaitableEventWatcher::Delegate* aDelegate=nsnull);
 
   ~GeckoChildProcessHost();
@@ -101,17 +101,17 @@ public:
   task_t GetChildTask() {
     return mChildTask;
   }
 #endif
 
 
 protected:
   GeckoProcessType mProcessType;
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
   bool mLaunched;
   bool mChannelInitialized;
   FilePath mProcessPath;
 
   static PRInt32 mChildCounter;
 
 #ifdef XP_WIN
   void InitWindowsGroupID();
--- a/ipc/glue/WindowsMessageLoop.cpp
+++ b/ipc/glue/WindowsMessageLoop.cpp
@@ -41,23 +41,20 @@
 #include "WindowsMessageLoop.h"
 #include "RPCChannel.h"
 
 #include "nsAutoPtr.h"
 #include "nsServiceManagerUtils.h"
 #include "nsStringGlue.h"
 #include "nsIXULAppInfo.h"
 
-#include "mozilla/Mutex.h"
 #include "mozilla/PaintTracker.h"
 
-using mozilla::ipc::SyncChannel;
-using mozilla::ipc::RPCChannel;
-using mozilla::MutexAutoUnlock;
-
+using namespace mozilla;
+using namespace mozilla::ipc;
 using namespace mozilla::ipc::windows;
 
 /**
  * The Windows-only code below exists to solve a general problem with deadlocks
  * that we experience when sending synchronous IPC messages to processes that
  * contain native windows (i.e. HWNDs). Windows (the OS) sends synchronous
  * messages between parent and child HWNDs in multiple circumstances (e.g.
  * WM_PARENTNOTIFY, WM_NCACTIVATE, etc.), even when those HWNDs are controlled
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -92,17 +92,17 @@
 #include "prmem.h"
 #include "prenv.h"
 #include "prclist.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsXPIDLString.h"
 #include "nsAutoJSValHolder.h"
 #include "mozilla/AutoRestore.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 #include "nsDataHashtable.h"
 
 #include "nsThreadUtils.h"
 #include "nsIJSContextStack.h"
 #include "nsDeque.h"
 
 #include "nsIConsoleService.h"
@@ -330,17 +330,17 @@ typedef nsDataHashtable<xpc::PtrAndPrinc
 /***************************************************************************/
 // Auto locking support class...
 
 // We PROMISE to never screw this up.
 #ifdef _MSC_VER
 #pragma warning(disable : 4355) // OK to pass "this" in member initializer
 #endif
 
-typedef mozilla::Monitor XPCLock;
+typedef mozilla::ReentrantMonitor XPCLock;
 
 static inline void xpc_Wait(XPCLock* lock) 
     {
         NS_ASSERTION(lock, "xpc_Wait called with null lock!");
         lock->Wait();
     }
 
 static inline void xpc_NotifyAll(XPCLock* lock) 
@@ -358,17 +358,17 @@ static inline void xpc_NotifyAll(XPCLock
 //
 // Note that xpconnect only makes *one* monitor and *mostly* holds it locked
 // only through very small critical sections.
 
 class NS_STACK_CLASS XPCAutoLock {
 public:
 
     static XPCLock* NewLock(const char* name)
-                        {return new mozilla::Monitor(name);}
+                        {return new mozilla::ReentrantMonitor(name);}
     static void     DestroyLock(XPCLock* lock)
                         {delete lock;}
 
     XPCAutoLock(XPCLock* lock MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM)
         : mLock(lock)
     {
         MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
         if(mLock)
--- a/modules/libpr0n/encoders/jpeg/nsJPEGEncoder.cpp
+++ b/modules/libpr0n/encoders/jpeg/nsJPEGEncoder.cpp
@@ -40,30 +40,32 @@
 #include "prmem.h"
 #include "prprf.h"
 #include "nsString.h"
 #include "nsStreamUtils.h"
 
 #include <setjmp.h>
 #include "jerror.h"
 
+using namespace mozilla;
+
 NS_IMPL_THREADSAFE_ISUPPORTS3(nsJPEGEncoder, imgIEncoder, nsIInputStream, nsIAsyncInputStream)
 
 // used to pass error info through the JPEG library
 struct encoder_error_mgr {
   jpeg_error_mgr pub;
   jmp_buf setjmp_buffer;
 };
 
 nsJPEGEncoder::nsJPEGEncoder() : mFinished(PR_FALSE),
                                  mImageBuffer(nsnull), mImageBufferSize(0),
                                  mImageBufferUsed(0), mImageBufferReadPoint(0),
                                  mCallback(nsnull),
                                  mCallbackTarget(nsnull), mNotifyThreshold(0),
-                                 mMonitor("JPEG Encoder Monitor")
+                                 mReentrantMonitor("nsJPEGEncoder.mReentrantMonitor")
 {
 }
 
 nsJPEGEncoder::~nsJPEGEncoder()
 {
   if (mImageBuffer) {
     PR_Free(mImageBuffer);
     mImageBuffer = nsnull;
@@ -263,17 +265,17 @@ NS_IMETHODIMP nsJPEGEncoder::Read(char *
 {
   return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, _retval);
 }
 
 /* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter, in voidPtr aClosure, in unsigned long aCount); */
 NS_IMETHODIMP nsJPEGEncoder::ReadSegments(nsWriteSegmentFun aWriter, void *aClosure, PRUint32 aCount, PRUint32 *_retval)
 {
   // Avoid another thread reallocing the buffer underneath us
-  mozilla::MonitorAutoEnter autoEnter(mMonitor);
+  ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
 
   PRUint32 maxCount = mImageBufferUsed - mImageBufferReadPoint;
   if (maxCount == 0) {
     *_retval = 0;
     return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
   }
 
   if (aCount > maxCount)
@@ -410,17 +412,17 @@ nsJPEGEncoder::initDestination(jpeg_comp
 boolean // static
 nsJPEGEncoder::emptyOutputBuffer(jpeg_compress_struct* cinfo)
 {
   nsJPEGEncoder* that = static_cast<nsJPEGEncoder*>(cinfo->client_data);
   NS_ASSERTION(that->mImageBuffer, "No buffer to empty!");
 
   // When we're reallocing the buffer we need to take the lock to ensure
   // that nobody is trying to read from the buffer we are destroying
-  mozilla::MonitorAutoEnter autoEnter(that->mMonitor);
+  ReentrantMonitorAutoEnter autoEnter(that->mReentrantMonitor);
 
   that->mImageBufferUsed = that->mImageBufferSize;
 
   // expand buffer, just double size each time
   that->mImageBufferSize *= 2;
 
   PRUint8* newBuf = (PRUint8*)PR_Realloc(that->mImageBuffer,
                                          that->mImageBufferSize);
@@ -489,17 +491,17 @@ nsJPEGEncoder::errorExit(jpeg_common_str
 
 void
 nsJPEGEncoder::NotifyListener()
 {
   // We might call this function on multiple threads (any threads that call
   // AsyncWait and any that do encoding) so we lock to avoid notifying the
   // listener twice about the same data (which generally leads to a truncated
   // image).
-  mozilla::MonitorAutoEnter autoEnter(mMonitor);
+  ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
 
   if (mCallback &&
       (mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
        mFinished)) {
     nsCOMPtr<nsIInputStreamCallback> callback;
     if (mCallbackTarget) {
       NS_NewInputStreamReadyEvent(getter_AddRefs(callback),
                                   mCallback,
--- a/modules/libpr0n/encoders/jpeg/nsJPEGEncoder.h
+++ b/modules/libpr0n/encoders/jpeg/nsJPEGEncoder.h
@@ -33,17 +33,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "imgIEncoder.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #include "nsCOMPtr.h"
 
 // needed for JPEG library
 #include <stdio.h>
 
 extern "C" {
 #include "jpeglib.h"
@@ -57,17 +57,17 @@ extern "C" {
     {0xb4, 0x0f, 0xbe, 0x03, 0x93, 0x2b, 0x56, 0xe0} \
 }
 
 // Provides JPEG encoding functionality. Use InitFromData() to do the
 // encoding. See that function definition for encoding options.
 
 class nsJPEGEncoder : public imgIEncoder
 {
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsJPEGEncoder();
 
@@ -102,10 +102,10 @@ protected:
   PRUint32 mNotifyThreshold;
 
   /*
     nsJPEGEncoder is designed to allow one thread to pump data into it while another
     reads from it.  We lock to ensure that the buffer remains append-only while
     we read from it (that it is not realloced) and to ensure that only one thread
     dispatches a callback for each call to AsyncWait.
    */
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 };
--- a/modules/libpr0n/encoders/png/nsPNGEncoder.cpp
+++ b/modules/libpr0n/encoders/png/nsPNGEncoder.cpp
@@ -41,26 +41,28 @@
 
 #include "nsCRT.h"
 #include "nsPNGEncoder.h"
 #include "prmem.h"
 #include "prprf.h"
 #include "nsString.h"
 #include "nsStreamUtils.h"
 
+using namespace mozilla;
+
 NS_IMPL_THREADSAFE_ISUPPORTS3(nsPNGEncoder, imgIEncoder, nsIInputStream, nsIAsyncInputStream)
 
 nsPNGEncoder::nsPNGEncoder() : mPNG(nsnull), mPNGinfo(nsnull),
                                mIsAnimation(PR_FALSE),
                                mFinished(PR_FALSE),
                                mImageBuffer(nsnull), mImageBufferSize(0),
                                mImageBufferUsed(0), mImageBufferReadPoint(0),
                                mCallback(nsnull),
                                mCallbackTarget(nsnull), mNotifyThreshold(0),
-                               mMonitor("PNG Encoder Monitor")
+                               mReentrantMonitor("nsPNGEncoder.mReentrantMonitor")
 {
 }
 
 nsPNGEncoder::~nsPNGEncoder()
 {
   if (mImageBuffer) {
     PR_Free(mImageBuffer);
     mImageBuffer = nsnull;
@@ -530,17 +532,17 @@ NS_IMETHODIMP nsPNGEncoder::Read(char * 
 /* [noscript] unsigned long readSegments (in nsWriteSegmentFun aWriter,
                                           in voidPtr aClosure,
                                           in unsigned long aCount); */
 NS_IMETHODIMP nsPNGEncoder::ReadSegments(nsWriteSegmentFun aWriter,
                                          void *aClosure, PRUint32 aCount,
                                          PRUint32 *_retval)
 {
   // Avoid another thread reallocing the buffer underneath us
-  mozilla::MonitorAutoEnter autoEnter(mMonitor);
+  ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
 
   PRUint32 maxCount = mImageBufferUsed - mImageBufferReadPoint;
   if (maxCount == 0) {
     *_retval = 0;
     return mFinished ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
   }
 
   if (aCount > maxCount)
@@ -669,17 +671,17 @@ nsPNGEncoder::WriteCallback(png_structp 
 {
   nsPNGEncoder* that = static_cast<nsPNGEncoder*>(png_get_io_ptr(png));
   if (! that->mImageBuffer)
     return;
 
   if (that->mImageBufferUsed + size > that->mImageBufferSize) {
     // When we're reallocing the buffer we need to take the lock to ensure
     // that nobody is trying to read from the buffer we are destroying
-    mozilla::MonitorAutoEnter autoEnter(that->mMonitor);
+    ReentrantMonitorAutoEnter autoEnter(that->mReentrantMonitor);
 
     // expand buffer, just double each time
     that->mImageBufferSize *= 2;
     PRUint8* newBuf = (PRUint8*)PR_Realloc(that->mImageBuffer,
                                            that->mImageBufferSize);
     if (! newBuf) {
       // can't resize, just zero (this will keep us from writing more)
       PR_Free(that->mImageBuffer);
@@ -696,17 +698,17 @@ nsPNGEncoder::WriteCallback(png_structp 
 
 void
 nsPNGEncoder::NotifyListener()
 {
   // We might call this function on multiple threads (any threads that call
   // AsyncWait and any that do encoding) so we lock to avoid notifying the
   // listener twice about the same data (which generally leads to a truncated
   // image).
-  mozilla::MonitorAutoEnter autoEnter(mMonitor);
+  ReentrantMonitorAutoEnter autoEnter(mReentrantMonitor);
 
   if (mCallback &&
       (mImageBufferUsed - mImageBufferReadPoint >= mNotifyThreshold ||
        mFinished)) {
     nsCOMPtr<nsIInputStreamCallback> callback;
     if (mCallbackTarget) {
       NS_NewInputStreamReadyEvent(getter_AddRefs(callback),
                                   mCallback,
--- a/modules/libpr0n/encoders/png/nsPNGEncoder.h
+++ b/modules/libpr0n/encoders/png/nsPNGEncoder.h
@@ -32,17 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "imgIEncoder.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #include "nsCOMPtr.h"
 
 #include <png.h>
 
 #define NS_PNGENCODER_CID \
 { /* 38d1592e-b81e-432b-86f8-471878bbfe07 */         \
      0x38d1592e,                                     \
@@ -51,17 +51,17 @@
     {0x86, 0xf8, 0x47, 0x18, 0x78, 0xbb, 0xfe, 0x07} \
 }
 
 // Provides PNG encoding functionality. Use InitFromData() to do the
 // encoding. See that function definition for encoding options.
 
 class nsPNGEncoder : public imgIEncoder
 {
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIENCODER
   NS_DECL_NSIINPUTSTREAM
   NS_DECL_NSIASYNCINPUTSTREAM
 
   nsPNGEncoder();
 
@@ -105,10 +105,10 @@ protected:
   PRUint32 mNotifyThreshold;
 
   /*
     nsPNGEncoder is designed to allow one thread to pump data into it while another
     reads from it.  We lock to ensure that the buffer remains append-only while
     we read from it (that it is not realloced) and to ensure that only one thread
     dispatches a callback for each call to AsyncWait.
    */
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 };
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -76,17 +76,17 @@ InsertTransactionSorted(nsTArray<nsHttpT
     }
     pendingQ.InsertElementAt(0, trans);
 }
 
 //-----------------------------------------------------------------------------
 
 nsHttpConnectionMgr::nsHttpConnectionMgr()
     : mRef(0)
-    , mMonitor("nsHttpConnectionMgr.mMonitor")
+    , mReentrantMonitor("nsHttpConnectionMgr.mReentrantMonitor")
     , mMaxConns(0)
     , mMaxConnsPerHost(0)
     , mMaxConnsPerProxy(0)
     , mMaxPersistConnsPerHost(0)
     , mMaxPersistConnsPerProxy(0)
     , mIsShuttingDown(PR_FALSE)
     , mNumActiveConns(0)
     , mNumIdleConns(0)
@@ -110,17 +110,17 @@ nsHttpConnectionMgr::EnsureSocketThreadT
         PRBool offline = PR_TRUE;
         ioService->GetOffline(&offline);
 
         if (!offline) {
             sts = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
         }
     }
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // do nothing if already initialized or if we've shut down
     if (mSocketThreadTarget || mIsShuttingDown)
         return NS_OK;
 
     mSocketThreadTarget = sts;
 
     return rv;
@@ -133,17 +133,17 @@ nsHttpConnectionMgr::Init(PRUint16 maxCo
                           PRUint16 maxPersistConnsPerHost,
                           PRUint16 maxPersistConnsPerProxy,
                           PRUint16 maxRequestDelay,
                           PRUint16 maxPipelinedRequests)
 {
     LOG(("nsHttpConnectionMgr::Init\n"));
 
     {
-        MonitorAutoEnter mon(mMonitor);
+        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         mMaxConns = maxConns;
         mMaxConnsPerHost = maxConnsPerHost;
         mMaxConnsPerProxy = maxConnsPerProxy;
         mMaxPersistConnsPerHost = maxPersistConnsPerHost;
         mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
         mMaxRequestDelay = maxRequestDelay;
         mMaxPipelinedRequests = maxPipelinedRequests;
@@ -154,17 +154,17 @@ nsHttpConnectionMgr::Init(PRUint16 maxCo
     return EnsureSocketThreadTargetIfOnline();
 }
 
 nsresult
 nsHttpConnectionMgr::Shutdown()
 {
     LOG(("nsHttpConnectionMgr::Shutdown\n"));
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     // do nothing if already shutdown
     if (!mSocketThreadTarget)
         return NS_OK;
 
     nsresult rv = PostEvent(&nsHttpConnectionMgr::OnMsgShutdown);
 
     // release our reference to the STS to prevent further events
@@ -187,17 +187,17 @@ nsresult
 nsHttpConnectionMgr::PostEvent(nsConnEventHandler handler, PRInt32 iparam, void *vparam)
 {
     // This object doesn't get reinitialized if the offline state changes, so our
     // socket thread target might be uninitialized if we were offline when this
     // object was being initialized, and we go online later on.  This call takes
     // care of initializing the socket thread target if that's the case.
     EnsureSocketThreadTargetIfOnline();
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     nsresult rv;
     if (!mSocketThreadTarget) {
         NS_WARNING("cannot post event if not initialized");
         rv = NS_ERROR_NOT_INITIALIZED;
     }
     else {
         nsRefPtr<nsIRunnable> event = new nsConnEvent(this, handler, iparam, vparam);
@@ -312,17 +312,17 @@ nsresult
 nsHttpConnectionMgr::GetSocketThreadTarget(nsIEventTarget **target)
 {
     // This object doesn't get reinitialized if the offline state changes, so our
     // socket thread target might be uninitialized if we were offline when this
     // object was being initialized, and we go online later on.  This call takes
     // care of initializing the socket thread target if that's the case.
     EnsureSocketThreadTargetIfOnline();
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     NS_IF_ADDREF(*target = mSocketThreadTarget);
     return NS_OK;
 }
 
 void
 nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline)
 {
     LOG(("nsHttpConnectionMgr::AddTransactionToPipeline [pipeline=%x]\n", pipeline));
@@ -915,17 +915,17 @@ nsHttpConnectionMgr::ProcessNewTransacti
 void
 nsHttpConnectionMgr::OnMsgShutdown(PRInt32, void *)
 {
     LOG(("nsHttpConnectionMgr::OnMsgShutdown\n"));
 
     mCT.Reset(ShutdownPassCB, this);
 
     // signal shutdown complete
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Notify();
 }
 
 void
 nsHttpConnectionMgr::OnMsgNewTransaction(PRInt32 priority, void *param)
 {
     LOG(("nsHttpConnectionMgr::OnMsgNewTransaction [trans=%p]\n", param));
 
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -41,17 +41,17 @@
 
 #include "nsHttpConnectionInfo.h"
 #include "nsHttpConnection.h"
 #include "nsHttpTransaction.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
 #include "nsHashtable.h"
 #include "nsAutoPtr.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsISocketTransportService.h"
 
 #include "nsIObserver.h"
 #include "nsITimer.h"
 
 class nsHttpPipeline;
 
 //-----------------------------------------------------------------------------
@@ -223,21 +223,21 @@ private:
         nsCOMPtr<nsITimer>             mSynTimer;
         nsCOMPtr<nsISocketTransport>   mBackupTransport;
         nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
         nsCOMPtr<nsIAsyncInputStream>  mBackupStreamIn;
     };
     friend class nsHalfOpenSocket;
 
     //-------------------------------------------------------------------------
-    // NOTE: these members may be accessed from any thread (use mMonitor)
+    // NOTE: these members may be accessed from any thread (use mReentrantMonitor)
     //-------------------------------------------------------------------------
 
     PRInt32                      mRef;
-    mozilla::Monitor             mMonitor;
+    mozilla::ReentrantMonitor    mReentrantMonitor;
     nsCOMPtr<nsIEventTarget>     mSocketThreadTarget;
 
     // connection limits
     PRUint16 mMaxConns;
     PRUint16 mMaxConnsPerHost;
     PRUint16 mMaxConnsPerProxy;
     PRUint16 mMaxPersistConnsPerHost;
     PRUint16 mMaxPersistConnsPerProxy;
--- a/netwerk/system/maemo/nsMaemoNetworkManager.cpp
+++ b/netwerk/system/maemo/nsMaemoNetworkManager.cpp
@@ -32,17 +32,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsMaemoNetworkManager.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
 #include <conic/conicconnection.h>
 #include <conic/conicconnectionevent.h>
 #include <conicstatisticsevent.h>
 
@@ -65,17 +65,17 @@ enum InternalState
 };
 
 static InternalState gInternalState = InternalState_Invalid;
 static ConIcConnection* gConnection = nsnull;
 static PRBool gConnectionCallbackInvoked = PR_FALSE;
 
 using namespace mozilla;
 
-static Monitor* gMonitor = nsnull;
+static ReentrantMonitor* gReentrantMonitor = nsnull;
 
 static void NotifyNetworkLinkObservers()
 {
   nsCOMPtr<nsIIOService> ioService = do_GetService("@mozilla.org/network/io-service;1");
   if (!ioService)
     return;
 
   ioService->SetOffline(gInternalState != InternalState_Connected);
@@ -83,17 +83,17 @@ static void NotifyNetworkLinkObservers()
 
 static void
 connection_event_callback(ConIcConnection *aConnection,
                           ConIcConnectionEvent *aEvent,
                           gpointer aUser_data)
 {
   ConIcConnectionStatus status = con_ic_connection_event_get_status(aEvent);
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     // When we are not connected, we are always disconnected.
     gInternalState = (CON_IC_STATUS_CONNECTED == status ?
                      InternalState_Connected : InternalState_Disconnected);
 
     gConnectionCallbackInvoked = PR_TRUE;
     mon.Notify();
   }
@@ -105,17 +105,17 @@ PRBool
 nsMaemoNetworkManager::OpenConnectionSync()
 {
   if (NS_IsMainThread() || !gConnection)
     return PR_FALSE;
 
   // protect gInternalState.  This also allows us
   // to block and wait in this method on this thread
   // until our callback on the main thread.
-  MonitorAutoEnter mon(*gMonitor);
+  ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
   gConnectionCallbackInvoked = PR_FALSE;
 
   if (!con_ic_connection_connect(gConnection,
                                  CON_IC_CONNECT_FLAG_NONE))
     g_error("openConnectionSync: Error while connecting. %p \n",
             (void*) PR_GetCurrentThread());
 
@@ -148,34 +148,34 @@ nsMaemoNetworkManager::GetLinkStatusKnow
 }
 
 PRBool
 nsMaemoNetworkManager::Startup()
 {
   if (gConnection)
     return PR_TRUE;
 
-  gMonitor = new Monitor("MaemoAutodialer");
-  if (!gMonitor)
+  gReentrantMonitor = new ReentrantMonitor("MaemoAutodialer");
+  if (!gReentrantMonitor)
     return PR_FALSE;
 
   DBusError error;
   dbus_error_init(&error);
 
   DBusConnection* dbusConnection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
   NS_ASSERTION(dbusConnection, "Error when connecting to the session bus");
 
   dbus_connection_setup_with_g_main(dbusConnection, nsnull);
 
   // grab a connection:
   gConnection = con_ic_connection_new();
   NS_ASSERTION(gConnection, "Error when creating connection");
   if (!gConnection) {
-    delete gMonitor;
-    gMonitor = nsnull;
+    delete gReentrantMonitor;
+    gReentrantMonitor = nsnull;
     return PR_FALSE;
   }
 
   g_signal_connect(G_OBJECT(gConnection),
                    "connection-event",
                    G_CALLBACK(connection_event_callback),
                    nsnull);
   
@@ -186,19 +186,19 @@ nsMaemoNetworkManager::Startup()
   return PR_TRUE;
 }
 
 void
 nsMaemoNetworkManager::Shutdown()
 {
   gConnection = nsnull;
 
-  if (gMonitor) {
+  if (gReentrantMonitor) {
     // notify anyone waiting
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
     gInternalState = InternalState_Invalid;    
     mon.Notify();
   }
   
-  // We are leaking the gMonitor because a race condition could occur. We need
+  // We are leaking the gReentrantMonitor because a race condition could occur. We need
   // a notification after xpcom-shutdown-threads so we can safely delete the monitor
 }
 
--- a/netwerk/wifi/nsWifiMonitor.cpp
+++ b/netwerk/wifi/nsWifiMonitor.cpp
@@ -60,17 +60,17 @@ PRLogModuleInfo *gWifiMonitorLog;
 
 NS_IMPL_THREADSAFE_ISUPPORTS3(nsWifiMonitor,
                               nsIRunnable,
                               nsIObserver,
                               nsIWifiMonitor)
 
 nsWifiMonitor::nsWifiMonitor()
 : mKeepGoing(PR_TRUE)
-, mMonitor("nsWifiMonitor.mMonitor")
+, mReentrantMonitor("nsWifiMonitor.mReentrantMonitor")
 {
 #if defined(PR_LOGGING)
   gWifiMonitorLog = PR_NewLogModule("WifiMonitor");
 #endif
 
   nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
   if (obsSvc)
     obsSvc->AddObserver(this, "xpcom-shutdown", PR_FALSE);
@@ -85,17 +85,17 @@ nsWifiMonitor::~nsWifiMonitor()
 NS_IMETHODIMP
 nsWifiMonitor::Observe(nsISupports *subject, const char *topic,
                      const PRUnichar *data)
 {
   if (!strcmp(topic, "xpcom-shutdown")) {
     LOG(("Shutting down\n"));
     mKeepGoing = PR_FALSE;
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Notify();
   }
   return NS_OK;
 }
 
 
 NS_IMETHODIMP nsWifiMonitor::StartWatching(nsIWifiListener *aListener)
 {
@@ -104,17 +104,17 @@ NS_IMETHODIMP nsWifiMonitor::StartWatchi
 
   nsresult rv = NS_OK;
   if (!mThread) {
     rv = NS_NewThread(getter_AddRefs(mThread), this);
     if (NS_FAILED(rv))
       return rv;
   }
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   mKeepGoing = PR_TRUE;
 
   mListeners.AppendElement(nsWifiListener(aListener));
 
   // tell ourselves that we have a new watcher.
   mon.Notify();
   return NS_OK;
@@ -122,17 +122,17 @@ NS_IMETHODIMP nsWifiMonitor::StartWatchi
 
 NS_IMETHODIMP nsWifiMonitor::StopWatching(nsIWifiListener *aListener)
 {
   if (!aListener)
     return NS_ERROR_NULL_POINTER;
 
   LOG(("removing listener\n"));
 
-  MonitorAutoEnter mon(mMonitor);
+  ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   for (PRUint32 i = 0; i < mListeners.Length(); i++) {
 
     if (mListeners[i].mListener == aListener) {
       mListeners.RemoveElementAt(i);
       break;
     }
   }
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -39,17 +39,17 @@
 
 #include "nsIWifiMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsAutoPtr.h"
 #include "nsIThread.h"
 #include "nsIRunnable.h"
 #include "nsCOMArray.h"
 #include "nsIWifiMonitor.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "prlog.h"
 #include "nsIObserver.h"
 #include "nsTArray.h"
 
 #ifndef __nsWifiMonitor__
 #define __nsWifiMonitor__
 
 #if defined(PR_LOGGING)
@@ -92,13 +92,13 @@ class nsWifiMonitor : nsIRunnable, nsIWi
   nsresult DoScanOld();
 #endif
 
   PRBool mKeepGoing;
   nsCOMPtr<nsIThread> mThread;
 
   nsTArray<nsWifiListener> mListeners;
 
-  mozilla::Monitor mMonitor;
+  mozilla::ReentrantMonitor mReentrantMonitor;
 
 };
 
 #endif
--- a/netwerk/wifi/nsWifiScannerMac.cpp
+++ b/netwerk/wifi/nsWifiScannerMac.cpp
@@ -72,17 +72,17 @@ nsWifiMonitor::DoScanWithCoreWLAN()
     nsresult rv = GetAccessPointsFromWLAN(accessPoints);
     if (NS_FAILED(rv))
       return rv;
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
     nsCOMArray<nsIWifiListener> currentListeners;
 
     {
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
       for (PRUint32 i = 0; i < mListeners.Length(); i++) {
         if (!mListeners[i].mHasSentData || accessPointsChanged) {
           mListeners[i].mHasSentData = PR_TRUE;
           currentListeners.AppendObject(mListeners[i].mListener);
         }
       }
     }
@@ -122,17 +122,17 @@ nsWifiMonitor::DoScanWithCoreWLAN()
       }
 
       nsMemory::Free(result);
     }
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
   while (mKeepGoing);
 
   return NS_OK;
 }
 
 nsresult
@@ -207,17 +207,17 @@ nsWifiMonitor::DoScanOld()
 
       accessPoints.AppendObject(ap);
     }
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
     nsCOMArray<nsIWifiListener> currentListeners;
 
     {
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
       for (PRUint32 i = 0; i < mListeners.Length(); i++) {
         if (!mListeners[i].mHasSentData || accessPointsChanged) {
           mListeners[i].mHasSentData = PR_TRUE;
           currentListeners.AppendObject(mListeners[i].mListener);
         }
       }
     }
@@ -258,17 +258,17 @@ nsWifiMonitor::DoScanOld()
       }
 
       nsMemory::Free(result);
     }
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
   while (mKeepGoing);
 
   (*WirelessDetach_function_)(wifi_context_);
 
   dlclose(apple_80211_library);
 
--- a/netwerk/wifi/nsWifiScannerUnix.cpp
+++ b/netwerk/wifi/nsWifiScannerUnix.cpp
@@ -165,17 +165,17 @@ nsWifiMonitor::DoScan()
     accessPoints.Clear();
 
     (*iw_enum)(skfd, &scan_wifi, args, 1);
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
     nsCOMArray<nsIWifiListener> currentListeners;
 
     {
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
       for (PRUint32 i = 0; i < mListeners.Length(); i++) {
         if (!mListeners[i].mHasSentData || accessPointsChanged) {
           mListeners[i].mHasSentData = PR_TRUE;
           currentListeners.AppendObject(mListeners[i].mListener);
         }
       }
     }
@@ -215,16 +215,16 @@ nsWifiMonitor::DoScan()
         }
       }
 
       nsMemory::Free(result);
     }
 
     LOG(("waiting on monitor\n"));
 
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
 
   iw_sockets_close(skfd);
 
   return NS_OK;
 }
--- a/netwerk/wifi/nsWifiScannerWin.cpp
+++ b/netwerk/wifi/nsWifiScannerWin.cpp
@@ -149,17 +149,17 @@ nsWifiMonitor::DoScan()
       // Close the handle.
       (*WlanCloseHandle)(wlan_handle, NULL);
 
 
       PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
       nsCOMArray<nsIWifiListener> currentListeners;
 
       {
-        MonitorAutoEnter mon(mMonitor);
+        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         for (PRUint32 i = 0; i < mListeners.Length(); i++) {
           if (!mListeners[i].mHasSentData || accessPointsChanged) {
             mListeners[i].mHasSentData = PR_TRUE;
             currentListeners.AppendObject(mListeners[i].mListener);
           }
         }
       }
@@ -197,15 +197,15 @@ nsWifiMonitor::DoScan()
         }
 
         nsMemory::Free(result);
       }
 
       // wait for some reasonable amount of time.  pref?
       LOG(("waiting on monitor\n"));
 
-      MonitorAutoEnter mon(mMonitor);
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       mon.Wait(PR_SecondsToInterval(60));
     }
     while (mKeepGoing);
 
     return NS_OK;
 }
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
+++ b/security/manager/boot/src/nsSecureBrowserUIImpl.cpp
@@ -155,17 +155,17 @@ class nsAutoAtomic {
     PRInt32 &mI;
 
   private:
     nsAutoAtomic(); // not accessible
 };
 #endif
 
 nsSecureBrowserUIImpl::nsSecureBrowserUIImpl()
-  : mMonitor("nsSecureBrowserUIImpl.mMonitor")
+  : mReentrantMonitor("nsSecureBrowserUIImpl.mReentrantMonitor")
   , mNotifiedSecurityState(lis_no_security)
   , mNotifiedToplevelIsEV(PR_FALSE)
   , mNewToplevelSecurityState(STATE_IS_INSECURE)
   , mNewToplevelIsEV(PR_FALSE)
   , mNewToplevelSecurityStateKnown(PR_TRUE)
   , mIsViewSource(PR_FALSE)
   , mSubRequestsHighSecurity(0)
   , mSubRequestsLowSecurity(0)
@@ -272,17 +272,17 @@ nsSecureBrowserUIImpl::Init(nsIDOMWindow
 
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSecureBrowserUIImpl::GetState(PRUint32* aState)
 {
-  MonitorAutoEnter lock(mMonitor);
+  ReentrantMonitorAutoEnter lock(mReentrantMonitor);
   return MapInternalToExternalState(aState, mNotifiedSecurityState, mNotifiedToplevelIsEV);
 }
 
 // static
 already_AddRefed<nsISupports> 
 nsSecureBrowserUIImpl::ExtractSecurityInfo(nsIRequest* aRequest)
 {
   nsISupports *retval = nsnull; 
@@ -336,17 +336,17 @@ nsSecureBrowserUIImpl::MapInternalToExte
 
 NS_IMETHODIMP
 nsSecureBrowserUIImpl::GetTooltipText(nsAString& aText)
 {
   lockIconState state;
   nsXPIDLString tooltip;
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     state = mNotifiedSecurityState;
     tooltip = mInfoTooltip;
   }
 
   if (state == lis_mixed_security)
   {
     GetBundleString(NS_LITERAL_STRING("SecurityButtonMixedContentTooltipText").get(),
                     aText);
@@ -455,17 +455,17 @@ nsSecureBrowserUIImpl::Notify(nsIDOMHTML
   {
     NS_WARNING("If you see this and can explain why it should be allowed, note in Bug 332324");
     *cancelSubmit = PR_TRUE;
     return NS_OK;
   }
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   PRBool isChild;
   IsChildOfDomWindow(window, postingWindow, &isChild);
   
   // This notify call is not for our window, ignore it.
@@ -491,17 +491,17 @@ nsSecureBrowserUIImpl::OnProgressChange(
                                         PRInt32 aMaxTotalProgress)
 {
   NS_NOTREACHED("notification excluded in AddProgressListener(...)");
   return NS_OK;
 }
 
 void nsSecureBrowserUIImpl::ResetStateTracking()
 {
-  MonitorAutoEnter lock(mMonitor);
+  ReentrantMonitorAutoEnter lock(mReentrantMonitor);
 
   mInfoTooltip.Truncate();
   mDocumentRequestsInProgress = 0;
   if (mTransferringRequests.ops) {
     PL_DHashTableFinish(&mTransferringRequests);
     mTransferringRequests.ops = nsnull;
   }
   PL_DHashTableInit(&mTransferringRequests, &gMapOps, nsnull,
@@ -553,17 +553,17 @@ nsSecureBrowserUIImpl::EvaluateAndUpdate
         }
       }
     }
 
   // assume temp_NewToplevelSecurityState was set in this scope!
   // see code that is directly above
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     mNewToplevelSecurityStateKnown = PR_TRUE;
     mNewToplevelSecurityState = temp_NewToplevelSecurityState;
     mNewToplevelIsEV = temp_NewToplevelIsEV;
     if (updateStatus) {
       mSSLStatus = temp_SSLStatus;
     }
     if (updateTooltip) {
       mInfoTooltip = temp_InfoTooltip;
@@ -586,17 +586,17 @@ nsSecureBrowserUIImpl::EvaluateAndUpdate
 void
 nsSecureBrowserUIImpl::UpdateSubrequestMembers(nsISupports *securityInfo)
 {
   // For wyciwyg channels in subdocuments we only update our
   // subrequest state members.
   PRUint32 reqState = GetSecurityStateFromSecurityInfo(securityInfo);
 
   // the code above this line should run without a lock
-  MonitorAutoEnter lock(mMonitor);
+  ReentrantMonitorAutoEnter lock(mReentrantMonitor);
 
   if (reqState & STATE_IS_SECURE) {
     if (reqState & STATE_SECURE_LOW || reqState & STATE_SECURE_MED) {
       PR_LOG(gSecureDocLog, PR_LOG_DEBUG,
              ("SecureUI:%p: OnStateChange: subreq LOW\n", this));
       ++mSubRequestsLowSecurity;
     } else {
       PR_LOG(gSecureDocLog, PR_LOG_DEBUG,
@@ -719,29 +719,29 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
   aWebProgress->GetDOMWindow(getter_AddRefs(windowForProgress));
 
   nsCOMPtr<nsIDOMWindow> window;
   PRBool isViewSource;
 
   nsCOMPtr<nsINetUtil> ioService;
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
     isViewSource = mIsViewSource;
     ioService = mIOService;
   }
 
   if (!ioService)
   {
     ioService = do_GetService(NS_IOSERVICE_CONTRACTID);
     if (ioService)
     {
-      MonitorAutoEnter lock(mMonitor);
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
       mIOService = ioService;
     }
   }
 
   PRBool isNoContentResponse = PR_FALSE;
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aRequest);
   if (httpChannel) 
   {
@@ -1008,30 +1008,30 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
 
   if (aProgressStateFlags & STATE_TRANSFERRING
       &&
       aProgressStateFlags & STATE_IS_REQUEST)
   {
     // The listing of a request in mTransferringRequests
     // means, there has already been data transfered.
 
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_ADD);
     
     return NS_OK;
   }
 
   PRBool requestHasTransferedData = PR_FALSE;
 
   if (aProgressStateFlags & STATE_STOP
       &&
       aProgressStateFlags & STATE_IS_REQUEST)
   {
-    { /* scope for the MonitorAutoEnter */
-      MonitorAutoEnter lock(mMonitor);
+    { /* scope for the ReentrantMonitorAutoEnter */
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
       PLDHashEntryHdr *entry = PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_LOOKUP);
       if (PL_DHASH_ENTRY_IS_BUSY(entry))
       {
         PL_DHashTableOperate(&mTransferringRequests, aRequest, PL_DHASH_REMOVE);
 
         requestHasTransferedData = PR_TRUE;
       }
     }
@@ -1079,17 +1079,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
     nsCOMPtr<nsIAssociatedContentSecurity> prevContentSecurity;
 
     PRInt32 newSubHigh = 0;
     PRInt32 newSubLow = 0;
     PRInt32 newSubBroken = 0;
     PRInt32 newSubNo = 0;
 
     {
-      MonitorAutoEnter lock(mMonitor);
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
       inProgress = (mDocumentRequestsInProgress!=0);
 
       if (allowSecurityStateChange && !inProgress)
       {
         saveSubHigh = mSubRequestsHighSecurity;
         saveSubLow = mSubRequestsLowSecurity;
         saveSubBroken = mSubRequestsBrokenSecurity;
         saveSubNo = mSubRequestsNoSecurity;
@@ -1149,17 +1149,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
           newContentSecurity->GetCountSubRequestsLowSecurity(&newSubLow);
           newContentSecurity->GetCountSubRequestsBrokenSecurity(&newSubBroken);
           newContentSecurity->GetCountSubRequestsNoSecurity(&newSubNo);
         }
       }
     }
 
     {
-      MonitorAutoEnter lock(mMonitor);
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
 
       if (allowSecurityStateChange && !inProgress)
       {
         ResetStateTracking();
         mSubRequestsHighSecurity = newSubHigh;
         mSubRequestsLowSecurity = newSubLow;
         mSubRequestsBrokenSecurity = newSubBroken;
         mSubRequestsNoSecurity = newSubNo;
@@ -1185,17 +1185,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
       isToplevelProgress
       &&
       loadFlags & nsIChannel::LOAD_DOCUMENT_URI)
   {
     PRInt32 temp_DocumentRequestsInProgress;
     nsCOMPtr<nsISecurityEventSink> temp_ToplevelEventSink;
 
     {
-      MonitorAutoEnter lock(mMonitor);
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
       temp_DocumentRequestsInProgress = mDocumentRequestsInProgress;
       if (allowSecurityStateChange)
       {
         temp_ToplevelEventSink = mToplevelEventSink;
       }
     }
 
     if (temp_DocumentRequestsInProgress <= 0)
@@ -1213,17 +1213,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
     {
       if (allowSecurityStateChange)
       {
         ObtainEventSink(channel, temp_ToplevelEventSink);
       }
     }
 
     {
-      MonitorAutoEnter lock(mMonitor);
+      ReentrantMonitorAutoEnter lock(mReentrantMonitor);
       if (allowSecurityStateChange)
       {
         mToplevelEventSink = temp_ToplevelEventSink;
       }
       --mDocumentRequestsInProgress;
     }
 
     if (allowSecurityStateChange && requestHasTransferedData) {
@@ -1258,17 +1258,17 @@ nsSecureBrowserUIImpl::OnStateChange(nsI
       // At this point, we are learning about the security state of a sub-document.
       // We must not update the security state based on the sub content,
       // if the new top level state is not yet known.
       //
       // We skip updating the security state in this case.
 
       PRBool temp_NewToplevelSecurityStateKnown;
       {
-        MonitorAutoEnter lock(mMonitor);
+        ReentrantMonitorAutoEnter lock(mReentrantMonitor);
         temp_NewToplevelSecurityStateKnown = mNewToplevelSecurityStateKnown;
       }
 
       if (temp_NewToplevelSecurityStateKnown)
         return UpdateSecurityState(aRequest, PR_FALSE, PR_FALSE, PR_FALSE);
     }
 
     return NS_OK;
@@ -1304,17 +1304,17 @@ nsresult nsSecureBrowserUIImpl::UpdateSe
   return rv;
 }
 
 // must not fail, by definition, only trivial assignments
 // or string operations are allowed
 // returns true if our overall state has changed and we must send out notifications
 PRBool nsSecureBrowserUIImpl::UpdateMyFlags(PRBool &showWarning, lockIconState &warnSecurityState)
 {
-  MonitorAutoEnter lock(mMonitor);
+  ReentrantMonitorAutoEnter lock(mReentrantMonitor);
   PRBool mustTellTheWorld = PR_FALSE;
 
   lockIconState newSecurityState;
 
   if (mNewToplevelSecurityState & STATE_IS_SECURE)
   {
     if (mNewToplevelSecurityState & STATE_SECURE_LOW
         ||
@@ -1454,17 +1454,17 @@ nsresult nsSecureBrowserUIImpl::TellTheW
                                              lockIconState warnSecurityState, 
                                              nsIRequest* aRequest)
 {
   nsCOMPtr<nsISecurityEventSink> temp_ToplevelEventSink;
   lockIconState temp_NotifiedSecurityState;
   PRBool temp_NotifiedToplevelIsEV;
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     temp_ToplevelEventSink = mToplevelEventSink;
     temp_NotifiedSecurityState = mNotifiedSecurityState;
     temp_NotifiedToplevelIsEV = mNotifiedToplevelIsEV;
   }
 
   if (temp_ToplevelEventSink)
   {
     PRUint32 newState = STATE_IS_INSECURE;
@@ -1541,17 +1541,17 @@ nsSecureBrowserUIImpl::OnLocationChange(
              ("SecureUI:%p: OnLocationChange: view-source\n", this));
     }
 
     updateIsViewSource = PR_TRUE;
     temp_IsViewSource = vs;
   }
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     if (updateIsViewSource) {
       mIsViewSource = temp_IsViewSource;
     }
     mCurrentURI = aLocation;
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
@@ -1589,17 +1589,17 @@ nsSecureBrowserUIImpl::OnLocationChange(
   // At this point, we are learning about the security state of a sub-document.
   // We must not update the security state based on the sub content, if the new
   // top level state is not yet known.
   //
   // We skip updating the security state in this case.
 
   PRBool temp_NewToplevelSecurityStateKnown;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     temp_NewToplevelSecurityStateKnown = mNewToplevelSecurityStateKnown;
   }
 
   if (temp_NewToplevelSecurityStateKnown)
     return UpdateSecurityState(aRequest, PR_TRUE, PR_FALSE, PR_FALSE);
 
   return NS_OK;
 }
@@ -1640,17 +1640,17 @@ nsSecureBrowserUIImpl::OnSecurityChange(
 }
 
 // nsISSLStatusProvider methods
 NS_IMETHODIMP
 nsSecureBrowserUIImpl::GetSSLStatus(nsISupports** _result)
 {
   NS_ENSURE_ARG_POINTER(_result);
 
-  MonitorAutoEnter lock(mMonitor);
+  ReentrantMonitorAutoEnter lock(mReentrantMonitor);
 
   switch (mNotifiedSecurityState)
   {
     case lis_mixed_security:
     case lis_low_security:
     case lis_high_security:
       break;
 
@@ -1692,17 +1692,17 @@ nsSecureBrowserUIImpl::IsURLJavaScript(n
 
 void
 nsSecureBrowserUIImpl::GetBundleString(const PRUnichar* name,
                                        nsAString &outString)
 {
   nsCOMPtr<nsIStringBundle> temp_StringBundle;
 
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     temp_StringBundle = mStringBundle;
   }
 
   if (temp_StringBundle && name) {
     PRUnichar *ptrv = nsnull;
     if (NS_SUCCEEDED(temp_StringBundle->GetStringFromName(name,
                                                           &ptrv)))
       outString = ptrv;
@@ -1836,17 +1836,17 @@ ConfirmEnteringSecure()
 {
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool confirms;
   dialogs->ConfirmEnteringSecure(ctx, &confirms);
@@ -1859,17 +1859,17 @@ ConfirmEnteringWeak()
 {
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool confirms;
   dialogs->ConfirmEnteringWeak(ctx, &confirms);
@@ -1882,17 +1882,17 @@ ConfirmLeavingSecure()
 {
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool confirms;
   dialogs->ConfirmLeavingSecure(ctx, &confirms);
@@ -1905,17 +1905,17 @@ ConfirmMixedMode()
 {
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool confirms;
   dialogs->ConfirmMixedMode(ctx, &confirms);
@@ -1935,17 +1935,17 @@ ConfirmPostToInsecure()
 
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool result;
 
@@ -1967,17 +1967,17 @@ ConfirmPostToInsecureFromSecure()
 
   nsCOMPtr<nsISecurityWarningDialogs> dialogs;
 
   GetNSSDialogs(getter_AddRefs(dialogs));
   if (!dialogs) return PR_FALSE;  // Should this allow PR_TRUE for unimplemented?
 
   nsCOMPtr<nsIDOMWindow> window;
   {
-    MonitorAutoEnter lock(mMonitor);
+    ReentrantMonitorAutoEnter lock(mReentrantMonitor);
     window = do_QueryReferent(mWindow);
     NS_ASSERTION(window, "Window has gone away?!");
   }
 
   nsCOMPtr<nsIInterfaceRequestor> ctx = new nsUIContext(window);
 
   PRBool result;
 
--- a/security/manager/boot/src/nsSecureBrowserUIImpl.h
+++ b/security/manager/boot/src/nsSecureBrowserUIImpl.h
@@ -37,17 +37,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsSecureBrowserUIImpl_h_
 #define nsSecureBrowserUIImpl_h_
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsCOMPtr.h"
 #include "nsXPIDLString.h"
 #include "nsString.h"
 #include "nsIObserver.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIStringBundle.h"
@@ -92,17 +92,17 @@ public:
   NS_DECL_NSISSLSTATUSPROVIDER
 
   NS_IMETHOD Notify(nsIDOMHTMLFormElement* formNode, nsIDOMWindowInternal* window,
                     nsIURI *actionURL, PRBool* cancelSubmit);
   NS_IMETHOD NotifyInvalidSubmit(nsIDOMHTMLFormElement* formNode,
                                  nsIArray* invalidElements) { return NS_OK; };
   
 protected:
-  mozilla::Monitor mMonitor;
+  mozilla::ReentrantMonitor mReentrantMonitor;
   
   nsWeakPtr mWindow;
   nsCOMPtr<nsINetUtil> mIOService;
   nsCOMPtr<nsIStringBundle> mStringBundle;
   nsCOMPtr<nsIURI> mCurrentURI;
   nsCOMPtr<nsISecurityEventSink> mToplevelEventSink;
   
   enum lockIconState {
@@ -124,17 +124,17 @@ protected:
 
   nsXPIDLString mInfoTooltip;
   PRInt32 mDocumentRequestsInProgress;
   PRInt32 mSubRequestsHighSecurity;
   PRInt32 mSubRequestsLowSecurity;
   PRInt32 mSubRequestsBrokenSecurity;
   PRInt32 mSubRequestsNoSecurity;
 #ifdef DEBUG
-  /* related to mMonitor */
+  /* related to mReentrantMonitor */
   PRInt32 mOnStateLocationChangeReentranceDetection;
 #endif
 
   static already_AddRefed<nsISupports> ExtractSecurityInfo(nsIRequest* aRequest);
   static nsresult MapInternalToExternalState(PRUint32* aState, lockIconState lock, PRBool ev);
   nsresult UpdateSecurityState(nsIRequest* aRequest, PRBool withNewLocation,
                                PRBool withUpdateStatus, PRBool withUpdateTooltip);
   PRBool UpdateMyFlags(PRBool &showWarning, lockIconState &warnSecurityState);
--- a/security/manager/ssl/src/nsCertOverrideService.cpp
+++ b/security/manager/ssl/src/nsCertOverrideService.cpp
@@ -174,50 +174,50 @@ nsCertOverrideService::Observe(nsISuppor
                                const char      *aTopic,
                                const PRUnichar *aData)
 {
   // check the topic
   if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     // The profile is about to change,
     // or is going away because the application is shutting down.
 
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
 
     if (!nsCRT::strcmp(aData, NS_LITERAL_STRING("shutdown-cleanse").get())) {
       RemoveAllFromMemory();
       // delete the storage file
       if (mSettingsFile) {
         mSettingsFile->Remove(PR_FALSE);
       }
     } else {
       RemoveAllFromMemory();
     }
 
   } else if (!nsCRT::strcmp(aTopic, "profile-do-change")) {
     // The profile has already changed.
     // Now read from the new profile location.
     // we also need to update the cached file location
 
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
 
     nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(mSettingsFile));
     if (NS_SUCCEEDED(rv)) {
       mSettingsFile->AppendNative(NS_LITERAL_CSTRING(kCertOverrideFileName));
     }
     Read();
 
   }
 
   return NS_OK;
 }
 
 void
 nsCertOverrideService::RemoveAllFromMemory()
 {
-  MonitorAutoEnter lock(monitor);
+  ReentrantMonitorAutoEnter lock(monitor);
   mSettingsTable.Clear();
 }
 
 PR_STATIC_CALLBACK(PLDHashOperator)
 RemoveTemporariesCallback(nsCertOverrideEntry *aEntry,
                           void *aArg)
 {
   if (aEntry && aEntry->mSettings.mIsTemporary) {
@@ -227,26 +227,26 @@ RemoveTemporariesCallback(nsCertOverride
 
   return PL_DHASH_NEXT;
 }
 
 void
 nsCertOverrideService::RemoveAllTemporaryOverrides()
 {
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     mSettingsTable.EnumerateEntries(RemoveTemporariesCallback, nsnull);
     // no need to write, as temporaries are never written to disk
   }
 }
 
 nsresult
 nsCertOverrideService::Read()
 {
-  MonitorAutoEnter lock(monitor);
+  ReentrantMonitorAutoEnter lock(monitor);
 
   nsresult rv;
   nsCOMPtr<nsIInputStream> fileInputStream;
   rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), mSettingsFile);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
@@ -355,17 +355,17 @@ WriteEntryCallback(nsCertOverrideEntry *
   }
 
   return PL_DHASH_NEXT;
 }
 
 nsresult
 nsCertOverrideService::Write()
 {
-  MonitorAutoEnter lock(monitor);
+  ReentrantMonitorAutoEnter lock(monitor);
 
   if (!mSettingsFile) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsresult rv;
   nsCOMPtr<nsIOutputStream> fileOutputStream;
   rv = NS_NewSafeLocalFileOutputStream(getter_AddRefs(fileOutputStream),
@@ -549,17 +549,17 @@ nsCertOverrideService::RememberValidityO
       ++dbkey_walk) {
     char c = *dbkey_walk;
     if (c == '\r' || c == '\n') {
       *dbkey_walk = ' ';
     }
   }
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     AddEntryToList(aHostName, aPort,
                    aTemporary ? aCert : nsnull,
                      // keep a reference to the cert for temporary overrides
                    aTemporary, 
                    mDottedOidForStoringNewHashes, fpStr, 
                    (nsCertOverride::OverrideBits)aOverrideBits, 
                    nsDependentCString(dbkey));
     Write();
@@ -588,17 +588,17 @@ nsCertOverrideService::HasMatchingOverri
   *_retval = PR_FALSE;
   *aOverrideBits = nsCertOverride::ob_None;
 
   nsCAutoString hostPort;
   GetHostWithPort(aHostName, aPort, hostPort);
   nsCertOverride settings;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     nsCertOverrideEntry *entry = mSettingsTable.GetEntry(hostPort.get());
   
     if (!entry)
       return NS_OK;
   
     settings = entry->mSettings; // copy
   }
 
@@ -635,17 +635,17 @@ nsCertOverrideService::GetValidityOverri
   *_found = PR_FALSE;
   *aOverrideBits = nsCertOverride::ob_None;
 
   nsCAutoString hostPort;
   GetHostWithPort(aHostName, aPort, hostPort);
   nsCertOverride settings;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     nsCertOverrideEntry *entry = mSettingsTable.GetEntry(hostPort.get());
   
     if (entry) {
       *_found = PR_TRUE;
       settings = entry->mSettings; // copy
     }
   }
 
@@ -667,17 +667,17 @@ nsCertOverrideService::AddEntryToList(co
                                       const nsACString &fingerprint,
                                       nsCertOverride::OverrideBits ob,
                                       const nsACString &dbKey)
 {
   nsCAutoString hostPort;
   GetHostWithPort(aHostName, aPort, hostPort);
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     nsCertOverrideEntry *entry = mSettingsTable.PutEntry(hostPort.get());
 
     if (!entry) {
       NS_ERROR("can't insert a null entry!");
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     entry->mHostWithPort = hostPort;
@@ -702,17 +702,17 @@ nsCertOverrideService::ClearValidityOver
   if (aPort == 0 &&
       aHostName.EqualsLiteral("all:temporary-certificates")) {
     RemoveAllTemporaryOverrides();
     return NS_OK;
   }
   nsCAutoString hostPort;
   GetHostWithPort(aHostName, aPort, hostPort);
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     mSettingsTable.RemoveEntry(hostPort.get());
     Write();
   }
   SSL_ClearSessionCache();
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -832,17 +832,17 @@ nsCertOverrideService::IsCertUsedForOver
   cai.cert = aCert;
   cai.aCheckTemporaries = aCheckTemporaries;
   cai.aCheckPermanents = aCheckPermanents;
   cai.counter = 0;
   cai.mOidTagForStoringNewHashes = mOidTagForStoringNewHashes;
   cai.mDottedOidForStoringNewHashes = mDottedOidForStoringNewHashes;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     mSettingsTable.EnumerateEntries(FindMatchingCertCallback, &cai);
   }
   *_retval = cai.counter;
   return NS_OK;
 }
 
 struct nsCertAndPointerAndCallback
 {
@@ -898,17 +898,17 @@ nsCertOverrideService::EnumerateCertOver
   nsCertAndPointerAndCallback capac;
   capac.cert = aCert;
   capac.userdata = aUserData;
   capac.enumerator = enumerator;
   capac.mOidTagForStoringNewHashes = mOidTagForStoringNewHashes;
   capac.mDottedOidForStoringNewHashes = mDottedOidForStoringNewHashes;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     mSettingsTable.EnumerateEntries(EnumerateCertOverridesCallback, &capac);
   }
   return NS_OK;
 }
 
 void
 nsCertOverrideService::GetHostWithPort(const nsACString & aHostName, PRInt32 aPort, nsACString& _retval)
 {
--- a/security/manager/ssl/src/nsCertOverrideService.h
+++ b/security/manager/ssl/src/nsCertOverrideService.h
@@ -36,17 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NSCERTOVERRIDESERVICE_H__
 #define __NSCERTOVERRIDESERVICE_H__
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsICertOverrideService.h"
 #include "nsTHashtable.h"
 #include "nsIObserver.h"
 #include "nsString.h"
 #include "nsIFile.h"
 #include "secoidt.h"
 #include "nsWeakReference.h"
 
@@ -185,17 +185,17 @@ public:
                                   void *aUserData);
 
     // Concates host name and the port number. If the port number is -1 then
     // port 443 is automatically used. This method ensures there is always a port
     // number separated with colon.
     static void GetHostWithPort(const nsACString & aHostName, PRInt32 aPort, nsACString& _retval);
 
 protected:
-    mozilla::Monitor monitor;
+    mozilla::ReentrantMonitor monitor;
     nsCOMPtr<nsIFile> mSettingsFile;
     nsTHashtable<nsCertOverrideEntry> mSettingsTable;
 
     SECOidTag mOidTagForStoringNewHashes;
     nsCString mDottedOidForStoringNewHashes;
 
     void RemoveAllFromMemory();
     nsresult Read();
--- a/security/manager/ssl/src/nsClientAuthRemember.cpp
+++ b/security/manager/ssl/src/nsClientAuthRemember.cpp
@@ -105,26 +105,26 @@ nsClientAuthRememberService::Observe(nsI
                                const char      *aTopic,
                                const PRUnichar *aData)
 {
   // check the topic
   if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
     // The profile is about to change,
     // or is going away because the application is shutting down.
 
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     RemoveAllFromMemory();
   }
 
   return NS_OK;
 }
 
 void nsClientAuthRememberService::ClearRememberedDecisions()
 {
-  MonitorAutoEnter lock(monitor);
+  ReentrantMonitorAutoEnter lock(monitor);
   RemoveAllFromMemory();
 }
 
 void
 nsClientAuthRememberService::RemoveAllFromMemory()
 {
   mSettingsTable.Clear();
 }
@@ -160,17 +160,17 @@ nsClientAuthRememberService::RememberDec
     return NS_ERROR_INVALID_ARG;
 
   nsCAutoString fpStr;
   nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr);
   if (NS_FAILED(rv))
     return rv;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     if (aClientCert) {
       nsNSSCertificate pipCert(aClientCert);
       char *dbkey = NULL;
       rv = pipCert.GetDbKey(&dbkey);
       if (NS_SUCCEEDED(rv) && dbkey) {
         AddEntryToList(aHostName, fpStr, 
                        nsDependentCString(dbkey));
       }
@@ -206,17 +206,17 @@ nsClientAuthRememberService::HasRemember
   if (NS_FAILED(rv))
     return rv;
 
   nsCAutoString hostCert;
   GetHostWithCert(aHostName, fpStr, hostCert);
   nsClientAuthRemember settings;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get());
     if (!entry)
       return NS_OK;
     settings = entry->mSettings; // copy
   }
 
   aCertDBKey = settings.mDBKey;
   *_retval = PR_TRUE;
@@ -228,17 +228,17 @@ nsClientAuthRememberService::AddEntryToL
                                       const nsACString &fingerprint,
                                       const nsACString &db_key)
 
 {
   nsCAutoString hostCert;
   GetHostWithCert(aHostName, fingerprint, hostCert);
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get());
 
     if (!entry) {
       NS_ERROR("can't insert a null entry!");
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     entry->mHostWithCert = hostCert;
--- a/security/manager/ssl/src/nsClientAuthRemember.h
+++ b/security/manager/ssl/src/nsClientAuthRemember.h
@@ -35,17 +35,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __NSCLIENTAUTHREMEMBER_H__
 #define __NSCLIENTAUTHREMEMBER_H__
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsTHashtable.h"
 #include "nsIObserver.h"
 #include "nsIX509Cert.h"
 #include "nsAutoPtr.h"
 #include "nsNSSCertificate.h"
 #include "nsString.h"
 #include "nsWeakReference.h"
 
@@ -158,17 +158,17 @@ public:
                             CERTCertificate *aServerCert, CERTCertificate *aClientCert);
   nsresult HasRememberedDecision(const nsACString & aHostName, 
                                  CERTCertificate *aServerCert, 
                                  nsACString & aCertDBKey, PRBool *_retval);
 
   void ClearRememberedDecisions();
 
 protected:
-    mozilla::Monitor monitor;
+    mozilla::ReentrantMonitor monitor;
     nsTHashtable<nsClientAuthRememberEntry> mSettingsTable;
 
     void RemoveAllFromMemory();
     nsresult AddEntryToList(const nsACString &host, 
                             const nsACString &server_fingerprint,
                             const nsACString &db_key);
 };
 
--- a/security/manager/ssl/src/nsRecentBadCerts.cpp
+++ b/security/manager/ssl/src/nsRecentBadCerts.cpp
@@ -94,17 +94,17 @@ nsRecentBadCertsService::GetRecentBadCer
   foundDER.len = 0;
   foundDER.data = nsnull;
 
   PRBool isDomainMismatch = PR_FALSE;
   PRBool isNotValidAtThisTime = PR_FALSE;
   PRBool isUntrusted = PR_FALSE;
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     for (size_t i=0; i<const_recently_seen_list_size; ++i) {
       if (mCerts[i].mHostWithPort.Equals(aHostNameWithPort)) {
         SECStatus srv = SECITEM_CopyItem(nsnull, &foundDER, &mCerts[i].mDERCert);
         if (srv != SECSuccess)
           return NS_ERROR_OUT_OF_MEMORY;
 
         isDomainMismatch = mCerts[i].isDomainMismatch;
         isNotValidAtThisTime = mCerts[i].isNotValidAtThisTime;
@@ -167,17 +167,17 @@ nsRecentBadCertsService::AddBadCert(cons
   rv = aStatus->GetIsUntrusted(&isUntrusted);
   NS_ENSURE_SUCCESS(rv, rv);
 
   SECItem tempItem;
   rv = cert->GetRawDER(&tempItem.len, (PRUint8 **)&tempItem.data);
   NS_ENSURE_SUCCESS(rv, rv);
 
   {
-    MonitorAutoEnter lock(monitor);
+    ReentrantMonitorAutoEnter lock(monitor);
     RecentBadCert &updatedEntry = mCerts[mNextStorePosition];
 
     ++mNextStorePosition;
     if (mNextStorePosition == const_recently_seen_list_size)
       mNextStorePosition = 0;
 
     updatedEntry.Clear();
     updatedEntry.mHostWithPort = hostWithPort;
--- a/security/manager/ssl/src/nsRecentBadCerts.h
+++ b/security/manager/ssl/src/nsRecentBadCerts.h
@@ -35,17 +35,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef __RECENTBADCERTS_H__
 #define __RECENTBADCERTS_H__
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsIRecentBadCertsService.h"
 #include "nsTHashtable.h"
 #include "nsString.h"
 #include "secitem.h"
 
 class RecentBadCert
 {
 public:
@@ -100,17 +100,17 @@ public:
   NS_DECL_NSIRECENTBADCERTSSERVICE
 
   nsRecentBadCertsService();
   ~nsRecentBadCertsService();
 
   nsresult Init();
 
 protected:
-    mozilla::Monitor monitor;
+    mozilla::ReentrantMonitor monitor;
 
     enum {const_recently_seen_list_size = 5};
     RecentBadCert mCerts[const_recently_seen_list_size];
 
     // will be in the range of 0 to list_size-1
     PRUint32 mNextStorePosition;
 };
 
--- a/storage/test/test_deadlock_detector.cpp
+++ b/storage/test/test_deadlock_detector.cpp
@@ -45,17 +45,17 @@
 #include "prenv.h"
 #include "prerror.h"
 #include "prio.h"
 #include "prproces.h"
 
 #include "nsMemory.h"
 
 #include "mozilla/CondVar.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "SQLiteMutex.h"
 
 #include "TestHarness.h"
 
 using namespace mozilla;
 
 /**
  * Helper class to allocate a sqlite3_mutex for our SQLiteMutex.  Also makes
@@ -426,33 +426,33 @@ Sanity3()
         FAIL("deadlock not detected");
     }
 }
 
 
 nsresult
 Sanity4_Child()
 {
-    mozilla::Monitor m1("dd.sanity4.m1");
+    mozilla::ReentrantMonitor m1("dd.sanity4.m1");
     TestMutex m2("dd.sanity4.m2");
     m1.Enter();
     m2.Lock();
     m1.Enter();
     return 0;
 }
 
 nsresult
 Sanity4()
 {
     const char* const tokens[] = {
-        "Re-entering Monitor after acquiring other resources",
+        "Re-entering ReentrantMonitor after acquiring other resources",
         "###!!! ERROR: Potential deadlock detected",
-        "=== Cyclical dependency starts at\n--- Monitor : dd.sanity4.m1",
+        "=== Cyclical dependency starts at\n--- ReentrantMonitor : dd.sanity4.m1",
         "--- Next dependency:\n--- Mutex : dd.sanity4.m2",
-        "=== Cycle completed at\n--- Monitor : dd.sanity4.m1",
+        "=== Cycle completed at\n--- ReentrantMonitor : dd.sanity4.m1",
         "###!!! ASSERTION: Potential deadlock detected",
         0
     };
     if (CheckForDeadlock("Sanity4", tokens)) {
         PASS();
     } else {
         FAIL("deadlock not detected");
     }
--- a/storage/test/test_service_init_background_thread.cpp
+++ b/storage/test/test_service_init_background_thread.cpp
@@ -34,17 +34,16 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "storage_test_harness.h"
 
-#include "mozilla/Monitor.h"
 #include "nsThreadUtils.h"
 
 /**
  * This file tests that the storage service can be initialized off of the main
  * thread without issue.
  */
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/storage/test/test_true_async.cpp
+++ b/storage/test/test_true_async.cpp
@@ -38,20 +38,20 @@
 
 #include "storage_test_harness.h"
 #include "prthread.h"
 #include "nsIEventTarget.h"
 #include "nsIInterfaceRequestorUtils.h"
 
 #include "sqlite3.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 
-using mozilla::Monitor;
-using mozilla::MonitorAutoEnter;
+using mozilla::ReentrantMonitor;
+using mozilla::ReentrantMonitorAutoEnter;
 
 /**
  * Verify that mozIStorageAsyncStatement's life-cycle never triggers a mutex on
  * the caller (generally main) thread.  We do this by decorating the sqlite
  * mutex logic with our own code that checks what thread it is being invoked on
  * and sets a flag if it is invoked on the main thread.  We are able to easily
  * decorate the SQLite mutex logic because SQLite allows us to retrieve the
  * current function pointers being used and then provide a new set.
@@ -135,41 +135,41 @@ void watch_for_mutex_use_on_this_thread(
  * runnables dispatched to the thread will execute until you invoke unwedge.
  *
  * The wedger is self-dispatching, just construct it with its target.
  */
 class ThreadWedger : public nsRunnable
 {
 public:
   ThreadWedger(nsIEventTarget *aTarget)
-  : mMonitor("thread wedger")
+  : mReentrantMonitor("thread wedger")
   , unwedged(false)
   {
     aTarget->Dispatch(this, aTarget->NS_DISPATCH_NORMAL);
   }
 
   NS_IMETHOD Run()
   {
-    MonitorAutoEnter automon(mMonitor);
+    ReentrantMonitorAutoEnter automon(mReentrantMonitor);
 
     if (!unwedged)
       automon.Wait();
 
     return NS_OK;
   }
 
   void unwedge()
   {
-    MonitorAutoEnter automon(mMonitor);
+    ReentrantMonitorAutoEnter automon(mReentrantMonitor);
     unwedged = true;
     automon.Notify();
   }
 
 private:
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
   bool unwedged;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //// Async Helpers
 
 /**
  * Execute an async statement, blocking the main thread until we get the
--- a/storage/test/test_unlock_notify.cpp
+++ b/storage/test/test_unlock_notify.cpp
@@ -34,17 +34,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "storage_test_harness.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsThreadUtils.h"
 #include "mozIStorageStatement.h"
 
 /**
  * This file tests that our implementation around sqlite3_unlock_notify works
  * as expected.
  */
 
@@ -73,17 +73,17 @@ public:
     (void)NS_NewThread(getter_AddRefs(mThread));
     do_check_true(mThread);
 
     do_check_success(mThread->Dispatch(this, NS_DISPATCH_NORMAL));
   }
 
   NS_IMETHOD Run()
   {
-    mozilla::MonitorAutoEnter lock(monitor);
+    mozilla::ReentrantMonitorAutoEnter lock(monitor);
 
     nsCOMPtr<mozIStorageConnection> db(getDatabase());
 
     nsCString sql(mSQL);
     nsCOMPtr<mozIStorageStatement> stmt;
     do_check_success(db->CreateStatement(sql, getter_AddRefs(stmt)));
 
     PRBool hasResult;
@@ -105,17 +105,17 @@ public:
 
   void Notify(State aState)
   {
     monitor.AssertCurrentThreadIn();
     mState = aState;
     do_check_success(monitor.Notify());
   }
 
-  mozilla::Monitor monitor;
+  mozilla::ReentrantMonitor monitor;
 
 protected:
   nsCOMPtr<nsIThread> mThread;
   const char *const mSQL;
   State mState;
 };
 
 class DatabaseTester : public DatabaseLocker
@@ -125,17 +125,17 @@ public:
                  const char* aSQL)
   : DatabaseLocker(aSQL)
   , mConnection(aConnection)
   {
   }
 
   NS_IMETHOD Run()
   {
-    mozilla::MonitorAutoEnter lock(monitor);
+    mozilla::ReentrantMonitorAutoEnter lock(monitor);
     WaitFor(READ_LOCK);
 
     nsCString sql(mSQL);
     nsCOMPtr<mozIStorageStatement> stmt;
     do_check_success(mConnection->CreateStatement(sql, getter_AddRefs(stmt)));
 
     PRBool hasResult;
     nsresult rv = stmt->ExecuteStep(&hasResult);
@@ -194,17 +194,17 @@ test_step_locked_does_not_block_main_thr
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
     "INSERT INTO test (data) VALUES ('test1')"
   ), getter_AddRefs(stmt));
   do_check_success(rv);
 
   nsRefPtr<DatabaseLocker> locker(new DatabaseLocker("SELECT * FROM test"));
   do_check_true(locker);
-  mozilla::MonitorAutoEnter lock(locker->monitor);
+  mozilla::ReentrantMonitorAutoEnter lock(locker->monitor);
   locker->RunInBackground();
 
   // Wait for the locker to notify us that it has locked the database properly.
   locker->WaitFor(WRITE_LOCK);
 
   PRBool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
   do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
@@ -223,17 +223,17 @@ test_drop_index_does_not_loop()
   nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT * FROM test"
   ), getter_AddRefs(stmt));
   do_check_success(rv);
 
   nsRefPtr<DatabaseTester> tester =
     new DatabaseTester(db, "DROP INDEX unique_data");
   do_check_true(tester);
-  mozilla::MonitorAutoEnter lock(tester->monitor);
+  mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
   tester->RunInBackground();
 
   // Hold a read lock on the database, and then let the tester try to execute.
   PRBool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
   do_check_success(rv);
   do_check_true(hasResult);
   tester->Notify(READ_LOCK);
@@ -252,17 +252,17 @@ test_drop_table_does_not_loop()
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
     "SELECT * FROM test"
   ), getter_AddRefs(stmt));
   do_check_success(rv);
 
   nsRefPtr<DatabaseTester> tester(new DatabaseTester(db, "DROP TABLE test"));
   do_check_true(tester);
-  mozilla::MonitorAutoEnter lock(tester->monitor);
+  mozilla::ReentrantMonitorAutoEnter lock(tester->monitor);
   tester->RunInBackground();
 
   // Hold a read lock on the database, and then let the tester try to execute.
   PRBool hasResult;
   rv = stmt->ExecuteStep(&hasResult);
   do_check_success(rv);
   do_check_true(hasResult);
   tester->Notify(READ_LOCK);
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -422,17 +422,17 @@ nsresult nsComponentManagerImpl::Init()
 
     return NS_OK;
 }
 
 void
 nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule,
                                        nsILocalFile* aFile)
 {
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
 
     KnownModule* m = new KnownModule(aModule, aFile);
     if (aFile) {
         nsCOMPtr<nsIHashable> h = do_QueryInterface(aFile);
         NS_ASSERTION(!mKnownFileModules.Get(h),
                      "Must not register a binary module twice.");
 
         mKnownFileModules.Put(h, m);
@@ -789,17 +789,17 @@ nsComponentManagerImpl::ManifestComponen
 
     nsID cid;
     if (!cid.Parse(id)) {
         LogMessageWithContext(cx.mFile, cx.mPath, lineno,
                               "Malformed CID: '%s'.", id);
         return;
     }
 
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     nsFactoryEntry* f = mFactories.Get(cid);
     if (f) {
         char idstr[NSID_LENGTH];
         cid.ToProvidedString(idstr);
 
         nsCString existing;
         if (f->mModule)
             existing = f->mModule->Description();
@@ -874,17 +874,17 @@ nsComponentManagerImpl::ManifestContract
 
     nsID cid;
     if (!cid.Parse(id)) {
         LogMessageWithContext(cx.mFile, cx.mPath, lineno,
                               "Malformed CID: '%s'.", id);
         return;
     }
 
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     nsFactoryEntry* f = mFactories.Get(cid);
     if (!f) {
         LogMessageWithContext(cx.mFile, cx.mPath, lineno,
                               "Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
                               contract, id);
         return;
     }
 
@@ -1051,25 +1051,25 @@ nsComponentManagerImpl::GetInterface(con
     // got via the GetInterface()
     return  QueryInterface(uuid, result);
 }
 
 nsFactoryEntry *
 nsComponentManagerImpl::GetFactoryEntry(const char *aContractID,
                                         PRUint32 aContractIDLen)
 {
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     return mContractIDs.Get(nsDependentCString(aContractID, aContractIDLen));
 }
 
 
 nsFactoryEntry *
 nsComponentManagerImpl::GetFactoryEntry(const nsCID &aClass)
 {
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     return mFactories.Get(aClass);
 }
 
 already_AddRefed<nsIFactory>
 nsComponentManagerImpl::FindFactory(const nsCID& aClass)
 {
     nsFactoryEntry* e = GetFactoryEntry(aClass);
     if (!e)
@@ -1376,53 +1376,53 @@ nsComponentManagerImpl::GetPendingServic
     if (info.cid->Equals(aServiceCID)) {
       return info.thread;
     }
   }
   return nsnull;
 }
 
 // GetService() wants to manually Exit()/Enter() a monitor which is
-// wrapped in MonitorAutoEnter, which nsAutoMonitor used to allow.
+// wrapped in ReentrantMonitorAutoEnter, which nsAutoReentrantMonitor used to allow.
 // One use is block-scoped Exit()/Enter(), which could be supported
 // with something like a MonitoAutoExit, but that's not a well-defined
 // operation in general so that helper doesn't exist.  The other use
 // is early-Exit() for perf reasons.  This code is probably hot enough
 // to warrant special considerations.
 //
-// We could use bare mozilla::Monitor, but that's error prone.
+// We could use bare mozilla::ReentrantMonitor, but that's error prone.
 // Instead, we just add a hacky wrapper here that acts like the old
-// nsAutoMonitor.
-struct NS_STACK_CLASS AutoMonitor
+// nsAutoReentrantMonitor.
+struct NS_STACK_CLASS AutoReentrantMonitor
 {
-    AutoMonitor(Monitor& aMonitor) : mMonitor(&aMonitor), mEnterCount(0)
+    AutoReentrantMonitor(ReentrantMonitor& aReentrantMonitor) : mReentrantMonitor(&aReentrantMonitor), mEnterCount(0)
     {
         Enter();
     }
 
-    ~AutoMonitor()
+    ~AutoReentrantMonitor()
     {
         if (mEnterCount) {
             Exit();
         }
     }
 
     void Enter()
     {
-        mMonitor->Enter();
+        mReentrantMonitor->Enter();
         ++mEnterCount;
     }
 
     void Exit()
     {
         --mEnterCount;
-        mMonitor->Exit();
+        mReentrantMonitor->Exit();
     }
 
-    Monitor* mMonitor;
+    ReentrantMonitor* mReentrantMonitor;
     PRInt32 mEnterCount;
 };
 
 NS_IMETHODIMP
 nsComponentManagerImpl::GetService(const nsCID& aClass,
                                    const nsIID& aIID,
                                    void* *result)
 {
@@ -1436,17 +1436,17 @@ nsComponentManagerImpl::GetService(const
         cid.Adopt(aClass.ToString());
         iid.Adopt(aIID.ToString());
         fprintf(stderr, "Getting service on shutdown. Denied.\n"
                "         CID: %s\n         IID: %s\n", cid.get(), iid.get());
 #endif /* SHOW_DENIED_ON_SHUTDOWN */
         return NS_ERROR_UNEXPECTED;
     }
 
-    AutoMonitor mon(mMon);
+    AutoReentrantMonitor mon(mMon);
 
     nsFactoryEntry* entry = mFactories.Get(aClass);
     if (!entry)
         return NS_ERROR_FACTORY_NOT_REGISTERED;
 
     if (entry->mServiceObject) {
         nsCOMPtr<nsISupports> supports = entry->mServiceObject;
         mon.Exit();
@@ -1555,17 +1555,17 @@ nsComponentManagerImpl::IsServiceInstant
 #endif /* SHOW_DENIED_ON_SHUTDOWN */
         return NS_ERROR_UNEXPECTED;
     }
 
     nsresult rv = NS_ERROR_SERVICE_NOT_AVAILABLE;
     nsFactoryEntry* entry;
 
     {
-        MonitorAutoEnter mon(mMon);
+        ReentrantMonitorAutoEnter mon(mMon);
         entry = mFactories.Get(aClass);
     }
 
     if (entry && entry->mServiceObject) {
         nsCOMPtr<nsISupports> service;
         rv = entry->mServiceObject->QueryInterface(aIID, getter_AddRefs(service));
         *result = (service!=nsnull);
     }
@@ -1594,17 +1594,17 @@ NS_IMETHODIMP nsComponentManagerImpl::Is
                "  ContractID: %s\n         IID: %s\n", aContractID, iid.get());
 #endif /* SHOW_DENIED_ON_SHUTDOWN */
         return NS_ERROR_UNEXPECTED;
     }
 
     nsresult rv = NS_ERROR_SERVICE_NOT_AVAILABLE;
     nsFactoryEntry *entry;
     {
-        MonitorAutoEnter mon(mMon);
+        ReentrantMonitorAutoEnter mon(mMon);
         entry = mContractIDs.Get(nsDependentCString(aContractID));
     }
 
     if (entry && entry->mServiceObject) {
         nsCOMPtr<nsISupports> service;
         rv = entry->mServiceObject->QueryInterface(aIID, getter_AddRefs(service));
         *result = (service!=nsnull);
     }
@@ -1626,17 +1626,17 @@ nsComponentManagerImpl::GetServiceByCont
         nsXPIDLCString iid;
         iid.Adopt(aIID.ToString());
         fprintf(stderr, "Getting service on shutdown. Denied.\n"
                "  ContractID: %s\n         IID: %s\n", aContractID, iid.get());
 #endif /* SHOW_DENIED_ON_SHUTDOWN */
         return NS_ERROR_UNEXPECTED;
     }
 
-    AutoMonitor mon(mMon);
+    AutoReentrantMonitor mon(mMon);
 
     nsFactoryEntry *entry = mContractIDs.Get(nsDependentCString(aContractID));
     if (!entry)
         return NS_ERROR_FACTORY_NOT_REGISTERED;
 
     if (entry->mServiceObject) {
         nsCOMPtr<nsISupports> serviceObject = entry->mServiceObject;
 
@@ -1746,28 +1746,28 @@ nsComponentManagerImpl::RegisterFactory(
                                         nsIFactory* aFactory)
 {
     if (!aFactory) {
         // If a null factory is passed in, this call just wants to reset
         // the contract ID to point to an existing CID entry.
         if (!aContractID)
             return NS_ERROR_INVALID_ARG;
 
-        MonitorAutoEnter mon(mMon);
+        ReentrantMonitorAutoEnter mon(mMon);
         nsFactoryEntry* oldf = mFactories.Get(aClass);
         if (!oldf)
             return NS_ERROR_FACTORY_NOT_REGISTERED;
 
         mContractIDs.Put(nsDependentCString(aContractID), oldf);
         return NS_OK;
     }
 
     nsAutoPtr<nsFactoryEntry> f(new nsFactoryEntry(aClass, aFactory));
 
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     nsFactoryEntry* oldf = mFactories.Get(aClass);
     if (oldf)
         return NS_ERROR_FACTORY_EXISTS;
 
     if (aContractID)
         mContractIDs.Put(nsDependentCString(aContractID), f);
 
     mFactories.Put(aClass, f.forget());
@@ -1780,17 +1780,17 @@ nsComponentManagerImpl::UnregisterFactor
                                           nsIFactory* aFactory)
 {
     // Don't release the dying factory or service object until releasing
     // the component manager monitor.
     nsCOMPtr<nsIFactory> dyingFactory;
     nsCOMPtr<nsISupports> dyingServiceObject;
 
     {
-        MonitorAutoEnter mon(mMon);
+        ReentrantMonitorAutoEnter mon(mMon);
         nsFactoryEntry* f = mFactories.Get(aClass);
         if (!f || f->mFactory != aFactory)
             return NS_ERROR_FACTORY_NOT_REGISTERED;
 
         mFactories.Remove(aClass);
 
         // This might leave a stale contractid -> factory mapping in
         // place, so null out the factory entry (see
@@ -1915,17 +1915,17 @@ nsComponentManagerImpl::CIDToContractID(
     return NS_ERROR_FACTORY_NOT_REGISTERED;
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::ContractIDToCID(const char *aContractID,
                                         nsCID * *_retval)
 {
     {
-        MonitorAutoEnter mon(mMon);
+        ReentrantMonitorAutoEnter mon(mMon);
         nsFactoryEntry* entry = mContractIDs.Get(nsDependentCString(aContractID));
         if (entry) {
             *_retval = (nsCID*) NS_Alloc(sizeof(nsCID));
             **_retval = *entry->mCIDEntry->cid;
             return NS_OK;
         }
     }
     *_retval = NULL;
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -42,17 +42,17 @@
 
 #include "xpcom-private.h"
 #include "nsIComponentManager.h"
 #include "nsIComponentRegistrar.h"
 #include "nsIServiceManager.h"
 #include "nsILocalFile.h"
 #include "mozilla/Module.h"
 #include "mozilla/ModuleLoader.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsXULAppAPI.h"
 #include "nsNativeComponentLoader.h"
 #include "nsIFactory.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "pldhash.h"
 #include "prtime.h"
 #include "nsCOMPtr.h"
@@ -145,17 +145,17 @@ public:
 
     nsFactoryEntry *GetFactoryEntry(const char *aContractID,
                                     PRUint32 aContractIDLen);
     nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
 
     nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories;
     nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
 
-    mozilla::Monitor    mMon;
+    mozilla::ReentrantMonitor mMon;
 
     static void InitializeStaticModules();
     static void InitializeModuleLocations();
 
     struct ComponentLocation
     {
         NSLocationType type;
         nsCOMPtr<nsILocalFile> location;
--- a/xpcom/glue/BlockingResourceBase.cpp
+++ b/xpcom/glue/BlockingResourceBase.cpp
@@ -38,30 +38,30 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "mozilla/BlockingResourceBase.h"
 
 #ifdef DEBUG
 #include "nsAutoPtr.h"
 
 #include "mozilla/CondVar.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 #endif // ifdef DEBUG
 
 namespace mozilla {
 //
 // BlockingResourceBase implementation
 //
 
 // static members
 const char* const BlockingResourceBase::kResourceTypeName[] =
 {
     // needs to be kept in sync with BlockingResourceType
-    "Mutex", "Monitor", "CondVar"
+    "Mutex", "ReentrantMonitor", "CondVar"
 };
 
 #ifdef DEBUG
 
 PRCallOnceType BlockingResourceBase::sCallOnce;
 PRUintn BlockingResourceBase::sResourceAcqnChainFrontTPI = (PRUintn)-1;
 BlockingResourceBase::DDT* BlockingResourceBase::sDeadlockDetector;
 
@@ -267,87 +267,87 @@ Mutex::Unlock()
 {
     Release();                  // protected by mLock
     PRStatus status = PR_Unlock(mLock);
     NS_ASSERTION(PR_SUCCESS == status, "bad Mutex::Unlock()");
 }
 
 
 //
-// Debug implementation of Monitor
+// Debug implementation of ReentrantMonitor
 void
-Monitor::Enter()
+ReentrantMonitor::Enter()
 {
     BlockingResourceBase* chainFront = ResourceChainFront();
 
     // the code below implements monitor reentrancy semantics
 
     if (this == chainFront) {
         // immediately re-entered the monitor: acceptable
-        PR_EnterMonitor(mMonitor);
+        PR_EnterMonitor(mReentrantMonitor);
         ++mEntryCount;
         return;
     }
 
     CallStack callContext = CallStack();
     
     // this is sort of a hack around not recording the thread that
     // owns this monitor
     if (chainFront) {
         for (BlockingResourceBase* br = ResourceChainPrev(chainFront);
              br;
              br = ResourceChainPrev(br)) {
             if (br == this) {
                 NS_WARNING(
-                    "Re-entering Monitor after acquiring other resources.\n"
+                    "Re-entering ReentrantMonitor after acquiring other resources.\n"
                     "At calling context\n");
                 GetAcquisitionContext().Print(stderr);
 
                 // show the caller why this is potentially bad
                 CheckAcquire(callContext);
 
-                PR_EnterMonitor(mMonitor);
+                PR_EnterMonitor(mReentrantMonitor);
                 ++mEntryCount;
                 return;
             }
         }
     }
 
     CheckAcquire(callContext);
-    PR_EnterMonitor(mMonitor);
-    NS_ASSERTION(0 == mEntryCount, "Monitor isn't free!");
-    Acquire(callContext);       // protected by mMonitor
+    PR_EnterMonitor(mReentrantMonitor);
+    NS_ASSERTION(0 == mEntryCount, "ReentrantMonitor isn't free!");
+    Acquire(callContext);       // protected by mReentrantMonitor
     mEntryCount = 1;
 }
 
 void
-Monitor::Exit()
+ReentrantMonitor::Exit()
 {
     if (0 == --mEntryCount)
-        Release();              // protected by mMonitor
-    PRStatus status = PR_ExitMonitor(mMonitor);
-    NS_ASSERTION(PR_SUCCESS == status, "bad Monitor::Exit()");
+        Release();              // protected by mReentrantMonitor
+    PRStatus status = PR_ExitMonitor(mReentrantMonitor);
+    NS_ASSERTION(PR_SUCCESS == status, "bad ReentrantMonitor::Exit()");
 }
 
 nsresult
-Monitor::Wait(PRIntervalTime interval)
+ReentrantMonitor::Wait(PRIntervalTime interval)
 {
     AssertCurrentThreadIn();
 
     // save monitor state and reset it to empty
     PRInt32 savedEntryCount = mEntryCount;
     CallStack savedAcquisitionContext = GetAcquisitionContext();
     BlockingResourceBase* savedChainPrev = mChainPrev;
     mEntryCount = 0;
     SetAcquisitionContext(CallStack::kNone);
     mChainPrev = 0;
 
     // give up the monitor until we're back from Wait()
     nsresult rv =
-        PR_Wait(mMonitor, interval) == PR_SUCCESS ?
+        PR_Wait(mReentrantMonitor, interval) == PR_SUCCESS ?
             NS_OK : NS_ERROR_FAILURE;
     
     // restore saved state
     mEntryCount = savedEntryCount;
     SetAcquisitionContext(savedAcquisitionContext);
     mChainPrev = savedChainPrev;
 
     return rv;
--- a/xpcom/glue/BlockingResourceBase.h
+++ b/xpcom/glue/BlockingResourceBase.h
@@ -70,17 +70,17 @@ namespace mozilla {
  * BlockingResourceBase
  * Base class of resources that might block clients trying to acquire them.  
  * Does debugging and deadlock detection in DEBUG builds.
  **/
 class NS_COM_GLUE BlockingResourceBase
 {
 public:
     // Needs to be kept in sync with kResourceTypeNames.
-    enum BlockingResourceType { eMutex, eMonitor, eCondVar };
+    enum BlockingResourceType { eMutex, eReentrantMonitor, eCondVar };
 
     /**
      * kResourceTypeName
      * Human-readable version of BlockingResourceType enum.
      */
     static const char* const kResourceTypeName[];
 
 
--- a/xpcom/glue/Makefile.in
+++ b/xpcom/glue/Makefile.in
@@ -124,18 +124,18 @@ EXPORTS = \
 EXPORTS_mozilla = \
   AutoRestore.h \
   BlockingResourceBase.h \
   CondVar.h \
   DeadlockDetector.h \
   FileUtils.h \
   GenericFactory.h \
   IntentionalCrash.h \
-  Monitor.h \
   Mutex.h \
+  ReentrantMonitor.h \
   SSE.h \
   arm.h \
   unused.h \
   $(NULL)
 
 EXPORTS_mozilla/threads = \
   nsThreadIDs.h \
   $(NULL)
rename from xpcom/glue/Monitor.h
rename to xpcom/glue/ReentrantMonitor.h
--- a/xpcom/glue/Monitor.h
+++ b/xpcom/glue/ReentrantMonitor.h
@@ -31,140 +31,137 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#ifndef mozilla_Monitor_h
-#define mozilla_Monitor_h
+#ifndef mozilla_ReentrantMonitor_h
+#define mozilla_ReentrantMonitor_h
 
 #include "prmon.h"
 
 #include "mozilla/BlockingResourceBase.h"
 
 //
 // Provides:
 //
-//  - Monitor, a Java-like monitor
-//  - MonitorAutoEnter, an RAII class for ensuring that Monitors are properly 
-//    entered and exited
+//  - ReentrantMonitor, a Java-like monitor
+//  - ReentrantMonitorAutoEnter, an RAII class for ensuring that
+//    ReentrantMonitors are properly entered and exited
 //
-// Using MonitorAutoEnter is MUCH preferred to making bare calls to 
-// Monitor.Enter and Exit.
+// Using ReentrantMonitorAutoEnter is MUCH preferred to making bare calls to 
+// ReentrantMonitor.Enter and Exit.
 //
 namespace mozilla {
 
 
 /**
- * Monitor
+ * ReentrantMonitor
  * Java-like monitor.
- * When possible, use MonitorAutoEnter to hold this monitor within a
+ * When possible, use ReentrantMonitorAutoEnter to hold this monitor within a
  * scope, instead of calling Enter/Exit directly.
  **/
-class NS_COM_GLUE Monitor : BlockingResourceBase
+class NS_COM_GLUE ReentrantMonitor : BlockingResourceBase
 {
 public:
     /**
-     * Monitor
+     * ReentrantMonitor
      * @param aName A name which can reference this monitor
-     * @returns If failure, nsnull
-     *          If success, a valid Monitor*, which must be destroyed
-     *          by Monitor::DestroyMonitor()
-     **/
-    Monitor(const char* aName) :
-        BlockingResourceBase(aName, eMonitor)
+     */
+    ReentrantMonitor(const char* aName) :
+        BlockingResourceBase(aName, eReentrantMonitor)
 #ifdef DEBUG
         , mEntryCount(0)
 #endif
     {
-        MOZ_COUNT_CTOR(Monitor);
-        mMonitor = PR_NewMonitor();
-        if (!mMonitor)
-            NS_RUNTIMEABORT("Can't allocate mozilla::Monitor");
+        MOZ_COUNT_CTOR(ReentrantMonitor);
+        mReentrantMonitor = PR_NewMonitor();
+        if (!mReentrantMonitor)
+            NS_RUNTIMEABORT("Can't allocate mozilla::ReentrantMonitor");
     }
 
     /**
-     * ~Monitor
+     * ~ReentrantMonitor
      **/
-    ~Monitor()
+    ~ReentrantMonitor()
     {
-        NS_ASSERTION(mMonitor,
-                     "improperly constructed Monitor or double free");
-        PR_DestroyMonitor(mMonitor);
-        mMonitor = 0;
-        MOZ_COUNT_DTOR(Monitor);
+        NS_ASSERTION(mReentrantMonitor,
+                     "improperly constructed ReentrantMonitor or double free");
+        PR_DestroyMonitor(mReentrantMonitor);
+        mReentrantMonitor = 0;
+        MOZ_COUNT_DTOR(ReentrantMonitor);
     }
 
 #ifndef DEBUG
     /** 
      * Enter
      * @see prmon.h 
      **/
     void Enter()
     {
-        PR_EnterMonitor(mMonitor);
+        PR_EnterMonitor(mReentrantMonitor);
     }
 
     /** 
      * Exit
      * @see prmon.h 
      **/
     void Exit()
     {
-        PR_ExitMonitor(mMonitor);
+        PR_ExitMonitor(mReentrantMonitor);
     }
 
     /**
      * Wait
      * @see prmon.h
      **/      
     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
     {
-        return PR_Wait(mMonitor, interval) == PR_SUCCESS ?
+        return PR_Wait(mReentrantMonitor, interval) == PR_SUCCESS ?
             NS_OK : NS_ERROR_FAILURE;
     }
 
 #else
     void Enter();
     void Exit();
     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
 
 #endif  // ifndef DEBUG
 
     /** 
      * Notify
      * @see prmon.h 
      **/      
     nsresult Notify()
     {
-        return PR_Notify(mMonitor) == PR_SUCCESS
+        return PR_Notify(mReentrantMonitor) == PR_SUCCESS
             ? NS_OK : NS_ERROR_FAILURE;
     }
 
     /** 
      * NotifyAll
      * @see prmon.h 
      **/      
     nsresult NotifyAll()
     {
-        return PR_NotifyAll(mMonitor) == PR_SUCCESS
+        return PR_NotifyAll(mReentrantMonitor) == PR_SUCCESS
             ? NS_OK : NS_ERROR_FAILURE;
     }
 
 #ifdef DEBUG
     /**
      * AssertCurrentThreadIn
      * @see prmon.h
      **/
     void AssertCurrentThreadIn()
     {
-        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mMonitor);
+        PR_ASSERT_CURRENT_THREAD_IN_MONITOR(mReentrantMonitor);
     }
 
     /**
      * AssertNotCurrentThreadIn
      * @see prmon.h
      **/
     void AssertNotCurrentThreadIn()
     {
@@ -177,79 +174,78 @@ public:
     }
     void AssertNotCurrentThreadIn()
     {
     }
 
 #endif  // ifdef DEBUG
 
 private:
-    Monitor();
-    Monitor(const Monitor&);
-    Monitor& operator =(const Monitor&);
+    ReentrantMonitor();
+    ReentrantMonitor(const ReentrantMonitor&);
+    ReentrantMonitor& operator =(const ReentrantMonitor&);
 
-    PRMonitor* mMonitor;
+    PRMonitor* mReentrantMonitor;
 #ifdef DEBUG
     PRInt32 mEntryCount;
 #endif
 };
 
 
 /**
- * MonitorAutoEnter
- * Enters the Monitor when it enters scope, and exits it when it leaves 
- * scope.
+ * ReentrantMonitorAutoEnter
+ * Enters the ReentrantMonitor when it enters scope, and exits it when
+ * it leaves scope.
  *
- * MUCH PREFERRED to bare calls to Monitor.Enter and Exit.
+ * MUCH PREFERRED to bare calls to ReentrantMonitor.Enter and Exit.
  */ 
-class NS_COM_GLUE NS_STACK_CLASS MonitorAutoEnter
+class NS_COM_GLUE NS_STACK_CLASS ReentrantMonitorAutoEnter
 {
 public:
     /**
      * Constructor
      * The constructor aquires the given lock.  The destructor
      * releases the lock.
      * 
-     * @param aMonitor A valid mozilla::Monitor* returned by 
-     *                 mozilla::Monitor::NewMonitor. 
+     * @param aReentrantMonitor A valid mozilla::ReentrantMonitor*. 
      **/
-    MonitorAutoEnter(mozilla::Monitor &aMonitor) :
-        mMonitor(&aMonitor)
+    ReentrantMonitorAutoEnter(mozilla::ReentrantMonitor &aReentrantMonitor) :
+        mReentrantMonitor(&aReentrantMonitor)
     {
-        NS_ASSERTION(mMonitor, "null monitor");
-        mMonitor->Enter();
+        NS_ASSERTION(mReentrantMonitor, "null monitor");
+        mReentrantMonitor->Enter();
     }
     
-    ~MonitorAutoEnter(void)
+    ~ReentrantMonitorAutoEnter(void)
     {
-        mMonitor->Exit();
+        mReentrantMonitor->Exit();
     }
  
     nsresult Wait(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT)
     {
-       return mMonitor->Wait(interval);
+       return mReentrantMonitor->Wait(interval);
     }
 
     nsresult Notify()
     {
-        return mMonitor->Notify();
+        return mReentrantMonitor->Notify();
     }
 
     nsresult NotifyAll()
     {
-        return mMonitor->NotifyAll();
+        return mReentrantMonitor->NotifyAll();
     }
 
 private:
-    MonitorAutoEnter();
-    MonitorAutoEnter(const MonitorAutoEnter&);
-    MonitorAutoEnter& operator =(const MonitorAutoEnter&);
+    ReentrantMonitorAutoEnter();
+    ReentrantMonitorAutoEnter(const ReentrantMonitorAutoEnter&);
+    ReentrantMonitorAutoEnter& operator =(const ReentrantMonitorAutoEnter&);
     static void* operator new(size_t) CPP_THROW_NEW;
     static void operator delete(void*);
 
-    mozilla::Monitor* mMonitor;
+    mozilla::ReentrantMonitor* mReentrantMonitor;
 };
 
 
 } // namespace mozilla
 
 
-#endif // ifndef mozilla_Monitor_h
+#endif // ifndef mozilla_ReentrantMonitor_h
--- a/xpcom/io/nsPipe3.cpp
+++ b/xpcom/io/nsPipe3.cpp
@@ -30,17 +30,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsIPipe.h"
 #include "nsIEventTarget.h"
 #include "nsISeekableStream.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsSegmentedBuffer.h"
 #include "nsStreamUtils.h"
 #include "nsCOMPtr.h"
 #include "nsCRT.h"
@@ -255,17 +255,17 @@ public:
 
 protected:
     // We can't inherit from both nsIInputStream and nsIOutputStream
     // because they collide on their Close method. Consequently we nest their
     // implementations to avoid the extra object allocation.
     nsPipeInputStream   mInput;
     nsPipeOutputStream  mOutput;
 
-    Monitor             mMonitor;
+    ReentrantMonitor    mReentrantMonitor;
     nsSegmentedBuffer   mBuffer;
 
     char*               mReadCursor;
     char*               mReadLimit;
 
     PRInt32             mWriteSegment;
     char*               mWriteCursor;
     char*               mWriteLimit;
@@ -315,17 +315,17 @@ protected:
 
 //-----------------------------------------------------------------------------
 // nsPipe methods:
 //-----------------------------------------------------------------------------
 
 nsPipe::nsPipe()
     : mInput(this)
     , mOutput(this)
-    , mMonitor("nsPipe.mMonitor")
+    , mReentrantMonitor("nsPipe.mReentrantMonitor")
     , mReadCursor(nsnull)
     , mReadLimit(nsnull)
     , mWriteSegment(-1)
     , mWriteCursor(nsnull)
     , mWriteLimit(nsnull)
     , mStatus(NS_OK)
     , mInited(PR_FALSE)
 {
@@ -400,34 +400,34 @@ nsPipe::PeekSegment(PRUint32 index, char
                 limit = cursor + mBuffer.GetSegmentSize();
         }
     }
 }
 
 nsresult
 nsPipe::GetReadSegment(const char *&segment, PRUint32 &segmentLen)
 {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (mReadCursor == mReadLimit)
         return NS_FAILED(mStatus) ? mStatus : NS_BASE_STREAM_WOULD_BLOCK;
 
     segment    = mReadCursor;
     segmentLen = mReadLimit - mReadCursor;
     return NS_OK;
 }
 
 void
 nsPipe::AdvanceReadCursor(PRUint32 bytesRead)
 {
     NS_ASSERTION(bytesRead, "don't call if no bytes read");
 
     nsPipeEvents events;
     {
-        MonitorAutoEnter mon(mMonitor);
+        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         LOG(("III advancing read cursor by %u\n", bytesRead));
         NS_ASSERTION(bytesRead <= mBuffer.GetSegmentSize(), "read too much");
 
         mReadCursor += bytesRead;
         NS_ASSERTION(mReadCursor <= mReadLimit, "read cursor exceeds limit");
 
         mInput.ReduceAvailable(bytesRead);
@@ -472,17 +472,17 @@ nsPipe::AdvanceReadCursor(PRUint32 bytes
                 mon.Notify();
         }
     }
 }
 
 nsresult
 nsPipe::GetWriteSegment(char *&segment, PRUint32 &segmentLen)
 {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (NS_FAILED(mStatus))
         return mStatus;
 
     // write cursor and limit may both be null indicating an empty buffer.
     if (mWriteCursor == mWriteLimit) {
         char *seg = mBuffer.AppendNewSegment();
         // pipe is full
@@ -515,17 +515,17 @@ nsPipe::GetWriteSegment(char *&segment, 
 
 void
 nsPipe::AdvanceWriteCursor(PRUint32 bytesWritten)
 {
     NS_ASSERTION(bytesWritten, "don't call if no bytes written");
 
     nsPipeEvents events;
     {
-        MonitorAutoEnter mon(mMonitor);
+        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         LOG(("OOO advancing write cursor by %u\n", bytesWritten));
 
         char *newWriteCursor = mWriteCursor + bytesWritten;
         NS_ASSERTION(newWriteCursor <= mWriteLimit, "write cursor exceeds limit");
 
         // update read limit if reading in the same segment
         if (mWriteSegment == 0 && mReadLimit == mWriteCursor)
@@ -572,17 +572,17 @@ nsPipe::AdvanceWriteCursor(PRUint32 byte
 void
 nsPipe::OnPipeException(nsresult reason, PRBool outputOnly)
 {
     LOG(("PPP nsPipe::OnPipeException [reason=%x output-only=%d]\n",
         reason, outputOnly));
 
     nsPipeEvents events;
     {
-        MonitorAutoEnter mon(mMonitor);
+        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         // if we've already hit an exception, then ignore this one.
         if (NS_FAILED(mStatus))
             return;
 
         mStatus = reason;
 
         // an output-only exception applies to the input end if the pipe has
@@ -638,17 +638,17 @@ NS_IMPL_CI_INTERFACE_GETTER4(nsPipeInput
 
 NS_IMPL_THREADSAFE_CI(nsPipeInputStream)
 
 nsresult
 nsPipeInputStream::Wait()
 {
     NS_ASSERTION(mBlocking, "wait on non-blocking pipe input stream");
 
-    MonitorAutoEnter mon(mPipe->mMonitor);
+    ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     while (NS_SUCCEEDED(mPipe->mStatus) && (mAvailable == 0)) {
         LOG(("III pipe input: waiting for data\n"));
 
         mBlocked = PR_TRUE;
         mon.Wait();
         mBlocked = PR_FALSE;
 
@@ -732,17 +732,17 @@ NS_IMETHODIMP
 nsPipeInputStream::Close()
 {
     return CloseWithStatus(NS_BASE_STREAM_CLOSED);
 }
 
 NS_IMETHODIMP
 nsPipeInputStream::Available(PRUint32 *result)
 {
-    MonitorAutoEnter mon(mPipe->mMonitor);
+    ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     // return error if pipe closed
     if (!mAvailable && NS_FAILED(mPipe->mStatus))
         return mPipe->mStatus;
 
     *result = mAvailable;
     return NS_OK;
 }
@@ -838,17 +838,17 @@ nsPipeInputStream::AsyncWait(nsIInputStr
                              PRUint32 flags,
                              PRUint32 requestedCount,
                              nsIEventTarget *target)
 {
     LOG(("III AsyncWait [this=%x]\n", this));
 
     nsPipeEvents pipeEvents;
     {
-        MonitorAutoEnter mon(mPipe->mMonitor);
+        ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
         // replace a pending callback
         mCallback = 0;
         mCallbackFlags = 0;
 
         if (!callback)
             return NS_OK;
 
@@ -879,17 +879,17 @@ nsPipeInputStream::Seek(PRInt32 whence, 
 {
     NS_NOTREACHED("nsPipeInputStream::Seek");
     return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsPipeInputStream::Tell(PRInt64 *offset)
 {
-    MonitorAutoEnter mon(mPipe->mMonitor);
+    ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     // return error if pipe closed
     if (!mAvailable && NS_FAILED(mPipe->mStatus))
         return mPipe->mStatus;
 
     *offset = mLogicalOffset;
     return NS_OK;
 }
@@ -909,17 +909,17 @@ nsPipeInputStream::SetEOF()
 NS_IMETHODIMP
 nsPipeInputStream::Search(const char *forString, 
                           PRBool ignoreCase,
                           PRBool *found,
                           PRUint32 *offsetSearchedTo)
 {
     LOG(("III Search [for=%s ic=%u]\n", forString, ignoreCase));
 
-    MonitorAutoEnter mon(mPipe->mMonitor);
+    ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     char *cursor1, *limit1;
     PRUint32 index = 0, offset = 0;
     PRUint32 strLen = strlen(forString);
 
     mPipe->PeekSegment(0, cursor1, limit1);
     if (cursor1 == limit1) {
         *found = PR_FALSE;
@@ -997,17 +997,17 @@ NS_IMPL_CI_INTERFACE_GETTER2(nsPipeOutpu
 
 NS_IMPL_THREADSAFE_CI(nsPipeOutputStream)
 
 nsresult
 nsPipeOutputStream::Wait()
 {
     NS_ASSERTION(mBlocking, "wait on non-blocking pipe output stream");
 
-    MonitorAutoEnter mon(mPipe->mMonitor);
+    ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
     if (NS_SUCCEEDED(mPipe->mStatus) && !mWritable) {
         LOG(("OOO pipe output: waiting for space\n"));
         mBlocked = PR_TRUE;
         mon.Wait();
         mBlocked = PR_FALSE;
         LOG(("OOO pipe output: woke up [pipe-status=%x writable=%u]\n",
             mPipe->mStatus, mWritable));
@@ -1219,17 +1219,17 @@ nsPipeOutputStream::AsyncWait(nsIOutputS
                               PRUint32 flags,
                               PRUint32 requestedCount,
                               nsIEventTarget *target)
 {
     LOG(("OOO AsyncWait [this=%x]\n", this));
 
     nsPipeEvents pipeEvents;
     {
-        MonitorAutoEnter mon(mPipe->mMonitor);
+        ReentrantMonitorAutoEnter mon(mPipe->mReentrantMonitor);
 
         // replace a pending callback
         mCallback = 0;
         mCallbackFlags = 0;
 
         if (!callback)
             return NS_OK;
 
--- a/xpcom/proxy/tests/proxy-create-threadsafety.cpp
+++ b/xpcom/proxy/tests/proxy-create-threadsafety.cpp
@@ -46,17 +46,17 @@
 #include "nsCOMPtr.h"
 
 #include "nscore.h"
 #include "nspr.h"
 
 #include "nsITestProxy.h"
 #include "nsISupportsPrimitives.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 #include "nsIRunnable.h"
 #include "nsIProxyObjectManager.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsISupportsUtils.h"
@@ -95,17 +95,17 @@ 1		proxy event object released
 
 class ProxyTest : public nsIRunnable,
                   public nsITestProxy,
                   public nsISupportsPrimitive
 {
 public:
     ProxyTest()
         : mCounterLock("ProxyTest.mCounterLock")
-        , mEvilMonitor("ProxyTest.mEvilMonitor")
+        , mEvilReentrantMonitor("ProxyTest.mEvilReentrantMonitor")
         , mCounter(0)
     {}
 
     NS_IMETHOD Run()
     {
         nsresult rv;
         nsCOMPtr<nsIProxyObjectManager> pom =
             do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
@@ -176,28 +176,28 @@ public:
             {
                 MutexAutoLock counterLock(mCounterLock);
                 switch(mCounter) {
                     case 0:
                         ++mCounter;
                     {
                         /* be evil here and hang */
                         MutexAutoUnlock counterUnlock(mCounterLock);
-                        MonitorAutoEnter evilMonitor(mEvilMonitor);
-                        nsresult rv = evilMonitor.Wait();
+                        ReentrantMonitorAutoEnter evilReentrantMonitor(mEvilReentrantMonitor);
+                        nsresult rv = evilReentrantMonitor.Wait();
                         NS_ENSURE_SUCCESS(rv, rv);
                         break;
                     }
                     case 1:
                         ++mCounter;
                     {
                         /* okay, we had our fun, un-hang */
                         MutexAutoUnlock counterUnlock(mCounterLock);
-                        MonitorAutoEnter evilMonitor(mEvilMonitor);
-                        nsresult rv = evilMonitor.Notify();
+                        ReentrantMonitorAutoEnter evilReentrantMonitor(mEvilReentrantMonitor);
+                        nsresult rv = evilReentrantMonitor.Notify();
                         NS_ENSURE_SUCCESS(rv, rv);
                         break;
                     }
                     default: {
                         /* nothing special here */
                         ++mCounter;
                     }
                 }
@@ -223,17 +223,17 @@ public:
     NS_IMETHOD_(nsrefcnt) Release(void);
 
 protected:
     nsAutoRefCnt mRefCnt;
     NS_DECL_OWNINGTHREAD
 
 private:
     Mutex mCounterLock;
-    Monitor mEvilMonitor;
+    ReentrantMonitor mEvilReentrantMonitor;
     PRInt32 mCounter;
     nsCOMPtr<nsIThread> mThreadOne;
     nsCOMPtr<nsIThread> mThreadTwo;
 };
 
 NS_IMPL_THREADSAFE_ADDREF(ProxyTest)
 NS_IMPL_THREADSAFE_RELEASE(ProxyTest)
 
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfo.cpp
@@ -46,29 +46,29 @@ using namespace mozilla;
 
 /***************************************************************************/
 // Debug Instrumentation...
 
 #ifdef SHOW_INFO_COUNT_STATS
 static int DEBUG_TotalInfos = 0;
 static int DEBUG_CurrentInfos = 0;
 static int DEBUG_MaxInfos = 0;
-static int DEBUG_MonitorEntryCount = 0;
+static int DEBUG_ReentrantMonitorEntryCount = 0;
 
 #define LOG_INFO_CREATE(t)                                                  \
     DEBUG_TotalInfos++;                                                     \
     DEBUG_CurrentInfos++;                                                   \
     if(DEBUG_MaxInfos < DEBUG_CurrentInfos)                                 \
         DEBUG_MaxInfos = DEBUG_CurrentInfos /* no ';' */
 
 #define LOG_INFO_DESTROY(t)                                                 \
     DEBUG_CurrentInfos-- /* no ';' */
 
 #define LOG_INFO_MONITOR_ENTRY                                              \
-    DEBUG_MonitorEntryCount++ /* no ';' */
+    DEBUG_ReentrantMonitorEntryCount++ /* no ';' */
 
 #else /* SHOW_INFO_COUNT_STATS */
 
 #define LOG_INFO_CREATE(t)     ((void)0)
 #define LOG_INFO_DESTROY(t)    ((void)0)
 #define LOG_INFO_MONITOR_ENTRY ((void)0)
 #endif /* SHOW_INFO_COUNT_STATS */
 
@@ -615,17 +615,17 @@ xptiInterfaceEntry::HasAncestor(const ns
 }
 
 /***************************************************/
 
 nsresult 
 xptiInterfaceEntry::GetInterfaceInfo(xptiInterfaceInfo** info)
 {
 #ifdef DEBUG
-    xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet()->mTableMonitor.
+    xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet()->mTableReentrantMonitor.
         AssertCurrentThreadIn();
 #endif
     LOG_INFO_MONITOR_ENTRY;
 
     if(!mInfo)
     {
         mInfo = new xptiInterfaceInfo(this);
         if(!mInfo)
@@ -647,18 +647,18 @@ xptiInterfaceEntry::LockedInvalidateInte
         mInfo->Invalidate(); 
         mInfo = nsnull;
     }
 }
 
 PRBool
 xptiInterfaceInfo::BuildParent()
 {
-    mozilla::MonitorAutoEnter monitor(xptiInterfaceInfoManager::GetSingleton()->
-                                    GetWorkingSet()->mTableMonitor);
+    mozilla::ReentrantMonitorAutoEnter monitor(xptiInterfaceInfoManager::GetSingleton()->
+                                    GetWorkingSet()->mTableReentrantMonitor);
     NS_ASSERTION(mEntry && 
                  mEntry->IsFullyResolved() && 
                  !mParent &&
                  mEntry->Parent(),
                 "bad BuildParent call");
     return NS_SUCCEEDED(mEntry->Parent()->GetInterfaceInfo(&mParent));
 }
 
@@ -690,19 +690,19 @@ xptiInterfaceInfo::AddRef(void)
 nsrefcnt
 xptiInterfaceInfo::Release(void)
 {
     xptiInterfaceEntry* entry = mEntry;
     nsrefcnt cnt = NS_AtomicDecrementRefcnt(mRefCnt);
     NS_LOG_RELEASE(this, cnt, "xptiInterfaceInfo");
     if(!cnt)
     {
-        mozilla::MonitorAutoEnter monitor(xptiInterfaceInfoManager::
+        mozilla::ReentrantMonitorAutoEnter monitor(xptiInterfaceInfoManager::
                                           GetSingleton()->GetWorkingSet()->
-                                          mTableMonitor);
+                                          mTableReentrantMonitor);
         LOG_INFO_MONITOR_ENTRY;
 
         // If GetInterfaceInfo added and *released* a reference before we 
         // acquired the monitor then 'this' might already be dead. In that
         // case we would not want to try to access any instance data. We
         // would want to bail immediately. If 'this' is already dead then the
         // entry will no longer have a pointer to 'this'. So, we can protect 
         // ourselves from danger without more aggressive locking.
--- a/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiInterfaceInfoManager.cpp
@@ -228,17 +228,17 @@ xptiInterfaceInfoManager::RegisterXPTHea
 {
     if (aHeader->major_version >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
         NS_ASSERTION(!aHeader->num_interfaces,"bad libxpt");
         LOG_AUTOREG(("      file is version %d.%d  Type file of version %d.0 or higher can not be read.\n", (int)header->major_version, (int)header->minor_version, (int)XPT_MAJOR_INCOMPATIBLE_VERSION));
     }
 
     xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     for(PRUint16 k = 0; k < aHeader->num_interfaces; k++)
         VerifyAndAddEntryIfNew(aHeader->interface_directory + k, k, typelib);
 }
 
 void
 xptiInterfaceInfoManager::RegisterInputStream(nsIInputStream* aStream)
 {
     XPTHeader* header = ReadXPTFileFromInputStream(aStream);
@@ -249,17 +249,17 @@ xptiInterfaceInfoManager::RegisterInputS
 void
 xptiInterfaceInfoManager::VerifyAndAddEntryIfNew(XPTInterfaceDirectoryEntry* iface,
                                                  PRUint16 idx,
                                                  xptiTypelibGuts* typelib)
 {
     if (!iface->interface_descriptor)
         return;
     
-    mWorkingSet.mTableMonitor.AssertCurrentThreadIn();
+    mWorkingSet.mTableReentrantMonitor.AssertCurrentThreadIn();
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(iface->iid);
     if (entry) {
         // XXX validate this info to find possible inconsistencies
         LOG_AUTOREG(("      ignoring repeated interface: %s\n", iface->name));
         return;
     }
     
     // Build a new xptiInterfaceEntry object and hook it up. 
@@ -301,65 +301,65 @@ EntryToInfo(xptiInterfaceEntry* entry, n
     // Transfer the AddRef done by GetInterfaceInfo.
     *_retval = static_cast<nsIInterfaceInfo*>(info);
     return NS_OK;    
 }
 
 xptiInterfaceEntry*
 xptiInterfaceInfoManager::GetInterfaceEntryForIID(const nsIID *iid)
 {
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     return mWorkingSet.mIIDTable.Get(*iid);
 }
 
 /* nsIInterfaceInfo getInfoForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForIID(const nsIID * iid, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
     return EntryToInfo(entry, _retval);
 }
 
 /* nsIInterfaceInfo getInfoForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetInfoForName(const char *name, nsIInterfaceInfo **_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
     return EntryToInfo(entry, _retval);
 }
 
 /* nsIIDPtr getIIDForName (in string name); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetIIDForName(const char *name, nsIID * *_retval)
 {
     NS_ASSERTION(name, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     xptiInterfaceEntry* entry = mWorkingSet.mNameTable.Get(name);
     if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetIID(_retval);
 }
 
 /* string getNameForIID (in nsIIDPtr iid); */
 NS_IMETHODIMP xptiInterfaceInfoManager::GetNameForIID(const nsIID * iid, char **_retval)
 {
     NS_ASSERTION(iid, "bad param");
     NS_ASSERTION(_retval, "bad param");
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     xptiInterfaceEntry* entry = mWorkingSet.mIIDTable.Get(*iid);
     if (!entry) {
         *_retval = nsnull;
         return NS_ERROR_FAILURE;    
     }
 
     return entry->GetName(_retval);
 }
@@ -383,17 +383,17 @@ NS_IMETHODIMP xptiInterfaceInfoManager::
     // the table using an nsISupportsArray and builds an enumerator for that.
     // We can afford this transient cost.
 
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
     if (!array)
         return NS_ERROR_UNEXPECTED;
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayAppender, array);
 
     return array->Enumerate(_retval);
 }
 
 struct ArrayAndPrefix
 {
     nsISupportsArray* array;
@@ -419,17 +419,17 @@ xpti_ArrayPrefixAppender(const char* key
 /* nsIEnumerator enumerateInterfacesWhoseNamesStartWith (in string prefix); */
 NS_IMETHODIMP xptiInterfaceInfoManager::EnumerateInterfacesWhoseNamesStartWith(const char *prefix, nsIEnumerator **_retval)
 {
     nsCOMPtr<nsISupportsArray> array;
     NS_NewISupportsArray(getter_AddRefs(array));
     if (!array)
         return NS_ERROR_UNEXPECTED;
 
-    MonitorAutoEnter monitor(mWorkingSet.mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
     ArrayAndPrefix args = {array, prefix, PL_strlen(prefix)};
     mWorkingSet.mNameTable.EnumerateRead(xpti_ArrayPrefixAppender, &args);
 
     return array->Enumerate(_retval);
 }
 
 /* void autoRegisterInterfaces (); */
 NS_IMETHODIMP xptiInterfaceInfoManager::AutoRegisterInterfaces()
--- a/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiTypelibGuts.cpp
@@ -71,17 +71,17 @@ xptiTypelibGuts::GetEntryAt(PRUint16 i)
         return r;
 
     XPTInterfaceDirectoryEntry* iface = mHeader->interface_directory + i;
 
     xptiWorkingSet* set =
         xptiInterfaceInfoManager::GetSingleton()->GetWorkingSet();
 
     {
-        MonitorAutoEnter monitor(set->mTableMonitor);
+        ReentrantMonitorAutoEnter monitor(set->mTableReentrantMonitor);
         if (iface->iid.Equals(zeroIID))
             r = set->mNameTable.Get(iface->name);
         else
             r = set->mIIDTable.Get(iface->iid);
     }
 
     if (r)
         SetEntryAt(i, r);
--- a/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
+++ b/xpcom/reflect/xptinfo/src/xptiWorkingSet.cpp
@@ -43,17 +43,17 @@
 #include "nsString.h"
 
 using namespace mozilla;
 
 #define XPTI_STRUCT_ARENA_BLOCK_SIZE    (1024 * 1)
 #define XPTI_HASHTABLE_SIZE             2048
 
 xptiWorkingSet::xptiWorkingSet()
-    : mTableMonitor("xptiWorkingSet::mTableMonitor")
+    : mTableReentrantMonitor("xptiWorkingSet::mTableReentrantMonitor")
 {
     MOZ_COUNT_CTOR(xptiWorkingSet);
 
     mIIDTable.Init(XPTI_HASHTABLE_SIZE);
     mNameTable.Init(XPTI_HASHTABLE_SIZE);
 
     gXPTIStructArena = XPT_NewArena(XPTI_STRUCT_ARENA_BLOCK_SIZE, sizeof(double),
                                     "xptiWorkingSet structs");
@@ -64,17 +64,17 @@ xpti_Invalidator(const char* keyname, xp
 {
     entry->LockedInvalidateInterfaceInfo();
     return PL_DHASH_NEXT;
 }
 
 void 
 xptiWorkingSet::InvalidateInterfaceInfos()
 {
-    MonitorAutoEnter monitor(mTableMonitor);
+    ReentrantMonitorAutoEnter monitor(mTableReentrantMonitor);
     mNameTable.EnumerateRead(xpti_Invalidator, NULL);
 }        
 
 xptiWorkingSet::~xptiWorkingSet()
 {
     MOZ_COUNT_DTOR(xptiWorkingSet);
 
     // Only destroy the arena if we're doing leak stats. Why waste shutdown
--- a/xpcom/reflect/xptinfo/src/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/src/xptiprivate.h
@@ -57,17 +57,17 @@
 
 #include "nsIServiceManager.h"
 #include "nsILocalFile.h"
 #include "nsIDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsIWeakReference.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 
 #include "nsCRT.h"
 #include "nsMemory.h"
 
 #include "nsCOMArray.h"
 #include "nsQuickSort.h"
 
@@ -179,17 +179,17 @@ private:
     PRUint32        mMaxFileCount;
 
 public:
     // XXX make these private with accessors
     // mTableMonitor must be held across:
     //  * any read from or write to mIIDTable or mNameTable
     //  * any writing to the links between an xptiInterfaceEntry
     //    and its xptiInterfaceInfo (mEntry/mInfo)
-    mozilla::Monitor mTableMonitor;
+    mozilla::ReentrantMonitor mTableReentrantMonitor;
     nsDataHashtable<nsIDHashKey, xptiInterfaceEntry*> mIIDTable;
     nsDataHashtable<nsDepCharHashKey, xptiInterfaceEntry*> mNameTable;
 };
 
 /***************************************************************************/
 
 // This class exists to help xptiInterfaceInfo store a 4-state (2 bit) value 
 // and a set of bitflags in one 8bit value. See below.
@@ -424,17 +424,17 @@ private:
 
 class xptiInterfaceInfoManager 
     : public nsIInterfaceInfoSuperManager
 {
     NS_DECL_ISUPPORTS
     NS_DECL_NSIINTERFACEINFOMANAGER
     NS_DECL_NSIINTERFACEINFOSUPERMANAGER
 
-    typedef mozilla::Monitor Monitor;
+    typedef mozilla::ReentrantMonitor ReentrantMonitor;
     typedef mozilla::Mutex Mutex;
 
 public:
     // GetSingleton() is infallible
     static xptiInterfaceInfoManager* GetSingleton();
     static void FreeInterfaceInfoManager();
 
     void RegisterFile(nsILocalFile* aFile);
--- a/xpcom/tests/TestDeadlockDetector.cpp
+++ b/xpcom/tests/TestDeadlockDetector.cpp
@@ -40,17 +40,17 @@
 #include "prenv.h"
 #include "prerror.h"
 #include "prio.h"
 #include "prproces.h"
 
 #include "nsMemory.h"
 
 #include "mozilla/CondVar.h"
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 
 #include "TestHarness.h"
 
 using namespace mozilla;
 
 static PRThread*
 spawn(void (*run)(void*), void* arg)
@@ -388,33 +388,33 @@ Sanity3()
         FAIL("deadlock not detected");
     }
 }
 
 
 nsresult
 Sanity4_Child()
 {
-    mozilla::Monitor m1("dd.sanity4.m1");
+    mozilla::ReentrantMonitor m1("dd.sanity4.m1");
     mozilla::Mutex m2("dd.sanity4.m2");
     m1.Enter();
     m2.Lock();
     m1.Enter();
     return 0;
 }
 
 nsresult
 Sanity4()
 {
     const char* const tokens[] = {
-        "Re-entering Monitor after acquiring other resources",
+        "Re-entering ReentrantMonitor after acquiring other resources",
         "###!!! ERROR: Potential deadlock detected",
-        "=== Cyclical dependency starts at\n--- Monitor : dd.sanity4.m1",
+        "=== Cyclical dependency starts at\n--- ReentrantMonitor : dd.sanity4.m1",
         "--- Next dependency:\n--- Mutex : dd.sanity4.m2",
-        "=== Cycle completed at\n--- Monitor : dd.sanity4.m1",
+        "=== Cycle completed at\n--- ReentrantMonitor : dd.sanity4.m1",
         "###!!! ASSERTION: Potential deadlock detected",
         0
     };
     if (CheckForDeadlock("Sanity4", tokens)) {
         PASS();
     } else {
         FAIL("deadlock not detected");
     }
--- a/xpcom/tests/TestRacingServiceManager.cpp
+++ b/xpcom/tests/TestRacingServiceManager.cpp
@@ -43,17 +43,17 @@
 #include "nsIThread.h"
 #include "nsIComponentRegistrar.h"
 
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "prmon.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 #ifdef DEBUG
 #define TEST_ASSERTION(_test, _msg) \
     NS_ASSERTION(_test, _msg);
 #else
 #define TEST_ASSERTION(_test, _msg) \
   PR_BEGIN_MACRO \
@@ -84,40 +84,40 @@ NS_DEFINE_CID(kFactoryCID1, FACTORY_CID1
 NS_DEFINE_CID(kFactoryCID2, FACTORY_CID2);
 
 #define FACTORY_CONTRACTID                           \
   "TestRacingThreadManager/factory;1"
 
 PRInt32 gComponent1Count = 0;
 PRInt32 gComponent2Count = 0;
 
-Monitor* gMonitor = nsnull;
+ReentrantMonitor* gReentrantMonitor = nsnull;
 
 PRBool gCreateInstanceCalled = PR_FALSE;
 PRBool gMainThreadWaiting = PR_FALSE;
 
-class AutoCreateAndDestroyMonitor
+class AutoCreateAndDestroyReentrantMonitor
 {
 public:
-  AutoCreateAndDestroyMonitor(Monitor** aMonitorPtr)
-  : mMonitorPtr(aMonitorPtr) {
-    *aMonitorPtr =
-      new Monitor("TestRacingServiceManager::AutoMon");
-    TEST_ASSERTION(*aMonitorPtr, "Out of memory!");
+  AutoCreateAndDestroyReentrantMonitor(ReentrantMonitor** aReentrantMonitorPtr)
+  : mReentrantMonitorPtr(aReentrantMonitorPtr) {
+    *aReentrantMonitorPtr =
+      new ReentrantMonitor("TestRacingServiceManager::AutoMon");
+    TEST_ASSERTION(*aReentrantMonitorPtr, "Out of memory!");
   }
 
-  ~AutoCreateAndDestroyMonitor() {
-    if (*mMonitorPtr) {
-      delete *mMonitorPtr;
-      *mMonitorPtr = nsnull;
+  ~AutoCreateAndDestroyReentrantMonitor() {
+    if (*mReentrantMonitorPtr) {
+      delete *mReentrantMonitorPtr;
+      *mReentrantMonitorPtr = nsnull;
     }
   }
 
 private:
-  Monitor** mMonitorPtr;
+  ReentrantMonitor** mReentrantMonitorPtr;
 };
 
 class Factory : public nsIFactory
 {
 public:
   NS_DECL_ISUPPORTS
 
   Factory() : mFirstComponentCreated(PR_FALSE) { }
@@ -180,17 +180,17 @@ Factory::CreateInstance(nsISupports* aDe
                         const nsIID& aIID,
                         void** aResult)
 {
   // Make sure that the second thread beat the main thread to the getService
   // call.
   TEST_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     gCreateInstanceCalled = PR_TRUE;
     mon.Notify();
 
     mon.Wait(PR_MillisecondsToInterval(3000));
   }
 
   NS_ENSURE_FALSE(aDelegate, NS_ERROR_NO_AGGREGATION);
@@ -221,17 +221,17 @@ public:
 
   PRBool mFirstRunnableDone;
 };
 
 NS_IMETHODIMP
 Runnable::Run()
 {
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     while (!gMainThreadWaiting) {
       mon.Wait();
     }
   }
 
   nsresult rv;
   nsCOMPtr<nsISupports> component;
@@ -280,28 +280,28 @@ static const mozilla::Module kLocalModul
 int main(int argc, char** argv)
 {
   nsresult rv;
   XRE_AddStaticComponent(&kLocalModule);
 
   ScopedXPCOM xpcom("RacingServiceManager");
   NS_ENSURE_FALSE(xpcom.failed(), 1);
 
-  AutoCreateAndDestroyMonitor mon(&gMonitor);
+  AutoCreateAndDestroyReentrantMonitor mon(&gReentrantMonitor);
 
   nsRefPtr<Runnable> runnable = new Runnable();
   NS_ENSURE_TRUE(runnable, 1);
 
   // Run the classID test
   nsCOMPtr<nsIThread> newThread;
   rv = NS_NewThread(getter_AddRefs(newThread), runnable);
   NS_ENSURE_SUCCESS(rv, 1);
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     gMainThreadWaiting = PR_TRUE;
     mon.Notify();
 
     while (!gCreateInstanceCalled) {
       mon.Wait();
     }
   }
@@ -313,17 +313,17 @@ int main(int argc, char** argv)
   gMainThreadWaiting = gCreateInstanceCalled = PR_FALSE;
   gFactory->mFirstComponentCreated = runnable->mFirstRunnableDone = PR_TRUE;
   component = nsnull;
 
   rv = newThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
   NS_ENSURE_SUCCESS(rv, 1);
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     gMainThreadWaiting = PR_TRUE;
     mon.Notify();
 
     while (!gCreateInstanceCalled) {
       mon.Wait();
     }
   }
--- a/xpcom/tests/TestThreadPoolListener.cpp
+++ b/xpcom/tests/TestThreadPoolListener.cpp
@@ -43,28 +43,28 @@
 
 #include "nsThreadUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "pratom.h"
 #include "prinrval.h"
 #include "prmon.h"
 #include "prthread.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 #define NUMBER_OF_THREADS 4
 
 // One hour... because test boxes can be slow!
 #define IDLE_THREAD_TIMEOUT 3600000
 
 static nsIThread** gCreatedThreadList = nsnull;
 static nsIThread** gShutDownThreadList = nsnull;
 
-static Monitor* gMonitor = nsnull;
+static ReentrantMonitor* gReentrantMonitor = nsnull;
 
 static PRBool gAllRunnablesPosted = PR_FALSE;
 static PRBool gAllThreadsCreated = PR_FALSE;
 static PRBool gAllThreadsShutDown = PR_FALSE;
 
 #ifdef DEBUG
 #define TEST_ASSERTION(_test, _msg) \
     NS_ASSERTION(_test, _msg);
@@ -87,17 +87,17 @@ public:
 NS_IMPL_THREADSAFE_ISUPPORTS1(Listener, nsIThreadPoolListener)
 
 NS_IMETHODIMP
 Listener::OnThreadCreated()
 {
   nsCOMPtr<nsIThread> current(do_GetCurrentThread());
   TEST_ASSERTION(current, "Couldn't get current thread!");
 
-  MonitorAutoEnter mon(*gMonitor);
+  ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
   while (!gAllRunnablesPosted) {
     mon.Wait();
   }
 
   for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) {
     nsIThread* thread = gCreatedThreadList[i];
     TEST_ASSERTION(thread != current, "Saw the same thread twice!");
@@ -117,17 +117,17 @@ Listener::OnThreadCreated()
 }
 
 NS_IMETHODIMP
 Listener::OnThreadShuttingDown()
 {
   nsCOMPtr<nsIThread> current(do_GetCurrentThread());
   TEST_ASSERTION(current, "Couldn't get current thread!");
 
-  MonitorAutoEnter mon(*gMonitor);
+  ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
   for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) {
     nsIThread* thread = gShutDownThreadList[i];
     TEST_ASSERTION(thread != current, "Saw the same thread twice!");
 
     if (!thread) {
       gShutDownThreadList[i] = current;
       if (i == (NUMBER_OF_THREADS - 1)) {
@@ -137,49 +137,49 @@ Listener::OnThreadShuttingDown()
       return NS_OK;
     }
   }
 
   TEST_ASSERTION(PR_FALSE, "Too many threads!");
   return NS_ERROR_FAILURE;
 }
 
-class AutoCreateAndDestroyMonitor
+class AutoCreateAndDestroyReentrantMonitor
 {
 public:
-  AutoCreateAndDestroyMonitor(Monitor** aMonitorPtr)
-  : mMonitorPtr(aMonitorPtr) {
-    *aMonitorPtr = new Monitor("TestThreadPoolListener::AutoMon");
-    TEST_ASSERTION(*aMonitorPtr, "Out of memory!");
+  AutoCreateAndDestroyReentrantMonitor(ReentrantMonitor** aReentrantMonitorPtr)
+  : mReentrantMonitorPtr(aReentrantMonitorPtr) {
+    *aReentrantMonitorPtr = new ReentrantMonitor("TestThreadPoolListener::AutoMon");
+    TEST_ASSERTION(*aReentrantMonitorPtr, "Out of memory!");
   }
 
-  ~AutoCreateAndDestroyMonitor() {
-    if (*mMonitorPtr) {
-      delete *mMonitorPtr;
-      *mMonitorPtr = nsnull;
+  ~AutoCreateAndDestroyReentrantMonitor() {
+    if (*mReentrantMonitorPtr) {
+      delete *mReentrantMonitorPtr;
+      *mReentrantMonitorPtr = nsnull;
     }
   }
 
 private:
-  Monitor** mMonitorPtr;
+  ReentrantMonitor** mReentrantMonitorPtr;
 };
 
 int main(int argc, char** argv)
 {
   ScopedXPCOM xpcom("ThreadPoolListener");
   NS_ENSURE_FALSE(xpcom.failed(), 1);
 
   nsIThread* createdThreadList[NUMBER_OF_THREADS] = { nsnull };
   gCreatedThreadList = createdThreadList;
 
   nsIThread* shutDownThreadList[NUMBER_OF_THREADS] = { nsnull };
   gShutDownThreadList = shutDownThreadList;
 
-  AutoCreateAndDestroyMonitor newMon(&gMonitor);
-  NS_ENSURE_TRUE(gMonitor, 1);
+  AutoCreateAndDestroyReentrantMonitor newMon(&gReentrantMonitor);
+  NS_ENSURE_TRUE(gReentrantMonitor, 1);
 
   nsresult rv;
 
   // Grab the proxy service before messing with the thread pool. This is a
   // workaround for bug 449822 where the thread pool shutdown can create two
   // instances of the proxy service and hang.
   nsCOMPtr<nsIProxyObjectManager> proxyObjMgr =
     do_GetService(NS_XPCOMPROXY_CONTRACTID, &rv);
@@ -200,42 +200,42 @@ int main(int argc, char** argv)
 
   nsCOMPtr<nsIThreadPoolListener> listener = new Listener();
   NS_ENSURE_TRUE(listener, 1);
 
   rv = pool->SetListener(listener);
   NS_ENSURE_SUCCESS(rv, 1);
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
 
     for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) {
       nsCOMPtr<nsIRunnable> runnable = new nsRunnable();
       NS_ENSURE_TRUE(runnable, 1);
 
       rv = pool->Dispatch(runnable, NS_DISPATCH_NORMAL);
       NS_ENSURE_SUCCESS(rv, 1);
     }
 
     gAllRunnablesPosted = PR_TRUE;
     mon.NotifyAll();
   }
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
     while (!gAllThreadsCreated) {
       mon.Wait();
     }
   }
 
   rv = pool->Shutdown();
   NS_ENSURE_SUCCESS(rv, 1);
 
   {
-    MonitorAutoEnter mon(*gMonitor);
+    ReentrantMonitorAutoEnter mon(*gReentrantMonitor);
     while (!gAllThreadsShutDown) {
       mon.Wait();
     }
   }
 
   for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) {
     nsIThread* created = gCreatedThreadList[i];
     NS_ENSURE_TRUE(created, 1);
--- a/xpcom/tests/TestTimers.cpp
+++ b/xpcom/tests/TestTimers.cpp
@@ -42,17 +42,17 @@
 
 #include "nsCOMPtr.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "prinrval.h"
 #include "prmon.h"
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 using namespace mozilla;
 
 typedef nsresult(*TestFuncPtr)();
 
 class AutoTestThread
 {
 public:
   AutoTestThread() {
@@ -75,69 +75,69 @@ public:
   nsIThread* operator->() const {
     return mThread;
   }
 
 private:
   nsCOMPtr<nsIThread> mThread;
 };
 
-class AutoCreateAndDestroyMonitor
+class AutoCreateAndDestroyReentrantMonitor
 {
 public:
-  AutoCreateAndDestroyMonitor() {
-    mMonitor = new Monitor("TestTimers::AutoMon");
-    NS_ASSERTION(mMonitor, "Out of memory!");
+  AutoCreateAndDestroyReentrantMonitor() {
+    mReentrantMonitor = new ReentrantMonitor("TestTimers::AutoMon");
+    NS_ASSERTION(mReentrantMonitor, "Out of memory!");
   }
 
-  ~AutoCreateAndDestroyMonitor() {
-    if (mMonitor) {
-      delete mMonitor;
+  ~AutoCreateAndDestroyReentrantMonitor() {
+    if (mReentrantMonitor) {
+      delete mReentrantMonitor;
     }
   }
 
-  operator Monitor* () {
-    return mMonitor;
+  operator ReentrantMonitor* () {
+    return mReentrantMonitor;
   }
 
 private:
-  Monitor* mMonitor;
+  ReentrantMonitor* mReentrantMonitor;
 };
 
 class TimerCallback : public nsITimerCallback
 {
 public:
   NS_DECL_ISUPPORTS
 
-  TimerCallback(nsIThread** aThreadPtr, Monitor* aMonitor)
-  : mThreadPtr(aThreadPtr), mMonitor(aMonitor) { }
+  TimerCallback(nsIThread** aThreadPtr, ReentrantMonitor* aReentrantMonitor)
+  : mThreadPtr(aThreadPtr), mReentrantMonitor(aReentrantMonitor) { }
 
   NS_IMETHOD Notify(nsITimer* aTimer) {
     nsCOMPtr<nsIThread> current(do_GetCurrentThread());
 
-    MonitorAutoEnter mon(*mMonitor);
+    ReentrantMonitorAutoEnter mon(*mReentrantMonitor);
 
     NS_ASSERTION(!*mThreadPtr, "Timer called back more than once!");
     *mThreadPtr = current;
 
     mon.Notify();
 
     return NS_OK;
   }
 private:
   nsIThread** mThreadPtr;
-  Monitor* mMonitor;
+  ReentrantMonitor* mReentrantMonitor;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(TimerCallback, nsITimerCallback)
 
 nsresult
 TestTargetedTimers()
 {
-  AutoCreateAndDestroyMonitor newMon;
+  AutoCreateAndDestroyReentrantMonitor newMon;
   NS_ENSURE_TRUE(newMon, NS_ERROR_OUT_OF_MEMORY);
 
   AutoTestThread testThread;
   NS_ENSURE_TRUE(testThread, NS_ERROR_OUT_OF_MEMORY);
 
   nsresult rv;
   nsCOMPtr<nsITimer> timer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -152,17 +152,17 @@ TestTargetedTimers()
   nsCOMPtr<nsITimerCallback> callback =
     new TimerCallback(&notifiedThread, newMon);
   NS_ENSURE_TRUE(callback, NS_ERROR_OUT_OF_MEMORY);
 
   rv = timer->InitWithCallback(callback, PR_MillisecondsToInterval(2000),
                                nsITimer::TYPE_ONE_SHOT);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  MonitorAutoEnter mon(*newMon);
+  ReentrantMonitorAutoEnter mon(*newMon);
   while (!notifiedThread) {
     mon.Wait();
   }
   NS_ENSURE_TRUE(notifiedThread == testThread, NS_ERROR_FAILURE);
 
   return NS_OK;
 }
 
--- a/xpcom/threads/nsEventQueue.cpp
+++ b/xpcom/threads/nsEventQueue.cpp
@@ -44,17 +44,17 @@
 using namespace mozilla;
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *sLog = PR_NewLogModule("nsEventQueue");
 #endif
 #define LOG(args) PR_LOG(sLog, PR_LOG_DEBUG, args)
 
 nsEventQueue::nsEventQueue()
-  : mMonitor("nsEventQueue.mMonitor")
+  : mReentrantMonitor("nsEventQueue.mReentrantMonitor")
   , mHead(nsnull)
   , mTail(nsnull)
   , mOffsetHead(0)
   , mOffsetTail(0)
 {
 }
 
 nsEventQueue::~nsEventQueue()
@@ -66,17 +66,17 @@ nsEventQueue::~nsEventQueue()
   if (mHead)
     FreePage(mHead);
 }
 
 PRBool
 nsEventQueue::GetEvent(PRBool mayWait, nsIRunnable **result)
 {
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     
     while (IsEmpty()) {
       if (!mayWait) {
         if (result)
           *result = nsnull;
         return PR_FALSE;
       }
       LOG(("EVENTQ(%p): wait begin\n", this)); 
@@ -102,17 +102,17 @@ nsEventQueue::GetEvent(PRBool mayWait, n
 
 PRBool
 nsEventQueue::PutEvent(nsIRunnable *runnable)
 {
   // Avoid calling AddRef+Release while holding our monitor.
   nsRefPtr<nsIRunnable> event(runnable);
   PRBool rv = PR_TRUE;
   {
-    MonitorAutoEnter mon(mMonitor);
+    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
     if (!mHead) {
       mHead = NewPage();
       if (!mHead) {
         rv = PR_FALSE;
       } else {
         mTail = mHead;
         mOffsetHead = 0;
--- a/xpcom/threads/nsEventQueue.h
+++ b/xpcom/threads/nsEventQueue.h
@@ -35,23 +35,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef nsEventQueue_h__
 #define nsEventQueue_h__
 
 #include <stdlib.h>
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsIRunnable.h"
 
 // A threadsafe FIFO event queue...
 class NS_COM nsEventQueue
 {
-  typedef mozilla::Monitor Monitor;
+  typedef mozilla::ReentrantMonitor ReentrantMonitor;
 
 public:
   nsEventQueue();
   ~nsEventQueue();
 
   // This method adds a new event to the pending event queue.  The event object
   // is AddRef'd if this method succeeds.  This method returns PR_TRUE if the
   // event was stored in the event queue, and it returns PR_FALSE if it could
@@ -77,18 +77,18 @@ public:
   }
 
   // This method waits for and returns the next pending event.
   PRBool WaitPendingEvent(nsIRunnable **runnable) {
     return GetEvent(PR_TRUE, runnable);
   }
 
   // Expose the event queue's monitor for "power users"
-  Monitor& GetMonitor() {
-    return mMonitor;
+  ReentrantMonitor& GetReentrantMonitor() {
+    return mReentrantMonitor;
   }
 
 private:
 
   PRBool IsEmpty() {
     return !mHead || (mHead == mTail && mOffsetHead == mOffsetTail);
   }
 
@@ -104,17 +104,17 @@ private:
   static Page *NewPage() {
     return static_cast<Page *>(calloc(1, sizeof(Page)));
   }
 
   static void FreePage(Page *p) {
     free(p);
   }
 
-  Monitor mMonitor;
+  ReentrantMonitor mReentrantMonitor;
 
   Page *mHead;
   Page *mTail;
 
   PRUint16 mOffsetHead;  // offset into mHead where next item is removed
   PRUint16 mOffsetTail;  // offset into mTail where next item is added
 };
 
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -31,17 +31,17 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-#include "mozilla/Monitor.h"
+#include "mozilla/ReentrantMonitor.h"
 #include "nsThread.h"
 #include "nsThreadManager.h"
 #include "nsIClassInfoImpl.h"
 #include "nsIProgrammingLanguage.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "prlog.h"
 #include "nsThreadUtilsInternal.h"
@@ -179,40 +179,40 @@ public:
     return new nsThreadStartupEvent();
   }
 
   // This method does not return until the thread startup object is in the
   // completion state.
   void Wait() {
     if (mInitialized)  // Maybe avoid locking...
       return;
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     while (!mInitialized)
       mon.Wait();
   }
 
   // This method needs to be public to support older compilers (xlC_r on AIX).
   // It should be called directly as this class type is reference counted.
   virtual ~nsThreadStartupEvent() {
   }
 
 private:
   NS_IMETHOD Run() {
-    MonitorAutoEnter mon(mMon);
+    ReentrantMonitorAutoEnter mon(mMon);
     mInitialized = PR_TRUE;
     mon.Notify();
     return NS_OK;
   }
 
   nsThreadStartupEvent()
     : mMon("nsThreadStartupEvent.mMon")
     , mInitialized(PR_FALSE) {
   }
 
-  Monitor    mMon;
+  ReentrantMonitor mMon;
   PRBool     mInitialized;
 };
 
 //-----------------------------------------------------------------------------
 
 struct nsThreadShutdownContext {
   nsThread *joiningThread;
   PRBool    shutdownAck;
--- a/xpcom/threads/nsThreadPool.cpp
+++ b/xpcom/threads/nsThreadPool.cpp
@@ -87,17 +87,17 @@ nsThreadPool::~nsThreadPool()
 
 nsresult
 nsThreadPool::PutEvent(nsIRunnable *event)
 {
   // Avoid spawning a new thread while holding the event queue lock...
  
   PRBool spawnThread = PR_FALSE;
   {
-    MonitorAutoEnter mon(mEvents.GetMonitor());
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
 
     LOG(("THRD-P(%p) put [%d %d %d]\n", this, mIdleCount, mThreads.Count(),
          mThreadLimit));
     NS_ASSERTION(mIdleCount <= (PRUint32) mThreads.Count(), "oops");
 
     // Make sure we have a thread to service this event.
     if (mIdleCount == 0 && mThreads.Count() < (PRInt32) mThreadLimit)
       spawnThread = PR_TRUE;
@@ -110,17 +110,17 @@ nsThreadPool::PutEvent(nsIRunnable *even
     return NS_OK;
 
   nsCOMPtr<nsIThread> thread;
   nsThreadManager::get()->NewThread(0, getter_AddRefs(thread));
   NS_ENSURE_STATE(thread);
 
   PRBool killThread = PR_FALSE;
   {
-    MonitorAutoEnter mon(mEvents.GetMonitor());
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
     if (mThreads.Count() < (PRInt32) mThreadLimit) {
       mThreads.AppendObject(thread);
     } else {
       killThread = PR_TRUE;  // okay, we don't need this thread anymore
     }
   }
   LOG(("THRD-P(%p) put [%p kill=%d]\n", this, thread.get(), killThread));
   if (killThread) {
@@ -162,28 +162,28 @@ nsThreadPool::Run()
 
   PRBool shutdownThreadOnExit = PR_FALSE;
   PRBool exitThread = PR_FALSE;
   PRBool wasIdle = PR_FALSE;
   PRIntervalTime idleSince;
 
   nsCOMPtr<nsIThreadPoolListener> listener;
   {
-    MonitorAutoEnter mon(mEvents.GetMonitor());
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
     listener = mListener;
   }
 
   if (listener) {
     listener->OnThreadCreated();
   }
 
   do {
     nsCOMPtr<nsIRunnable> event;
     {
-      MonitorAutoEnter mon(mEvents.GetMonitor());
+      ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
       if (!mEvents.GetPendingEvent(getter_AddRefs(event))) {
         PRIntervalTime now     = PR_IntervalNow();
         PRIntervalTime timeout = PR_MillisecondsToInterval(mIdleThreadTimeout);
 
         // If we are shutting down, then don't keep any idle threads
         if (mShutdown) {
           exitThread = PR_TRUE;
         } else {
@@ -272,17 +272,17 @@ nsThreadPool::IsOnCurrentThread(PRBool *
 }
 
 NS_IMETHODIMP
 nsThreadPool::Shutdown()
 {
   nsCOMArray<nsIThread> threads;
   nsCOMPtr<nsIThreadPoolListener> listener;
   {
-    MonitorAutoEnter mon(mEvents.GetMonitor());
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
     mShutdown = PR_TRUE;
     mon.NotifyAll();
 
     threads.AppendObjects(mThreads);
     mThreads.Clear();
 
     // Swap in a null listener so that we release the listener at the end of
     // this method. The listener will be kept alive as long as the other threads
@@ -304,17 +304,17 @@ nsThreadPool::GetThreadLimit(PRUint32 *v
 {
   *value = mThreadLimit;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThreadPool::SetThreadLimit(PRUint32 value)
 {
-  MonitorAutoEnter mon(mEvents.GetMonitor());
+  ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
   mThreadLimit = value;
   if (mIdleThreadLimit > mThreadLimit)
     mIdleThreadLimit = mThreadLimit;
   mon.NotifyAll();  // wake up threads so they observe this change
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -322,17 +322,17 @@ nsThreadPool::GetIdleThreadLimit(PRUint3
 {
   *value = mIdleThreadLimit;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThreadPool::SetIdleThreadLimit(PRUint32 value)
 {
-  MonitorAutoEnter mon(mEvents.GetMonitor());
+  ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
   mIdleThreadLimit = value;
   if (mIdleThreadLimit > mThreadLimit)
     mIdleThreadLimit = mThreadLimit;
   mon.NotifyAll();  // wake up threads so they observe this change
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -340,32 +340,32 @@ nsThreadPool::GetIdleThreadTimeout(PRUin
 {
   *value = mIdleThreadTimeout;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThreadPool::SetIdleThreadTimeout(PRUint32 value)
 {
-  MonitorAutoEnter mon(mEvents.GetMonitor());
+  ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
   mIdleThreadTimeout = value;
   mon.NotifyAll();  // wake up threads so they observe this change
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThreadPool::GetListener(nsIThreadPoolListener** aListener)
 {
-  MonitorAutoEnter mon(mEvents.GetMonitor());
+  ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
   NS_IF_ADDREF(*aListener = mListener);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsThreadPool::SetListener(nsIThreadPoolListener* aListener)
 {
   nsCOMPtr<nsIThreadPoolListener> swappedListener(aListener);
   {
-    MonitorAutoEnter mon(mEvents.GetMonitor());
+    ReentrantMonitorAutoEnter mon(mEvents.GetReentrantMonitor());
     mListener.swap(swappedListener);
   }
   return NS_OK;
 }