00001 #ifndef _sys_Monitor_h
00002 #define _sys_Monitor_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <sys/errno.h>
00026 #include <boost/noncopyable.hpp>
00027 #include <sys/Mutex.h>
00028 #include <sys/Time.h>
00029
00030 #ifdef USE_APR
00031 # include <apr_thread_cond.h>
00032 #endif
00033
00034 namespace qpid {
00035 namespace sys {
00036
00040 class Monitor : public Mutex
00041 {
00042 public:
00043 inline Monitor();
00044 inline ~Monitor();
00045 inline void wait();
00046 inline bool wait(const Time& absoluteTime);
00047 inline void notify();
00048 inline void notifyAll();
00049
00050 private:
00051 #ifdef USE_APR
00052 apr_thread_cond_t* condition;
00053 #else
00054 pthread_cond_t condition;
00055 #endif
00056 };
00057
00058
00059
00060 #ifdef USE_APR
00061
00062 Monitor::Monitor() {
00063 apr_pool_t* pool = APRPool::get();
00064 CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, pool));
00065 APRPool::free(pool);
00066 }
00067
00068 Monitor::~Monitor() {
00069 CHECK_APR_SUCCESS(apr_thread_cond_destroy(condition));
00070 }
00071
00072 void Monitor::wait() {
00073 CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex));
00074 }
00075
00076 bool Monitor::wait(const Time& absoluteTime){
00077
00078 apr_status_t status =
00079 apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC);
00080 if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status);
00081 return status == 0;
00082 }
00083
00084 void Monitor::notify(){
00085 CHECK_APR_SUCCESS(apr_thread_cond_signal(condition));
00086 }
00087
00088 void Monitor::notifyAll(){
00089 CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition));
00090 }
00091
00092 #else
00093
00094
00095 Monitor::Monitor() {
00096 QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0));
00097 }
00098
00099 Monitor::~Monitor() {
00100 QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition));
00101 }
00102
00103 void Monitor::wait() {
00104 QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex));
00105 }
00106
00107 bool Monitor::wait(const Time& absoluteTime){
00108 struct timespec ts;
00109 toTimespec(ts, absoluteTime);
00110 int status = pthread_cond_timedwait(&condition, &mutex, &ts);
00111 if (status != 0) {
00112 if (status == ETIMEDOUT) return false;
00113 throw QPID_POSIX_ERROR(status);
00114 }
00115 return true;
00116 }
00117
00118 void Monitor::notify(){
00119 QPID_POSIX_THROW_IF(pthread_cond_signal(&condition));
00120 }
00121
00122 void Monitor::notifyAll(){
00123 QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition));
00124 }
00125 #endif
00126
00127
00128 }}
00129 #endif