/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_CondVar_h #define mozilla_CondVar_h #include "prcvar.h" #include "mozilla/BlockingResourceBase.h" #include "mozilla/Mutex.h" #ifdef MOZILLA_INTERNAL_API #include "GeckoProfiler.h" #endif //MOZILLA_INTERNAL_API namespace mozilla { /** * CondVar * Vanilla condition variable. Please don't use this unless you have a * compelling reason --- Monitor provides a simpler API. */ class CondVar : BlockingResourceBase { public: /** * CondVar * * The CALLER owns |aLock|. * * @param aLock A Mutex to associate with this condition variable. * @param aName A name which can reference this monitor * @returns If failure, nullptr. * If success, a valid Monitor* which must be destroyed * by Monitor::DestroyMonitor() **/ CondVar(Mutex& aLock, const char* aName) : BlockingResourceBase(aName, eCondVar) , mLock(&aLock) { MOZ_COUNT_CTOR(CondVar); // |aLock| must necessarily already be known to the deadlock detector mCvar = PR_NewCondVar(mLock->mLock); if (!mCvar) { NS_RUNTIMEABORT("Can't allocate mozilla::CondVar"); } } /** * ~CondVar * Clean up after this CondVar, but NOT its associated Mutex. **/ ~CondVar() { NS_ASSERTION(mCvar && mLock, "improperly constructed CondVar or double free"); PR_DestroyCondVar(mCvar); mCvar = 0; mLock = 0; MOZ_COUNT_DTOR(CondVar); } #ifndef DEBUG /** * Wait * @see prcvar.h **/ nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT) { #ifdef MOZILLA_INTERNAL_API GeckoProfilerSleepRAII profiler_sleep; #endif //MOZILLA_INTERNAL_API // NSPR checks for lock ownership return PR_WaitCondVar(mCvar, aInterval) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; } #else nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT); #endif // ifndef DEBUG /** * Notify * @see prcvar.h **/ nsresult Notify() { // NSPR checks for lock ownership return PR_NotifyCondVar(mCvar) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; } /** * NotifyAll * @see prcvar.h **/ nsresult NotifyAll() { // NSPR checks for lock ownership return PR_NotifyAllCondVar(mCvar) == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE; } #ifdef DEBUG /** * AssertCurrentThreadOwnsMutex * @see Mutex::AssertCurrentThreadOwns **/ void AssertCurrentThreadOwnsMutex() { mLock->AssertCurrentThreadOwns(); } /** * AssertNotCurrentThreadOwnsMutex * @see Mutex::AssertNotCurrentThreadOwns **/ void AssertNotCurrentThreadOwnsMutex() { mLock->AssertNotCurrentThreadOwns(); } #else void AssertCurrentThreadOwnsMutex() {} void AssertNotCurrentThreadOwnsMutex() {} #endif // ifdef DEBUG private: CondVar(); CondVar(CondVar&); CondVar& operator=(CondVar&); Mutex* mLock; PRCondVar* mCvar; }; } // namespace mozilla #endif // ifndef mozilla_CondVar_h