1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 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
|