00001 
00020 #ifndef COIL_CONDITION_H
00021 #define COIL_CONDITION_H
00022 
00023 #include <pthread.h>
00024 #include <algorithm>
00025 #include <ctime>
00026 #include <sys/time.h>
00027 
00028 namespace coil
00029 {
00043   template <class M>
00044   class Condition
00045   {
00046   public:
00047 
00063     Condition(M& mutex)
00064       : m_mutex(mutex)
00065     {
00066       ::pthread_cond_init(&m_cond, 0);
00067     }
00068 
00084     ~Condition()
00085     {
00086       ::pthread_cond_destroy(&m_cond);
00087     }
00088 
00104     inline void signal()
00105     {
00106       ::pthread_cond_signal(&m_cond);
00107     }
00108 
00124     inline void broadcast()
00125     {
00126       ::pthread_cond_broadcast(&m_cond);
00127     }
00128 
00148     bool wait()
00149     {
00150       return 0 == ::pthread_cond_wait(&m_cond, &m_mutex.mutex_);
00151     }
00152 
00178     bool wait(long second, long nano_second = 0)
00179     {
00180       struct timeval tv;
00181       timespec abstime;
00182 
00183       ::gettimeofday(&tv, NULL);
00184       abstime.tv_sec  = tv.tv_sec + second;
00185       abstime.tv_nsec = tv.tv_usec * 1000 + nano_second;
00186       if (abstime.tv_nsec >= 1000000000) {
00187         abstime.tv_nsec -= 1000000000;
00188         abstime.tv_sec ++;
00189       }
00190       return 0 == ::pthread_cond_timedwait(&m_cond, &m_mutex.mutex_, &abstime);
00191     }
00192 
00193   private:
00194     Condition(const M&);
00195     Condition& operator=(const M &);
00196     pthread_cond_t m_cond;
00197     M& m_mutex;
00198   };
00199 };
00200 #endif // COIL_CONDITION_H