00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ARCHON_UTILITIES_CONDITION_H
00021 #define ARCHON_UTILITIES_CONDITION_H
00022
00023 #include <list>
00024
00025 #include <sys/select.h>
00026
00027 #include <archon/util/exception.H>
00028 #include <archon/util/time.H>
00029 #include <archon/util/mutex.H>
00030
00031 namespace Archon
00032 {
00033 namespace Utilities
00034 {
00035 using namespace std;
00036
00041 struct ThreadTerminatedException: UnexpectedException
00042 {
00043 ThreadTerminatedException(string l): UnexpectedException(l) {}
00044 };
00045
00049 struct Condition
00050 {
00051 Condition(Mutex &m);
00052 ~Condition();
00053
00054 void notifyOne()
00055 {
00056 const int e = pthread_cond_signal(&cond);
00057 if(e != 0)
00058 ARCHON_THROW1(InternalException,
00059 "Attempt to signal on condition failed");
00060 Mutex::Lock l(sigThreadsMutex);
00061 if(sigThreads.size()) notifySigThreads();
00062 }
00063
00064 void notifyAll()
00065 {
00066 const int e = pthread_cond_broadcast(&cond);
00067 if(e != 0)
00068 ARCHON_THROW1(InternalException,
00069 "Attempt to broadcast on condition failed");
00070 Mutex::Lock l(sigThreadsMutex);
00071 if(sigThreads.size()) notifySigThreads();
00072 }
00073
00084 void wait() throw(UnexpectedException);
00085
00100 bool timedWait(Time timeout) throw(UnexpectedException);
00101
00122 int select(int n, fd_set *readfds, fd_set *writefds,
00123 fd_set *exceptfds, Time timeout)
00124 throw(UnexpectedException);
00125
00126 private:
00127 friend struct Thread;
00128
00129 pthread_cond_t cond;
00130 Mutex *mutex;
00131
00132 Mutex sigThreadsMutex;
00133 list<pthread_t> sigThreads;
00134
00135 Condition(const Condition &);
00136 Condition &operator=(const Condition &);
00137
00138 void notifySigThreads();
00139 };
00140 }
00141 }
00142
00143 #endif