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   OpMode        opmode() const;
00087   pthread_t     thread_id() const;
00088   bool          started() const;
00089   bool          cancelled() const;
00090   bool          detached() const;
00091   bool          running() const;
00092   bool          waiting() const;
00093   const char *  name() const { return __name; }
00094 
00095   void  set_flags(uint32_t flags);
00096   void  set_flag(uint32_t flag);
00097   void  unset_flag(uint32_t flag);
00098   bool  flagged_bad() const;
00099 
00100   static Thread *  current_thread();
00101   static Thread *  current_thread_noexc() throw();
00102   static pthread_t current_thread_id();
00103 
00104   static void      init_main();
00105   static void      destroy_main();
00106 
00107   static void      set_cancel_state(CancelState new_state, CancelState *old_state = 0);
00108 
00109   void set_delete_on_exit(bool del);
00110   void set_prepfin_hold(bool hold);
00111 
00112   void add_notification_listener(ThreadNotificationListener *notification_listener);
00113   void remove_notification_listener(ThreadNotificationListener *notification_listener);
00114 
00115  protected:
00116   Thread(const char *name);
00117   Thread(const char *name, OpMode op_mode);
00118   void exit();
00119   void test_cancel();
00120   void yield();
00121   virtual void run();
00122 
00123   void set_opmode(OpMode op_mode);
00124   void set_prepfin_conc_loop(bool concurrent = true);
00125   void set_coalesce_wakeups(bool coalesce = true);
00126 
00127   void set_name(const char *format, ...);
00128 
00129   virtual void once();
00130   virtual void loop();
00131 
00132   bool         wakeup_pending();
00133 
00134   bool           finalize_prepared;
00135   mutable Mutex *loop_mutex;
00136   Mutex         *loopinterrupt_antistarve_mutex;
00137 
00138  private:
00139   Thread(const Thread &t);
00140   Thread(const char *name, pthread_t id);
00141   Thread & operator=(const Thread &t);
00142   static void * entry(void * pthis);
00143   void __constructor(const char *name, OpMode op_mode);
00144   void notify_of_failed_init();
00145   void notify_of_startup();
00146   void lock_sleep_mutex();
00147 
00148   static void init_thread_key();
00149   static void set_tsd_thread_instance(Thread *t);
00150 
00151   pthread_t      __thread_id;
00152 
00153   Barrier       *__startup_barrier;
00154   mutable Mutex *__sleep_mutex;
00155   WaitCondition *__sleep_condition;
00156   unsigned int   __pending_wakeups;
00157   Barrier       *__barrier;
00158 
00159   bool           __prepfin_hold;
00160   Mutex         *__prepfin_hold_mutex;
00161   WaitCondition *__prepfin_hold_waitcond;
00162 
00163   bool           __started;
00164   bool           __cancelled;
00165   bool           __detached;
00166   bool           __waiting_for_wakeup;
00167   bool           __delete_on_exit;
00168   bool           __wait;
00169   char          *__name;
00170 
00171   OpMode         __op_mode;
00172   bool           __prepfin_conc_loop;
00173   bool           __coalesce_wakeups;
00174 
00175   uint32_t       __flags;
00176 
00177   LockList<ThreadNotificationListener *>  *__notification_listeners;
00178 
00179   static pthread_key_t   THREAD_KEY;
00180   static pthread_key_t   MAIN_THREAD_KEY;
00181   static pthread_mutex_t __thread_key_mutex;
00182 };
00183 
00184 
00185 } // end namespace fawkes
00186 
00187 #endif