00001 /* 00002 wefts_thread.h 00003 Main thread class 00004 00005 $Id: wefts_thread.h,v 1.9 2003/12/16 03:07:48 jonnymind Exp $ 00006 --------------------------------------------- 00007 Begin : 2003-08-02 23:45 00008 Author : Giancarlo Niccolai 00009 00010 Last modified because: 00011 Implementing OS independent base threading 00012 */ 00013 00014 /************************************************************************** 00015 * This program is free software; you can redistribute it and/or modify * 00016 * it under the terms of the GNU Library General Public License as * 00017 * published by the Free Software Foundation; either version 2.1 of the * 00018 * License, or (at your option) any later version. * 00019 ***************************************************************************/ 00020 00021 #ifndef WT_THREAD_H 00022 #define WT_THREAD_H 00023 00024 #include <wefts_os.h> 00025 #include <wefts_counter.h> 00026 #include <wefts_cleanup.h> 00027 #include <stack> 00028 00029 namespace Wefts { 00030 00037 extern Counter runningThreads; 00038 00045 extern Counter startedThreads; 00046 00047 00048 00121 class Thread 00122 { 00123 private: 00135 inline virtual void executionEnd() { m_running = false; } 00136 00138 void setCancel() { setCancel( m_canCancel ); } 00139 00141 CleanupList m_cleanupHandlers; 00142 00143 friend void s_ThreadCleanupper( void *); 00144 friend void s_ThreadRunner( void *); 00145 friend void *s_ThreadRunFunc( void *); 00146 00147 protected: 00149 void *m_runReturnValue; 00151 OSThread m_thread; 00153 bool m_canCancel; 00155 void *m_thread_data; 00157 bool m_detached; 00159 volatile bool m_stopped; 00160 00164 volatile bool m_running; 00165 00169 int m_thSequence; 00170 00178 void testCancel() { m_thread.testCancel(); if ( m_stopped ) m_thread.exit(0); } 00179 00187 void setCancel( bool cando ); 00188 00200 void doDetach() { m_thread.detach(); } 00201 00205 void setReturn( void *ret ) { m_runReturnValue = ret; } 00206 00207 public: 00209 Thread(); 00210 00214 virtual ~Thread(); 00215 00224 bool start( bool detachable = false, bool cancelable = true ); 00225 00233 bool stop(); 00234 00246 void detach() { m_detached = true; } 00248 bool detached() const { return m_detached; } 00249 00268 virtual void *join() throw( NotJoinableError ); 00269 00281 bool running() const { return m_running; } 00282 00284 OSThread *getThread() { return &m_thread; } 00285 00287 inline void setData( void *data ) { m_thread_data = data; } 00288 00296 inline int sequence() const { return m_thSequence; } 00297 00329 virtual void cleanup(); 00330 00345 bool pushCleanup( CleanupHandler *handler, int value=0 ) 00346 { 00347 //avoid pushing a cleanup handler while the thread is diyng 00348 if ( m_stopped ) return false; 00349 m_cleanupHandlers.push( CleanupItem( handler, value ) ); 00350 return true; 00351 } 00352 00366 bool popCleanup( bool execute=false ) 00367 { 00368 if ( m_stopped ) 00369 return false; 00370 if ( m_cleanupHandlers.size() > 0 ) { 00371 if ( execute ) 00372 m_cleanupHandlers.top().first-> 00373 handleCleanup( m_cleanupHandlers.top().second ); 00374 m_cleanupHandlers.pop(); 00375 return true; 00376 } 00377 return false; 00378 } 00379 00413 virtual void *run()=0; 00414 00415 }; 00416 00417 } 00418 00419 #endif 00420 /* end of wefts_thread.h */