nsresult Monitor::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 ? NS_OK : NS_ERROR_FAILURE; // restore saved state mEntryCount = savedEntryCount; SetAcquisitionContext(savedAcquisitionContext); mChainPrev = savedChainPrev; return rv; }
nsresult ReentrantMonitor::Wait(PRIntervalTime aInterval) { AssertCurrentThreadIn(); // save monitor state and reset it to empty int32_t savedEntryCount = mEntryCount; CallStack savedAcquisitionContext = GetAcquisitionContext(); BlockingResourceBase* savedChainPrev = mChainPrev; mEntryCount = 0; SetAcquisitionContext(CallStack::kNone); mChainPrev = 0; nsresult rv; #ifdef MOZILLA_INTERNAL_API { GeckoProfilerSleepRAII profiler_sleep; #endif //MOZILLA_INTERNAL_API // give up the monitor until we're back from Wait() rv = PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; #ifdef MOZILLA_INTERNAL_API } #endif //MOZILLA_INTERNAL_API // restore saved state mEntryCount = savedEntryCount; SetAcquisitionContext(savedAcquisitionContext); mChainPrev = savedChainPrev; return rv; }
// // Debug implementation of Monitor void Monitor::Enter() { BlockingResourceBase* chainFront = ResourceChainFront(); // the code below implements monitor reentrancy semantics if (this == chainFront) { // immediately re-entered the monitor: acceptable PR_EnterMonitor(mMonitor); ++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" "At calling context\n"); GetAcquisitionContext().Print(stderr); // show the caller why this is potentially bad CheckAcquire(callContext); PR_EnterMonitor(mMonitor); ++mEntryCount; return; } } } CheckAcquire(callContext); PR_EnterMonitor(mMonitor); NS_ASSERTION(0 == mEntryCount, "Monitor isn't free!"); Acquire(callContext); // protected by mMonitor mEntryCount = 1; }