summaryrefslogtreecommitdiffstats
path: root/xpcom/threads/CondVar.h
blob: e427fc2d9e0b33cd62eed33880deea05e133a3e4 (plain)
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