00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef INDRI_CONDITIONVARIABLE_HPP
00021 #define INDRI_CONDITIONVARIABLE_HPP
00022
00023 #ifndef WIN32
00024 #include <pthread.h>
00025 #include <sys/time.h>
00026 #include <errno.h>
00027 #endif
00028
00029
00030 #include "indri/indri-platform.h"
00031 #include "Mutex.hpp"
00032 namespace indri
00033 {
00035 namespace thread
00036 {
00037 class ConditionVariable {
00038 private:
00039 #ifdef WIN32
00040 HANDLE _event;
00041 int _waiters;
00042 #else
00043 pthread_cond_t _condition;
00044 #endif
00045
00046 public:
00047 ConditionVariable() {
00048 #ifdef WIN32
00049 _event = ::CreateEvent( NULL, FALSE, FALSE, NULL );
00050 _waiters = 0;
00051 #else
00052 pthread_cond_init( &_condition, NULL );
00053 #endif
00054 }
00055
00056 ~ConditionVariable() {
00057 #ifdef WIN32
00058 ::CloseHandle( _event );
00059 #else
00060 pthread_cond_destroy( &_condition );
00061 #endif
00062 }
00063
00064 void wait( Mutex& mutex ) {
00065 #ifdef WIN32
00066 HRESULT result = ::SignalObjectAndWait( mutex._mutex, _event, INFINITE, FALSE );
00067 assert( SUCCEEDED(result) );
00068 mutex.lock();
00069 #else
00070 pthread_cond_wait( &_condition, &mutex._mutex );
00071 #endif
00072 }
00073
00074 bool wait( Mutex& mutex, UINT64 microseconds ) {
00075 #ifdef WIN32
00076 HRESULT result = ::SignalObjectAndWait( mutex._mutex, _event, DWORD(microseconds/1000), FALSE );
00077 assert( SUCCEEDED(result) );
00078 mutex.lock();
00079 return result != WAIT_TIMEOUT;
00080 #else
00081 struct timeval tv;
00082 gettimeofday( &tv, 0 );
00083
00084 UINT64 seconds = tv.tv_sec;
00085 seconds *= 1000 * 1000;
00086 microseconds += seconds;
00087 microseconds += tv.tv_usec;
00088
00089 struct timespec ts;
00090 ts.tv_sec = microseconds / 1000000;
00091 ts.tv_nsec = (microseconds % 1000000) * 1000;
00092
00093 int result = pthread_cond_timedwait( &_condition, &mutex._mutex, &ts );
00094 return result != ETIMEDOUT;
00095 #endif
00096 }
00097
00098
00099 void notifyOne( ) {
00100 #ifdef WIN32
00101 ::SetEvent( _event );
00102 #else
00103 pthread_cond_signal( &_condition );
00104 #endif
00105 }
00106
00107 void notifyAll( ) {
00108 #ifdef WIN32
00109 ::SetEvent( _event );
00110 #else
00111 pthread_cond_broadcast( &_condition );
00112 #endif
00113 }
00114 };
00115 }
00116 }
00117
00118 #endif // INDRI_CONDITIONVARIBLE_HPP
00119