diff -r 000000000000 -r 6474c204b198 xpcom/glue/CondVar.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xpcom/glue/CondVar.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: sw=4 ts=4 et : + * 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 NS_COM_GLUE CondVar : BlockingResourceBase +{ +public: + /** + * CondVar + * + * The CALLER owns |lock|. + * + * @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); + // |lock| 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 interval = PR_INTERVAL_NO_TIMEOUT) + { + +#ifdef MOZILLA_INTERNAL_API + GeckoProfilerSleepRAII profiler_sleep; +#endif //MOZILLA_INTERNAL_API + // NSPR checks for lock ownership + return PR_WaitCondVar(mCvar, interval) == PR_SUCCESS + ? NS_OK : NS_ERROR_FAILURE; + } +#else + nsresult Wait(PRIntervalTime interval = 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