00001 #ifndef QPID_SYS_WAITABLE_H
00002 #define QPID_SYS_WAITABLE_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "qpid/sys/Monitor.h"
00025 #include "qpid/sys/ExceptionHolder.h"
00026 #include <assert.h>
00027
00028 namespace qpid {
00029 namespace sys {
00030
00038 class Waitable : public Monitor {
00039 public:
00040 Waitable() : waiters(0) {}
00041
00042 ~Waitable() { assert(waiters == 0); }
00043
00047 struct ScopedWait {
00048 Waitable& w;
00049 ScopedWait(Waitable& w_) : w(w_) { ++w.waiters; }
00050 ~ScopedWait() { if (--w.waiters==0) w.notifyAll(); }
00051 };
00052
00058 void waitWaiters() {
00059 while (waiters != 0)
00060 Monitor::wait();
00061 }
00062
00066 size_t hasWaiters() const {
00067 return waiters;
00068 }
00069
00073 void setException(const ExceptionHolder& e) {
00074 exception = e;
00075 notifyAll();
00076
00077 }
00078
00080 bool hasException() const { return exception; }
00081
00083 void resetException() { exception.reset(); }
00084
00086 void wait() {
00087 ExCheck e(exception);
00088 Monitor::wait();
00089 }
00090
00092 bool wait(const AbsTime& absoluteTime) {
00093 ExCheck e(exception);
00094 return Monitor::wait(absoluteTime);
00095 }
00096
00097 private:
00098 struct ExCheck {
00099 const ExceptionHolder& exception;
00100 ExCheck(const ExceptionHolder& e) : exception(e) { e.raise(); }
00101 ~ExCheck() { exception.raise(); }
00102 };
00103
00104 size_t waiters;
00105 ExceptionHolder exception;
00106
00107 friend struct ScopedWait;
00108 };
00109
00110 }}
00111
00112
00113
00114 #endif