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 CHECK_APR_SUCCESS(apr_thread_cond_create(&condition, APRPool::get()));
00064 }
00065
00066 Monitor::~Monitor() {
00067 CHECK_APR_SUCCESS(apr_thread_cond_destroy(condition));
00068 }
00069
00070 void Monitor::wait() {
00071 CHECK_APR_SUCCESS(apr_thread_cond_wait(condition, mutex));
00072 }
00073
00074 bool Monitor::wait(const Time& absoluteTime){
00075
00076 apr_status_t status =
00077 apr_thread_cond_timedwait(condition, mutex, absoluteTime/TIME_USEC);
00078 if(status != APR_TIMEUP) CHECK_APR_SUCCESS(status);
00079 return status == 0;
00080 }
00081
00082 void Monitor::notify(){
00083 CHECK_APR_SUCCESS(apr_thread_cond_signal(condition));
00084 }
00085
00086 void Monitor::notifyAll(){
00087 CHECK_APR_SUCCESS(apr_thread_cond_broadcast(condition));
00088 }
00089
00090 #else
00091
00092
00093 Monitor::Monitor() {
00094 QPID_POSIX_THROW_IF(pthread_cond_init(&condition, 0));
00095 }
00096
00097 Monitor::~Monitor() {
00098 QPID_POSIX_THROW_IF(pthread_cond_destroy(&condition));
00099 }
00100
00101 void Monitor::wait() {
00102 QPID_POSIX_THROW_IF(pthread_cond_wait(&condition, &mutex));
00103 }
00104
00105 bool Monitor::wait(const Time& absoluteTime){
00106 struct timespec ts;
00107 toTimespec(ts, absoluteTime);
00108 int status = pthread_cond_timedwait(&condition, &mutex, &ts);
00109 if (status != 0) {
00110 if (status == ETIMEDOUT) return false;
00111 throw QPID_POSIX_ERROR(status);
00112 }
00113 return true;
00114 }
00115
00116 void Monitor::notify(){
00117 QPID_POSIX_THROW_IF(pthread_cond_signal(&condition));
00118 }
00119
00120 void Monitor::notifyAll(){
00121 QPID_POSIX_THROW_IF(pthread_cond_broadcast(&condition));
00122 }
00123 #endif
00124
00125
00126 }}
00127 #endif