diff options
Diffstat (limited to 'xpcom/glue/CondVar.h')
-rw-r--r-- | xpcom/glue/CondVar.h | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/xpcom/glue/CondVar.h b/xpcom/glue/CondVar.h new file mode 100644 index 000000000..5d05464ec --- /dev/null +++ b/xpcom/glue/CondVar.h @@ -0,0 +1,144 @@ +/* -*- 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 |