summaryrefslogtreecommitdiffstats
path: root/xpcom/glue/CondVar.h
diff options
context:
space:
mode:
Diffstat (limited to 'xpcom/glue/CondVar.h')
-rw-r--r--xpcom/glue/CondVar.h144
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