Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

FXThread.h

00001 /******************************************************************************** 00002 * * 00003 * M u l i t h r e a d i n g S u p p o r t * 00004 * * 00005 ********************************************************************************* 00006 * Copyright (C) 2004,2005 by Jeroen van der Zijp. All Rights Reserved. * 00007 ********************************************************************************* 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU Lesser General Public * 00010 * License as published by the Free Software Foundation; either * 00011 * version 2.1 of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * Lesser General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU Lesser General Public * 00019 * License along with this library; if not, write to the Free Software * 00020 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 00021 ********************************************************************************* 00022 * $Id: FXThread.h,v 1.34.2.1 2005/02/10 15:41:36 fox Exp $ * 00023 ********************************************************************************/ 00024 #ifndef FXTHREAD_H 00025 #define FXTHREAD_H 00026 00027 namespace FX { 00028 00029 00030 // Thread ID type 00031 #ifndef WIN32 00032 typedef unsigned long FXThreadID; 00033 #else 00034 typedef void* FXThreadID; 00035 #endif 00036 00037 00038 class FXCondition; 00039 00040 00041 /** 00042 * FXMutex provides a mutex which can be used to enforce critical 00043 * sections around updates of data shared by multiple threads. 00044 */ 00045 class FXAPI FXMutex { 00046 friend class FXCondition; 00047 private: 00048 FXuval data[24]; 00049 private: 00050 FXMutex(const FXMutex&); 00051 FXMutex &operator=(const FXMutex&); 00052 public: 00053 00054 /// Initialize the mutex 00055 FXMutex(FXbool recursive=FALSE); 00056 00057 /// Lock the mutex 00058 void lock(); 00059 00060 /// Return TRUE if succeeded locking the mutex 00061 FXbool trylock(); 00062 00063 /// Return TRUE if mutex is already locked 00064 FXbool locked(); 00065 00066 /// Unlock mutex 00067 void unlock(); 00068 00069 /// Delete the mutex 00070 ~FXMutex(); 00071 }; 00072 00073 00074 /** 00075 * An easy way to establish a correspondence between a C++ scope 00076 * and a critical section is to simply declare an FXMutexLock 00077 * at the beginning of the scope. 00078 * The mutex will be automatically released when the scope is 00079 * left (either by natural means or by means of an exception. 00080 */ 00081 class FXAPI FXMutexLock { 00082 private: 00083 FXMutex& mtx; 00084 private: 00085 FXMutexLock(); 00086 FXMutexLock(const FXMutexLock&); 00087 FXMutexLock& operator=(const FXMutexLock&); 00088 public: 00089 00090 /// Construct & lock associated mutex 00091 FXMutexLock(FXMutex& m):mtx(m){ lock(); } 00092 00093 /// Return reference to associated mutex 00094 FXMutex& mutex(){ return mtx; } 00095 00096 /// Lock mutex 00097 void lock(){ mtx.lock(); } 00098 00099 /// Return TRUE if succeeded locking the mutex 00100 FXbool trylock(){ return mtx.trylock(); } 00101 00102 /// Return TRUE if mutex is already locked 00103 FXbool locked(){ return mtx.locked(); } 00104 00105 /// Unlock mutex 00106 void unlock(){ mtx.unlock(); } 00107 00108 /// Destroy and unlock associated mutex 00109 ~FXMutexLock(){ unlock(); } 00110 }; 00111 00112 00113 /** 00114 * A condition allows one or more threads to synchronize 00115 * to an event. When a thread calls wait, the associated 00116 * mutex is unlocked while the thread is blocked. When the 00117 * condition becomes signalled, the associated mutex is 00118 * locked and the thread(s) are reawakened. 00119 */ 00120 class FXAPI FXCondition { 00121 private: 00122 FXuval data[12]; 00123 private: 00124 FXCondition(const FXCondition&); 00125 FXCondition& operator=(const FXCondition&); 00126 public: 00127 00128 /// Initialize the condition 00129 FXCondition(); 00130 00131 /** 00132 * Wait until condition becomes signalled, using given mutex, 00133 * which must already have been locked prior to this call. 00134 */ 00135 void wait(FXMutex& mtx); 00136 00137 /** 00138 * Wait until condition becomes signalled, using given mutex, 00139 * which must already have been locked prior to this call. 00140 * Returns TRUE if successful, FALSE if timeout occurred. 00141 */ 00142 FXbool wait(FXMutex& mtx,FXuint ms); 00143 00144 /** 00145 * Wake or unblock a single blocked thread 00146 */ 00147 void signal(); 00148 00149 /** 00150 * Wake or unblock all blocked threads 00151 */ 00152 void broadcast(); 00153 00154 /// Delete the condition 00155 ~FXCondition(); 00156 }; 00157 00158 00159 /** 00160 * A semaphore allows for protection of a resource that can 00161 * be accessed by a fixed number of simultaneous threads. 00162 */ 00163 class FXSemaphore { 00164 private: 00165 FXuval data[16]; 00166 private: 00167 FXSemaphore(const FXSemaphore&); 00168 FXSemaphore& operator=(const FXSemaphore&); 00169 public: 00170 00171 /// Initialize semaphore with given count 00172 FXSemaphore(FXint initial=1); 00173 00174 /// Decrement semaphore 00175 void wait(); 00176 00177 /// Non-blocking semaphore decrement 00178 FXbool trywait(); 00179 00180 /// Increment semaphore 00181 void post(); 00182 00183 /// Delete semaphore 00184 ~FXSemaphore(); 00185 }; 00186 00187 00188 /** 00189 * FXThread provides system-independent support for threads. 00190 * Subclasses must implement the run() function do implement 00191 * the desired functionality of the thread. 00192 * The storage of the FXThread object is to be managed by the 00193 * calling thread, not by the thread itself. 00194 */ 00195 class FXAPI FXThread { 00196 private: 00197 FXThreadID tid; 00198 private: 00199 FXThread(const FXThread&); 00200 FXThread &operator=(const FXThread&); 00201 #ifdef WIN32 00202 static unsigned int CALLBACK execute(void*); 00203 #else 00204 static void* execute(void*); 00205 #endif 00206 protected: 00207 00208 /// All threads execute by deriving the run method of FXThread 00209 virtual FXint run() = 0; 00210 00211 public: 00212 00213 /// Initialize thread object. 00214 FXThread(); 00215 00216 /** 00217 * Return handle of this thread object. 00218 * This handle is valid in the context of the thread which 00219 * called start(). 00220 */ 00221 FXThreadID id() const; 00222 00223 /** 00224 * Return TRUE if this thread is running. 00225 */ 00226 FXbool running() const; 00227 00228 /** 00229 * Start thread; the thread is started as attached. 00230 * The thread is given stacksize for its stack; a value of 00231 * zero for stacksize will give it the default stack size. 00232 */ 00233 FXbool start(unsigned long stacksize=0); 00234 00235 /** 00236 * Suspend calling thread until thread is done. 00237 */ 00238 FXbool join(); 00239 00240 /** 00241 * Suspend calling thread until thread is done, and set code to the 00242 * return value of run() or the argument passed into exit(). 00243 * If an exception happened in the thread, return -1. 00244 */ 00245 FXbool join(FXint& code); 00246 00247 /** 00248 * Cancel the thread, stopping it immediately, running or not. 00249 * If the calling thread is this thread, nothing happens. 00250 * It is probably better to wait until it is finished, in case the 00251 * thread currently holds mutexes. 00252 */ 00253 FXbool cancel(); 00254 00255 /** 00256 * Detach thread, so that a no join() is necessary to harvest the 00257 * resources of this thread. 00258 */ 00259 FXbool detach(); 00260 00261 /** 00262 * Exit the calling thread. 00263 * No destructors are invoked for objects on thread's stack; 00264 * to invoke destructors, throw an exception instead. 00265 */ 00266 static void exit(FXint code=0); 00267 00268 /** 00269 * Make the thread yield its time quantum. 00270 */ 00271 static void yield(); 00272 00273 /** 00274 * Make the calling thread sleep for a number of seconds 00275 * and nanoseconds. 00276 */ 00277 static void sleep(unsigned long sec,unsigned long nsec=0); 00278 00279 /** 00280 * Return pointer to the FXThread instance associated 00281 * with the calling thread; it returns NULL for the main 00282 * thread and all threads not created by FOX. 00283 */ 00284 static FXThread* self(); 00285 00286 /** 00287 * Return thread id of calling thread. 00288 */ 00289 static FXThreadID current(); 00290 00291 /** 00292 * Set thread priority. 00293 */ 00294 void priority(FXint prio); 00295 00296 /** 00297 * Return thread priority. 00298 */ 00299 FXint priority(); 00300 00301 /** 00302 * Destroy the thread immediately, running or not. 00303 * It is probably better to wait until it is finished, in case 00304 * the thread currently holds mutexes. 00305 */ 00306 virtual ~FXThread(); 00307 }; 00308 00309 } 00310 00311 #endif 00312

Copyright © 1997-2005 Jeroen van der Zijp