HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UT_Condition.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_Condition.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  * A condition class the implements pthread-like condition variables.
10  */
11 
12 #ifndef __UT_Condition_h__
13 #define __UT_Condition_h__
14 
15 #include "UT_API.h"
16 #include "UT_Assert.h"
17 #include "UT_Lock.h"
18 
19 #ifdef USE_PTHREADS
20  #include <pthread.h>
21 #endif
22 
23 
24 /// Condition synchronization primitive
26 {
27 public:
28  UT_Condition();
29  ~UT_Condition();
30 
31  /// Block until we're triggered.
32  ///
33  /// The lock must be held when this method is called. Will return when
34  /// the predicate evaluates to true, with the lock acquired. Internally
35  /// will release the lock and wait for triggers before retesting the
36  /// predicate.
37  template<typename Predicate>
38  void wait(UT_Lock &lock, const Predicate& pred)
39  {
40  while (!pred())
41  waitForTrigger(lock);
42  }
43 
44  /// The lock must be held when this method is called it will be released
45  /// when waiting for the trigger and re-acquired when this method returns.
46  void waitForTrigger(UT_Lock &lock);
47 
48  /// Wait with a timeout, returns true if the lock was re-acquired.
49  /// False means a timeout occurred.
50  bool waitForTriggerMS(UT_Lock &lock, int64 timeout_msec);
51 
52  /// Trigger all waiting threads.
53  ///
54  /// @note The caller should hold the same lock that was passed to
55  /// waitForTrigger() if precise scheduling of events is desired.
56  void triggerAll();
57 
58  /// Trigger one waiting thread.
59  ///
60  /// @note The caller should hold the same lock that was passed to
61  /// waitForTrigger() if precise scheduling of events is desired.
62  void triggerOne();
63 
64  // Prevent users from calling the copy constructor or assignment operator
65  // by declaring them as private. They are not implemented.
66  UT_Condition(const UT_Condition &copy) = delete;
67  UT_Condition &operator=(const UT_Condition &copy) = delete;
68 
69 private:
70 
71 #if defined(USE_PTHREADS)
72  pthread_cond_t myCond;
73 #elif defined(_WIN32)
74  void *myCond;
75 #else
76  #error Missing implementation
77 #endif
78 };
79 
80 //////////////////////////////////////////////////////////////////////////////
81 //
82 // PThreads Implementation
83 //
84 
85 #ifdef USE_PTHREADS
86 
87 inline
89 {
90  UT_VERIFY(pthread_cond_init(&myCond, 0) == 0);
91 }
92 
93 inline
95 {
96  // You should not destroy a condition upon which other threads are
97  // currently blocked. I suppose we trigger them here to try and detect
98  // errors more easily.
99  triggerAll();
100 
101  UT_VERIFY(pthread_cond_destroy(&myCond) == 0);
102 }
103 
104 // inline for speed
105 inline void
107 {
108  UT_VERIFY(pthread_cond_wait(&myCond, &lock.myLock) == 0);
109 }
110 
111 // inline for speed
112 inline void
114 {
115  UT_VERIFY(pthread_cond_broadcast(&myCond) == 0);
116 }
117 
118 // inline for speed
119 inline void
121 {
122  UT_VERIFY(pthread_cond_signal(&myCond) == 0);
123 }
124 
125 #endif // USE_PTHREADS
126 
127 //////////////////////////////////////////////////////////////////////////////
128 //
129 // Windows Implementation
130 //
131 
132 #ifdef _WIN32
133 
134 extern "C"
135 {
136  struct _RTL_CONDITION_VARIABLE;
137  using CONDITION_VARIABLE = _RTL_CONDITION_VARIABLE;
138 
139  __declspec(dllimport) void __stdcall
140  WakeConditionVariable(CONDITION_VARIABLE *ConditionVariable);
141  __declspec(dllimport) void __stdcall
142  WakeAllConditionVariable(CONDITION_VARIABLE *ConditionVariable);
143 }
144 
145 inline
147  : myCond{nullptr}
148 {
149 }
150 
151 inline
153 {
154  // You should not destroy a condition upon which other threads are
155  // currently blocked. I suppose we trigger them here to try and detect
156  // errors more easily.
157  triggerAll();
158 }
159 
160 // inline for speed
161 inline void
163 {
164  lock.sleep(this);
165 }
166 
167 inline bool
169 {
170  return lock.sleepMS(this, timeout_ms);
171 }
172 
173 // inline for speed
174 inline void
176 {
177  WakeAllConditionVariable((CONDITION_VARIABLE*) &myCond);
178 }
179 
180 // inline for speed
181 inline void
183 {
184  WakeConditionVariable((CONDITION_VARIABLE*) &myCond);
185 }
186 
187 #endif // _WIN32
188 
189 #endif // __UT_Condition_h__
bool waitForTriggerMS(UT_Lock &lock, int64 timeout_msec)
void
Definition: png.h:1083
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
#define UT_API
Definition: UT_API.h:14
Condition synchronization primitive.
Definition: UT_Condition.h:25
void triggerOne()
void waitForTrigger(UT_Lock &lock)
long long int64
Definition: SYS_Types.h:116
void triggerAll()
#define UT_VERIFY(expr)
Definition: UT_Assert.h:202
LeafData & operator=(const LeafData &)=delete
void wait(UT_Lock &lock, const Predicate &pred)
Definition: UT_Condition.h:38