Fawkes API  Fawkes Development Version
thread.h
00001 
00002 /***************************************************************************
00003  *  thread.h - base class for threads, implementation based on pthreads
00004  *
00005  *  Created: Thu Sep 14 13:06:18 2006
00006  *  Copyright  2006-2009  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __CORE_THREADING_THREAD_H_
00025 #define __CORE_THREADING_THREAD_H_
00026 
00027 #include <sys/types.h>
00028 #include <stdint.h>
00029 
00030 #define forever while (1)
00031 
00032 namespace fawkes {
00033 
00034 
00035 class WaitCondition;
00036 class Mutex;
00037 class Barrier;
00038 class ThreadNotificationListener;
00039 class ThreadList;
00040 template <typename Type> class LockList;
00041 
00042 class Thread {
00043  public:
00044   friend class ThreadList;
00045 
00046   /** Thread operation mode.
00047    * A thread can operate in two different modes. In continuous mode the
00048    * thread is on it's own running continuously. No timing is done. The loop() is
00049    * immediately called again after it has finished once. In wait-for-wakeup mode
00050    * the thread will pause after each loop and wait for an explicit wakeup.
00051    */
00052   typedef enum {
00053     OPMODE_CONTINUOUS,          /**< operate in continuous mode (default) */
00054     OPMODE_WAITFORWAKEUP        /**< operate in wait-for-wakeup mode */
00055   } OpMode;
00056 
00057   /** Cancel state.
00058    * The current cancel state of a thread.
00059    */
00060   typedef enum {
00061     CANCEL_ENABLED,     /**< cancellation is possible */
00062     CANCEL_DISABLED     /**< thread cannot be cancelled */
00063   } CancelState;
00064 
00065   static const unsigned int FLAG_BAD;
00066 
00067   virtual ~Thread();
00068 
00069   virtual void init();
00070           bool prepare_finalize();
00071   virtual bool prepare_finalize_user();
00072   virtual void finalize();
00073           void cancel_finalize();
00074 
00075   void start(bool wait=true);
00076   void cancel();
00077   void join();
00078   void detach();
00079   void kill(int sig);
00080 
00081   bool operator==(const Thread &thread);
00082 
00083   void wakeup();
00084   void wakeup(Barrier *barrier);
00085 
00086   void wait_loop_done();
00087 
00088   OpMode        opmode() const;
00089   pthread_t     thread_id() const;
00090   bool          started() const;
00091   bool          cancelled() const;
00092   bool          detached() const;
00093   bool          running() const;
00094   bool          waiting() const;
00095   const char *  name() const { return __name; }
00096 
00097   void  set_flags(uint32_t flags);
00098   void  set_flag(uint32_t flag);
00099   void  unset_flag(uint32_t flag);
00100   bool  flagged_bad() const;
00101 
00102   static Thread *  current_thread();
00103   static Thread *  current_thread_noexc() throw();
00104   static pthread_t current_thread_id();
00105 
00106   static void      init_main();
00107   static void      destroy_main();
00108 
00109   static void      set_cancel_state(CancelState new_state, CancelState *old_state = 0);
00110 
00111   void set_delete_on_exit(bool del);
00112   void set_prepfin_hold(bool hold);
00113 
00114   void add_notification_listener(ThreadNotificationListener *notification_listener);
00115   void remove_notification_listener(ThreadNotificationListener *notification_listener);
00116 
00117  protected:
00118   Thread(const char *name);
00119   Thread(const char *name, OpMode op_mode);
00120   void exit();
00121   void test_cancel();
00122   void yield();
00123   virtual void run();
00124 
00125   void set_opmode(OpMode op_mode);
00126   void set_prepfin_conc_loop(bool concurrent = true);
00127   void set_coalesce_wakeups(bool coalesce = true);
00128 
00129   void set_name(const char *format, ...);
00130 
00131   virtual void once();
00132   virtual void loop();
00133 
00134   bool         wakeup_pending();
00135 
00136   bool           finalize_prepared;
00137   mutable Mutex *loop_mutex;
00138   Mutex         *loopinterrupt_antistarve_mutex;
00139 
00140  private:
00141   Thread(const Thread &t);
00142   Thread(const char *name, pthread_t id);
00143   Thread & operator=(const Thread &t);
00144   static void * entry(void * pthis);
00145   void __constructor(const char *name, OpMode op_mode);
00146   void notify_of_failed_init();
00147   void notify_of_startup();
00148   void lock_sleep_mutex();
00149 
00150   static void init_thread_key();
00151   static void set_tsd_thread_instance(Thread *t);
00152 
00153   pthread_t      __thread_id;
00154 
00155   Barrier       *__startup_barrier;
00156   mutable Mutex *__sleep_mutex;
00157   WaitCondition *__sleep_condition;
00158   unsigned int   __pending_wakeups;
00159   Barrier       *__barrier;
00160 
00161   bool           __loop_done;
00162   Mutex         *__loop_done_mutex;
00163   WaitCondition *__loop_done_waitcond;
00164 
00165   bool           __prepfin_hold;
00166   Mutex         *__prepfin_hold_mutex;
00167   WaitCondition *__prepfin_hold_waitcond;
00168 
00169   bool           __started;
00170   bool           __cancelled;
00171   bool           __detached;
00172   bool           __waiting_for_wakeup;
00173   bool           __delete_on_exit;
00174   bool           __wait;
00175   char          *__name;
00176 
00177   OpMode         __op_mode;
00178   bool           __prepfin_conc_loop;
00179   bool           __coalesce_wakeups;
00180 
00181   uint32_t       __flags;
00182 
00183   LockList<ThreadNotificationListener *>  *__notification_listeners;
00184 
00185   static pthread_key_t   THREAD_KEY;
00186   static pthread_key_t   MAIN_THREAD_KEY;
00187   static pthread_mutex_t __thread_key_mutex;
00188 };
00189 
00190 
00191 } // end namespace fawkes
00192 
00193 #endif