| Tekkotsu Homepage | Demos | Overview | Downloads | Dev. Resources | Reference | Credits |
Thread.hGo to the documentation of this file.00001 //-*-c++-*- 00002 #ifndef INCLUDED_Thread_h_ 00003 #define INCLUDED_Thread_h_ 00004 00005 #ifdef PLATFORM_APERIOS 00006 # warning Thread class is not Aperios compatable 00007 #else 00008 00009 #include "Shared/Resource.h" 00010 #include <stddef.h> 00011 00012 //! provides Thread related data structures 00013 namespace ThreadNS { 00014 //! an inter-thread lock -- doesn't work across processes, only threads within a process. (see MutexLock for inter-process locks) 00015 class Lock : public Resource { 00016 public: 00017 Lock(); //!< constructor 00018 //explicit Lock(const Lock& l); //!< copy constructor -- shallow copy, share a lock, is handy for locking over a scope!!! (lock is automatically obtained on copy -- to avoid autolock, pass false to the two-argument constructor: Lock(const Lock& l, bool autolock) ) 00019 //Lock(const Lock& l, bool autolock); //!< copy constructor -- shallow copy, share a lock, is handy for locking over a scope!!! 00020 //Lock& operator=(const Lock& l); //!< assignment -- dereference (and release) any previous lock, take on the new storage (shallow copy!) 00021 ~Lock(); //!< destructor -- dereference and release (if any references remain) 00022 void lock(); //!< block until lock is obtained 00023 bool trylock(); //!< see if lock is available 00024 void unlock(); //!< release lock, if held 00025 unsigned int getInstanceLockLevel() const { return locklevel; } //!< returns the lock level of the local instance of Lock (as opposed to the lock storage structure, which might be shared with other Lock instances) 00026 unsigned int getLockLevel() const; //!< returns the lock level of the lock storage itself, the sum of all instance's lock levels 00027 protected: 00028 friend class MarkScope; 00029 virtual void useResource(Resource::Data&) { lock(); } 00030 virtual void releaseResource(Resource::Data&) { unlock(); } 00031 00032 class LockStorage; //!< this internal class will hold the system-dependent lock information 00033 static LockStorage* glock; //!< The global lock to protect Locks sharing #mylock's 00034 LockStorage* mylock; //!< This lock's implementation 00035 static void setup(); //!< creates a new #glock if it is currently NULL (should be called by the Lock() constructor) 00036 unsigned int locklevel; //!< the current lock level from this Lock, may differ from #mylock's lock level if several Locks are sharing a storage! 00037 private: 00038 Lock(const Lock& l); //!< don't call 00039 Lock& operator=(const Lock& l); //!< don't call 00040 }; 00041 } 00042 00043 //! Provides a nice wrapping of pthreads library 00044 /*! If you need to provide cleanup functions on stop(), cancelled(), etc., you 00045 * should override the destructor to stop and join so that you can be assured 00046 * that your cleanup will be called if the thread is auto-destructed by going out of scope */ 00047 class Thread { 00048 public: 00049 typedef ThreadNS::Lock Lock; //!< shorthand for pthread lock wrapper 00050 00051 Thread(); //!< constructor, does not start thread by itself (although subclasses may) 00052 virtual ~Thread()=0; //!< destructor, will stop and join the thread, but you should override it to do the same if you provide any cleanup functions 00053 00054 //! requests that the thread be started, if not already running (you need to create a separate instances if you want to run multiple copies) 00055 virtual void start(); 00056 00057 //! requests that the thread be stopped gracefully, if running. 00058 /*! A cancel flag is sent, and the thread will be stopped at next cancel point, defined 00059 * by whenever testCancel(), or a set of other system functions, are called. 00060 * See your system's pthread_testcancel() manual page for a list of cancel points. 00061 * @see pushNoCancel(), popNoCancel() */ 00062 virtual void stop(); 00063 00064 //! sends a SIGUSR1 to the thread, breaking its execution, but still allowing handle_exit (and thus cancelled()) to be called. 00065 /*! Beware if your thread uses mutual exclusion locks, this can cause the thread to terminate while still holding locks */ 00066 virtual void kill(); 00067 00068 //! detaches thread and sends SIGSTOP, which immediately halts the thread without any chance for cleanup 00069 /*! Beware if your thread uses mutual exclusion locks, this @b will cause the thread to terminate while still holding locks. */ 00070 virtual void murder(); 00071 00072 //! sends a signal to the thread 00073 virtual void sendSignal(int sig); 00074 00075 //! blocks calling thread until this Thread has terminated, via one means or another; return value is final return value by the thread 00076 virtual void * join(); 00077 00078 //! indicates whether start() has been previously called 00079 virtual bool isRunning() const { return running; } 00080 00081 //! returns the Thread object for the current thread (or NULL for the main thread) 00082 static Thread* getCurrent() ; 00083 00084 //! should be called before any threads are created to allow some global thread-specific data to be set up 00085 static void initMainThread(); 00086 //! should be called if you no longer expect to have any threads in use 00087 static void releaseMainThread(); 00088 00089 //! should be called whenever a critical section has been entered (i.e. mutex obtained) -- prevents cancel from occurring until popNoCancel() is called 00090 static void pushNoCancel(); 00091 //! should be called whenever a critical section is left (i.e. mutex released) -- if it was the last one, tests cancellability as well 00092 static void popNoCancel(); 00093 00094 protected: 00095 //! called by launch() when thread is first entered, return false to cancel launch (set #returnValue as well if you care) 00096 virtual bool launched() { return true; } 00097 //! called by launch() once the thread has been set up; when this returns, the thread ends, see runloop() 00098 /*! Default implementation repeatedly calls runloop(), usleep(), and testCancel(). 00099 * If you override, you should also be sure to call testCancel occasionally in order to support stop() 00100 * If function returns a value, that value overrides #returnValue. If cancel occurs, #returnValue is used. */ 00101 virtual void * run(); 00102 //! override this as a convenient way to define your thread -- return the number of *micro*seconds to sleep before the next call; return -1U to indicate end of processing 00103 virtual unsigned int runloop() { return -1U; } 00104 //! called when handle_exit() is triggered, either by the thread being cancelled, or when run() has returned voluntarily 00105 virtual void cancelled() {} 00106 00107 //! checks to see if stop() has been called, and if so, will exit the thread (passing through handle_exit() first) 00108 virtual void testCancel(); 00109 //! thread entry point -- calls launched() on the thread (as indicated by @a msg), and then run() 00110 static void * launch(void * msg); 00111 //! indicates kill() has been called (or SIGUSR1 was sent from some other source) while launch() was still running 00112 static void handle_launch_signal(int sig); 00113 //! indicates kill() has been called (or SIGUSR1 was sent from some other source) 00114 static void handle_signal(int sig); 00115 //! indicates the thread is exiting, either voluntary (run() returned), stop(), or kill() -- calls cancelled() for the thread as indicated by @a th 00116 static void handle_exit(void * th); 00117 00118 //! emit a warning that the last thread exited while the self-pointer thread-specific key still exists (need to call releaseMainThread() or handle_exit()) 00119 static void warnSelfUndestructed(void* msg); 00120 00121 //! stores the actual pthread data fields 00122 struct Threadstorage_t * pt; 00123 //! set to true once start has been called, set back to false by handle_exit(), or by murder() itself 00124 bool running; 00125 //! indicates the value to be returned by the thread entry point (and thus passed back to join()) -- set this in runloop() or launched(), overridden by run()'s return value 00126 void * returnValue; 00127 //! depth of the pushNoCancel() stack 00128 unsigned int noCancelDepth; 00129 //! cancel status at root of no-cancel stack (may be no-cancel through and through) 00130 int cancelOrig; 00131 00132 private: 00133 Thread(const Thread& r); //!< don't call, not a well defined operation 00134 Thread& operator=(const Thread& r); //!< don't call, not a well defined operation 00135 }; 00136 00137 #endif //Aperios check 00138 00139 #endif 00140 00141 /*! @file 00142 * @brief Describes the Thread class and its AutoThread templated subclass 00143 * @author ejt (Creator) 00144 * 00145 * $Author: ejt $ 00146 * $Name: tekkotsu-3_0 $ 00147 * $Revision: 1.12 $ 00148 * $State: Exp $ 00149 * $Date: 2006/06/16 21:49:23 $ 00150 */ 00151 |
|
Tekkotsu v3.0 |
Generated Wed Oct 4 00:03:46 2006 by Doxygen 1.4.7 |