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