Back to index

nordugrid-arc-nox  1.1.0~rc6
Thread.h
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifndef __ARC_THREAD_H__
00004 #define __ARC_THREAD_H__
00005 
00006 #include <glibmm/thread.h>
00007 
00008 #include <arc/User.h>
00009 
00010 namespace Arc {
00012 
00018 
00019   /* It seems like MacOS has very small stack per thread by default.
00020      So it's safer to have bigger one defined. If this value is set
00021      to 0 default value will be used. */
00022   const size_t thread_stacksize = (16 * 1024 * 1024);
00023 
00025 
00031 /*
00032 #define CreateThreadClass(instance, method) \
00033   { \
00034     Glib::Thread *thr = NULL; \
00035     * ThreadLock.lock(); * \
00036     try { \
00037       UserSwitch usw(0,0); \
00038       thr = Glib::Thread::create(sigc::mem_fun((instance), &method), false); \
00039     } catch (std::exception& e) {}; \
00040     * ThreadLock.unlock(); * \
00041     (thr != NULL); \
00042   }
00043 */
00044 
00046 
00050   bool CreateThreadFunction(void (*func)(void*), void *arg);
00051 
00053 
00059   //bool CreateThreadFunction(void (*func)(void*), void *arg, Glib::Thread *&thr);
00060 
00062 
00063   class SimpleCondition {
00064   private:
00065     Glib::Cond cond_;
00066     Glib::Mutex lock_;
00067     bool flag_;
00068   public:
00069     SimpleCondition(void)
00070       : flag_(false) {}
00071     ~SimpleCondition(void) {
00072       /* race condition ? */
00073       broadcast();
00074     }
00076     void lock(void) {
00077       lock_.lock();
00078     }
00080     void unlock(void) {
00081       lock_.unlock();
00082     }
00084     void signal(void) {
00085       lock_.lock();
00086       flag_ = true;
00087       cond_.signal();
00088       lock_.unlock();
00089     }
00091     void signal_nonblock(void) {
00092       flag_ = true;
00093       cond_.signal();
00094     }
00096     void broadcast(void) {
00097       lock_.lock();
00098       flag_ = true;
00099       cond_.broadcast();
00100       lock_.unlock();
00101     }
00103     void wait(void) {
00104       lock_.lock();
00105       while (!flag_)
00106         cond_.wait(lock_);
00107       flag_ = false;
00108       lock_.unlock();
00109     }
00111     void wait_nonblock(void) {
00112       while (!flag_)
00113         cond_.wait(lock_);
00114       flag_ = false;
00115     }
00117     bool wait(int t) {
00118       lock_.lock();
00119       Glib::TimeVal etime;
00120       etime.assign_current_time();
00121       etime.add_milliseconds(t);
00122       bool res(true);
00123       while (!flag_) {
00124         res = cond_.timed_wait(lock_, etime);
00125         if (!res)
00126           break;
00127       }
00128       flag_ = false;
00129       lock_.unlock();
00130       return res;
00131     }
00133     void reset(void) {
00134       lock_.lock();
00135       flag_ = false;
00136       lock_.unlock();
00137     }
00138   };
00139 
00144   class ThreadRegistry {
00145   private:
00146     int counter_;
00147     bool cancel_;
00148     Glib::Cond cond_;
00149     Glib::Mutex lock_;
00150   public:
00151     ThreadRegistry(void);
00152     ~ThreadRegistry(void);
00154     void RegisterThread(void);
00156     void UnregisterThread(void);
00159     bool WaitOrCancel(int timeout);
00163     bool WaitForExit(int timeout = -1);
00164     // Send cancel request to registered threads
00165     void RequestCancel(void);
00166   };
00167 
00168   void GlibThreadInitialize(void);
00169 
00170   // This class initializes glibmm thread system
00171   class ThreadInitializer {
00172   public:
00173     ThreadInitializer(void) {
00174       GlibThreadInitialize();
00175     }
00176   };
00177 
00178   // This is done intentionally to make sure glibmm is
00179   // properly initialized before every module starts
00180   // using threads functionality. To make it work this
00181   // header must be included before defining any 
00182   // variable/class instance using static threads-related
00183   // elements. The simplest way to do that is to use
00184   // this header instead of glibmm/thread.h
00185   static ThreadInitializer _local_thread_initializer;
00186 
00187 } // namespace Arc
00188 
00189 #endif /* __ARC_THREAD_H__ */