00001 /* 00002 wefts_thread.h 00003 Main thread class 00004 00005 $Id: wefts_thread.h,v 1.17 2004/03/13 16:10:18 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 00049 Counter &startedThreads(); 00050 00051 00052 00125 class Thread 00126 { 00127 private: 00139 inline virtual void executionEnd() { m_running = false; } 00140 00142 void setCancel() { setCancel( m_canCancel ); } 00143 00145 CleanupList m_cleanupHandlers; 00146 00147 friend void s_ThreadCleanupper( void *); 00148 friend void *s_ThreadRunner( void *); 00149 friend void *s_ThreadRunFunc( void *); 00150 00152 OSPriority m_reqPriority; 00153 00155 int m_reqBoost; 00156 00158 Mutex m_guard; 00159 00161 void *m_runReturn; 00162 00163 protected: 00165 OSThread m_thread; 00167 bool m_canCancel; 00169 void *m_thread_data; 00171 bool m_detached; 00173 bool m_stopped; 00175 bool m_wasCanceled; 00176 00180 volatile bool m_running; 00181 00185 int m_thSequence; 00186 00194 void testCancel() { m_thread.testCancel(); if ( m_stopped ) m_thread.exit(0); } 00195 00203 void setCancel( bool cando ); 00204 00216 void doDetach() { m_thread.detach(); } 00217 00218 00219 public: 00250 Thread( OSPriority prio = PrioNormal, int boost = 0); 00251 00255 virtual ~Thread(); 00256 00265 bool start( bool detachable = false, bool cancelable = true ); 00266 00287 bool stop(); 00288 00300 void detach() { 00301 m_guard.lock(); 00302 m_detached = true; 00303 m_guard.unlock(); 00304 } 00305 00307 bool detached() { 00308 volatile bool ret; 00309 m_guard.lock(); 00310 ret = m_detached; 00311 m_guard.unlock(); 00312 return ret; 00313 } 00314 00333 virtual void *join() throw( NotJoinableError ); 00334 00346 bool running() { 00347 bool ret; 00348 m_guard.lock(); 00349 ret = m_running; 00350 m_guard.unlock(); 00351 return ret; 00352 } 00353 00355 OSThread *getThread() { return &m_thread; } 00356 00358 inline void setData( void *data ) { 00359 m_guard.lock(); 00360 m_thread_data = data; 00361 m_guard.unlock(); 00362 } 00363 00371 inline int sequence() const { return m_thSequence; } 00372 00404 virtual void cleanup(); 00405 00420 bool pushCleanup( CleanupHandler *handler, int value=0 ) 00421 { 00422 //avoid pushing a cleanup handler while the thread is diyng 00423 m_guard.lock(); 00424 if ( m_stopped && ! m_running ) { 00425 m_guard.unlock(); 00426 return false; 00427 } 00428 // don't push "this" as caller: we'll directly send "this" at cleanup. 00429 m_cleanupHandlers.push( CleanupItem( handler, value ) ); 00430 m_guard.unlock(); 00431 return true; 00432 } 00433 00447 bool popCleanup( bool execute=false ) 00448 { 00449 m_guard.lock(); 00450 if ( m_stopped && ! m_running ) { 00451 m_guard.unlock(); 00452 return false; 00453 } 00454 00455 if ( m_cleanupHandlers.size() > 0 ) { 00456 if ( execute ) { 00457 m_cleanupHandlers.top().handler-> 00458 handleCleanup( m_cleanupHandlers.top().position, this ); 00459 } 00460 m_cleanupHandlers.pop(); 00461 m_guard.unlock(); 00462 return true; 00463 } 00464 m_guard.unlock(); 00465 return false; 00466 } 00467 00474 bool priority( OSPriority Prio, int boost = 0 ); 00475 00512 virtual void *run()=0; 00513 00517 void *getRunReturn() { return m_runReturn; } 00518 }; 00519 00520 } 00521 00522 #endif 00523 /* end of wefts_thread.h */