diff options
Diffstat (limited to 'xpcom/threads/CondVar.h')
-rw-r--r-- | xpcom/threads/CondVar.h | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/xpcom/threads/CondVar.h b/xpcom/threads/CondVar.h new file mode 100644 index 0000000000..e427fc2d9e --- /dev/null +++ b/xpcom/threads/CondVar.h @@ -0,0 +1,139 @@ +/* -*- 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 "mozilla/BlockingResourceBase.h" +#include "mozilla/PlatformConditionVariable.h" +#include "mozilla/Mutex.h" +#include "mozilla/TimeStamp.h" + +#if defined(MOZILLA_INTERNAL_API) && !defined(DEBUG) +# include "mozilla/ProfilerThreadSleep.h" +#endif // defined( MOZILLA_INTERNAL_API) && !defined(DEBUG) + +namespace mozilla { + +/** + * Similarly to OffTheBooksMutex, OffTheBooksCondvar is identical to CondVar, + * except that OffTheBooksCondVar doesn't include leak checking. Sometimes + * you want to intentionally "leak" a CondVar until shutdown; in these cases, + * OffTheBooksCondVar is for you. + */ +class OffTheBooksCondVar : BlockingResourceBase { + public: + /** + * OffTheBooksCondVar + * + * 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() + **/ + OffTheBooksCondVar(OffTheBooksMutex& aLock, const char* aName) + : BlockingResourceBase(aName, eCondVar), mLock(&aLock) {} + + /** + * ~OffTheBooksCondVar + * Clean up after this OffTheBooksCondVar, but NOT its associated Mutex. + **/ + ~OffTheBooksCondVar() = default; + + /** + * Wait + * @see prcvar.h + **/ +#ifndef DEBUG + void Wait() { +# ifdef MOZILLA_INTERNAL_API + AUTO_PROFILER_THREAD_SLEEP; +# endif // MOZILLA_INTERNAL_API + mImpl.wait(*mLock); + } + + CVStatus Wait(TimeDuration aDuration) { +# ifdef MOZILLA_INTERNAL_API + AUTO_PROFILER_THREAD_SLEEP; +# endif // MOZILLA_INTERNAL_API + return mImpl.wait_for(*mLock, aDuration); + } +#else + // NOTE: debug impl is in BlockingResourceBase.cpp + void Wait(); + CVStatus Wait(TimeDuration aDuration); +#endif + + /** + * Notify + * @see prcvar.h + **/ + void Notify() { mImpl.notify_one(); } + + /** + * NotifyAll + * @see prcvar.h + **/ + void NotifyAll() { mImpl.notify_all(); } + +#ifdef DEBUG + /** + * AssertCurrentThreadOwnsMutex + * @see Mutex::AssertCurrentThreadOwns + **/ + void AssertCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(mLock) { + mLock->AssertCurrentThreadOwns(); + } + + /** + * AssertNotCurrentThreadOwnsMutex + * @see Mutex::AssertNotCurrentThreadOwns + **/ + void AssertNotCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(!mLock) { + mLock->AssertNotCurrentThreadOwns(); + } + +#else + void AssertCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(mLock) {} + void AssertNotCurrentThreadOwnsMutex() const MOZ_ASSERT_CAPABILITY(!mLock) {} + +#endif // ifdef DEBUG + + private: + OffTheBooksCondVar(); + OffTheBooksCondVar(const OffTheBooksCondVar&) = delete; + OffTheBooksCondVar& operator=(const OffTheBooksCondVar&) = delete; + + OffTheBooksMutex* mLock; + detail::ConditionVariableImpl mImpl; +}; + +/** + * CondVar + * Vanilla condition variable. Please don't use this unless you have a + * compelling reason --- Monitor provides a simpler API. + */ +class CondVar : public OffTheBooksCondVar { + public: + CondVar(OffTheBooksMutex& aLock, const char* aName) + : OffTheBooksCondVar(aLock, aName) { + MOZ_COUNT_CTOR(CondVar); + } + + MOZ_COUNTED_DTOR(CondVar) + + private: + CondVar(); + CondVar(const CondVar&); + CondVar& operator=(const CondVar&); +}; + +} // namespace mozilla + +#endif // ifndef mozilla_CondVar_h |