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