1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_BASE_PLATFORM_CONDITION_VARIABLE_H_ 6 #define V8_BASE_PLATFORM_CONDITION_VARIABLE_H_ 7 8 #include "src/base/base-export.h" 9 #include "src/base/lazy-instance.h" 10 #include "src/base/platform/mutex.h" 11 12 #if V8_OS_STARBOARD 13 #include "starboard/common/condition_variable.h" 14 #endif 15 16 namespace v8 { 17 namespace base { 18 19 // Forward declarations. 20 class ConditionVariableEvent; 21 class TimeDelta; 22 23 // ----------------------------------------------------------------------------- 24 // ConditionVariable 25 // 26 // This class is a synchronization primitive that can be used to block a thread, 27 // or multiple threads at the same time, until: 28 // - a notification is received from another thread, 29 // - a timeout expires, or 30 // - a spurious wakeup occurs 31 // Any thread that intends to wait on a ConditionVariable has to acquire a lock 32 // on a Mutex first. The |Wait()| and |WaitFor()| operations atomically release 33 // the mutex and suspend the execution of the calling thread. When the condition 34 // variable is notified, the thread is awakened, and the mutex is reacquired. 35 36 class V8_BASE_EXPORT ConditionVariable final { 37 public: 38 ConditionVariable(); 39 ConditionVariable(const ConditionVariable&) = delete; 40 ConditionVariable& operator=(const ConditionVariable&) = delete; 41 ~ConditionVariable(); 42 43 // If any threads are waiting on this condition variable, calling 44 // |NotifyOne()| unblocks one of the waiting threads. 45 void NotifyOne(); 46 47 // Unblocks all threads currently waiting for this condition variable. 48 void NotifyAll(); 49 50 // |Wait()| causes the calling thread to block until the condition variable is 51 // notified or a spurious wakeup occurs. Atomically releases the mutex, blocks 52 // the current executing thread, and adds it to the list of threads waiting on 53 // this condition variable. The thread will be unblocked when |NotifyAll()| or 54 // |NotifyOne()| is executed. It may also be unblocked spuriously. When 55 // unblocked, regardless of the reason, the lock on the mutex is reacquired 56 // and |Wait()| exits. 57 void Wait(Mutex* mutex); 58 59 // Atomically releases the mutex, blocks the current executing thread, and 60 // adds it to the list of threads waiting on this condition variable. The 61 // thread will be unblocked when |NotifyAll()| or |NotifyOne()| is executed, 62 // or when the relative timeout |rel_time| expires. It may also be unblocked 63 // spuriously. When unblocked, regardless of the reason, the lock on the mutex 64 // is reacquired and |WaitFor()| exits. Returns true if the condition variable 65 // was notified prior to the timeout. 66 bool WaitFor(Mutex* mutex, const TimeDelta& rel_time) V8_WARN_UNUSED_RESULT; 67 68 // The implementation-defined native handle type. 69 #if V8_OS_POSIX 70 using NativeHandle = pthread_cond_t; 71 #elif V8_OS_WIN 72 using NativeHandle = CONDITION_VARIABLE; 73 #elif V8_OS_STARBOARD 74 using NativeHandle = SbConditionVariable; 75 #endif 76 native_handle()77 NativeHandle& native_handle() { 78 return native_handle_; 79 } native_handle()80 const NativeHandle& native_handle() const { 81 return native_handle_; 82 } 83 84 private: 85 NativeHandle native_handle_; 86 }; 87 88 // POD ConditionVariable initialized lazily (i.e. the first time Pointer() is 89 // called). 90 // Usage: 91 // static LazyConditionVariable my_condvar = 92 // LAZY_CONDITION_VARIABLE_INITIALIZER; 93 // 94 // void my_function() { 95 // MutexGuard lock_guard(&my_mutex); 96 // my_condvar.Pointer()->Wait(&my_mutex); 97 // } 98 using LazyConditionVariable = 99 LazyStaticInstance<ConditionVariable, 100 DefaultConstructTrait<ConditionVariable>, 101 ThreadSafeInitOnceTrait>::type; 102 103 #define LAZY_CONDITION_VARIABLE_INITIALIZER LAZY_STATIC_INSTANCE_INITIALIZER 104 105 } // namespace base 106 } // namespace v8 107 108 #endif // V8_BASE_PLATFORM_CONDITION_VARIABLE_H_ 109