00001 #include "ibrcommon/config.h"
00002 #include "ibrcommon/thread/Conditional.h"
00003 #include "ibrcommon/thread/Thread.h"
00004 #include <sys/time.h>
00005
00006 namespace ibrcommon
00007 {
00008 Conditional::Conditional()
00009 {
00010 pthread_cond_init(&cond, &attr.attr);
00011 }
00012
00013 Conditional::~Conditional()
00014 {
00015 signal(true);
00016 pthread_cond_destroy(&cond);
00017 }
00018
00019 void Conditional::signal (bool broadcast)
00020 {
00021 if (broadcast)
00022 pthread_cond_broadcast( &cond );
00023 else
00024 pthread_cond_signal( &cond );
00025 }
00026
00027 void Conditional::wait()
00028 {
00029 pthread_cond_wait( &cond, &m_mutex );
00030 }
00031
00032 bool Conditional::wait(size_t timeout)
00033 {
00034 struct timespec ts;
00035 gettimeout(timeout, &ts);
00036 return wait(&ts);
00037 }
00038
00039 bool Conditional::wait(struct timespec *ts)
00040 {
00041 if(pthread_cond_timedwait(&cond, &m_mutex, ts) == ETIMEDOUT)
00042 {
00043 return false;
00044 }
00045
00046 return true;
00047 }
00048
00049 Conditional::attribute Conditional::attr;
00050
00051 Conditional::attribute::attribute()
00052 {
00053 pthread_condattr_init(&attr);
00054 }
00055
00056 void Conditional::gettimeout(size_t msec, struct timespec *ts)
00057 {
00058 #if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined(_POSIX_MONOTONIC_CLOCK)
00059 clock_gettime(CLOCK_MONOTONIC, ts);
00060 #elif _POSIX_TIMERS > 0
00061 clock_gettime(CLOCK_REALTIME, ts);
00062 #else
00063 timeval tv;
00064 ::gettimeofday(&tv, NULL);
00065 ts->tv_sec = tv.tv_sec;
00066 ts->tv_nsec = tv.tv_usec * 1000l;
00067 #endif
00068 ts->tv_sec += msec / 1000;
00069 ts->tv_nsec += (msec % 1000) * 1000000l;
00070 while(ts->tv_nsec > 1000000000l) {
00071 ++ts->tv_sec;
00072 ts->tv_nsec -= 1000000000l;
00073 }
00074 }
00075 }
00076