00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __UT_Condition_h__
00021 #define __UT_Condition_h__
00022
00023 #include "UT_API.h"
00024 #include "UT_Lock.h"
00025 #include <SYS/SYS_Types.h>
00026 #ifdef USE_PTHREADS
00027 #include <pthread.h>
00028 #endif
00029 #if defined(WIN32)
00030
00031
00032 #include <windows.h>
00033 #include <SYS/SYS_AtomicInt.h>
00034 #endif
00035
00036 class UT_API UT_Condition
00037 {
00038 public:
00039 UT_Condition();
00040 ~UT_Condition();
00041
00042
00043
00044
00045 void waitForTrigger(UT_Lock &lock)
00046 #ifdef USE_PTHREADS
00047 {
00048
00049 #if (UT_ASSERT_LEVEL > UT_ASSERT_LEVEL_NONE)
00050 int r = pthread_cond_wait(&myCond, &lock.myLock);
00051 UT_ASSERT(r == 0);
00052 #else
00053 pthread_cond_wait(&myCond, &lock.myLock);
00054 #endif
00055 }
00056 #else
00057 ;
00058 #endif
00059
00060
00061
00062
00063 void triggerAll()
00064 #ifdef USE_PTHREADS
00065 {
00066
00067 #if (UT_ASSERT_LEVEL > UT_ASSERT_LEVEL_NONE)
00068 int r = pthread_cond_broadcast(&myCond);
00069 UT_ASSERT(r == 0);
00070 #else
00071 pthread_cond_broadcast(&myCond);
00072 #endif
00073 }
00074 #else
00075 ;
00076 #endif
00077
00078
00079
00080
00081 void triggerOne()
00082 #ifdef USE_PTHREADS
00083 {
00084
00085 #if (UT_ASSERT_LEVEL > UT_ASSERT_LEVEL_NONE)
00086 int r = pthread_cond_signal(&myCond);
00087 UT_ASSERT(r == 0);
00088 #else
00089 pthread_cond_signal(&myCond);
00090 #endif
00091 }
00092 #else
00093 ;
00094 #endif
00095
00096 private:
00097
00098
00099 UT_Condition(const UT_Condition ©);
00100 UT_Condition &operator=(const UT_Condition ©);
00101
00102 #ifdef USE_PTHREADS
00103 pthread_cond_t myCond;
00104 #elif defined(WIN32)
00105 UT_Lock myCriticalSectionLock;
00106 SYS_AtomicInt32 myNumWaitingThreads;
00107 HANDLE myEvents[2];
00108 #endif
00109 };
00110
00111
00112
00113 #if defined(WIN32)
00114 #define USE_SPINLOCK_FOR_CONDITIONLOCK
00115 #endif
00116
00117 #ifdef USE_SPINLOCK_FOR_CONDITIONLOCK
00118 #include "UT_SpinLock.h"
00119 #endif
00120
00121
00122 class UT_API UT_ConditionLock
00123 {
00124 public:
00125 UT_ConditionLock()
00126 #ifdef USE_SPINLOCK_FOR_CONDITIONLOCK
00127 : myLock(false, false)
00128 #else
00129 : myLock(*this)
00130 #endif
00131 {}
00132
00133
00134 void waitForTrigger()
00135 {
00136 #ifdef USE_SPINLOCK_FOR_CONDITIONLOCK
00137 myLock.waitForTrigger();
00138 #else
00139 myLock.lock();
00140 myCond.waitForTrigger(myLock);
00141 myLock.unlock();
00142 #endif
00143 }
00144
00145
00146 void triggerOne()
00147 #ifdef USE_SPINLOCK_FOR_CONDITIONLOCK
00148 { myLock.trigger(); }
00149 #else
00150 { myCond.triggerOne(); }
00151 #endif
00152
00153 private:
00154 UT_ConditionLock(const UT_ConditionLock ©);
00155 UT_ConditionLock &operator=(const UT_ConditionLock ©);
00156
00157 #ifdef USE_SPINLOCK_FOR_CONDITIONLOCK
00158 UT_SpinLock myLock;
00159 #else
00160 UT_Lock myLock;
00161 UT_Condition myCond;
00162 #endif
00163 };
00164
00165 #endif