00001 #ifndef IPC_ALARM_H
00002 #define IPC_ALARM_H
00003
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00022 #include <omniORB4/CORBA.h>
00023 #include <owl/mutex.h>
00024 #include <owl/thread.h>
00025 #include <owl/condition.h>
00026
00031 class IPCAlarm
00032 {
00033 public:
00038 typedef bool (*Callback)( void * );
00039
00040 private:
00041 class Thread : public OWLThread
00042 {
00043 public:
00044 Thread( long seconds, long nano_seconds, Callback cb, void * param )
00045 : condition_(&mutex_),
00046 suspended_(false),
00047 terminated_(false),
00048 seconds_(seconds),
00049 nano_seconds_(nano_seconds),
00050 callback_(cb),
00051 param_(param)
00052 { ; }
00053
00054 void suspend() {
00055 OWLMutexLock ml( mutex_ );
00056 suspended_ = true;
00057 }
00058
00059 void resume() {
00060 OWLMutexLock ml( mutex_ );
00061 suspended_ = false;
00062 }
00063
00064 void start() {
00065 start_undetached();
00066 }
00067
00068 void stop() {
00069 {
00070 OWLMutexLock ml( mutex_ );
00071 terminated_ = true;
00072 condition_.signal();
00073 }
00074 join(0);
00075 }
00076
00077 void * run_undetached( void * )
00078 {
00079 unsigned long s, n;
00080 OWLThread::get_time( &s, &n, seconds_, nano_seconds_ );
00081 OWLMutexLock ml( mutex_ );
00082 while ( !terminated_ && condition_.timedwait( s, n ) == 0 )
00083 {
00084 if ( !suspended_ && !terminated_ )
00085 {
00086 suspended_ = !callback_( param_ );
00087 }
00088 OWLThread::get_time( &s, &n, seconds_, nano_seconds_ );
00089 }
00090 return 0;
00091 }
00092
00093 private:
00095
00097 Thread ( Thread & );
00098 Thread & operator= ( Thread & );
00099
00100 OWLMutex mutex_;
00101 OWLCondition condition_;
00102 bool suspended_;
00103 bool terminated_;
00104 long seconds_;
00105 long nano_seconds_;
00106 Callback callback_;
00107 void * param_;
00108 };
00109
00110 public:
00111
00120 IPCAlarm( long seconds, long nano_seconds, IPCAlarm::Callback callback, void * param = 0 ) {
00121 alarm_thread_ = new Thread( seconds, nano_seconds, callback, param );
00122 alarm_thread_ -> start();
00123 }
00124
00131 IPCAlarm( double period, IPCAlarm::Callback callback, void * param = 0 ) {
00132 alarm_thread_ = new Thread( (long)period, (long)((period-(double)((long)period))*1000000000.), callback, param );
00133 alarm_thread_ -> start();
00134 }
00135
00139 ~IPCAlarm ( ) {
00140 alarm_thread_ -> stop();
00141 }
00142
00146 void suspend( ) {
00147 alarm_thread_ -> suspend();
00148 }
00149
00153 void resume( ) {
00154 alarm_thread_ -> resume();
00155 }
00156
00157 private:
00158
00160
00162 IPCAlarm ( IPCAlarm & );
00163 IPCAlarm & operator= ( IPCAlarm & );
00164
00165 Thread * alarm_thread_;
00166 };
00167
00168 #endif