Main Page Class Hierarchy Alphabetical List Compound List File List Compound Members
|
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,2006 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.40 2006/03/16 22:22:43 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 signaled, 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 * Note that the wait-time is specified in nanoseconds 00142 * since the Epoch (Jan 1, 1970). 00143 */ 00144 FXbool wait(FXMutex& mtx,FXlong nsec); 00145 00146 /** 00147 * Wake or unblock a single blocked thread 00148 */ 00149 void signal(); 00150 00151 /** 00152 * Wake or unblock all blocked threads 00153 */ 00154 void broadcast(); 00155 00156 /// Delete the condition 00157 ~FXCondition(); 00158 }; 00159 00160 00161 /** 00162 * A semaphore allows for protection of a resource that can 00163 * be accessed by a fixed number of simultaneous threads. 00164 */ 00165 class FXSemaphore { 00166 private: 00167 FXuval data[16]; 00168 private: 00169 FXSemaphore(const FXSemaphore&); 00170 FXSemaphore& operator=(const FXSemaphore&); 00171 public: 00172 00173 /// Initialize semaphore with given count 00174 FXSemaphore(FXint initial=1); 00175 00176 /// Decrement semaphore 00177 void wait(); 00178 00179 /// Non-blocking semaphore decrement; return true if locked 00180 FXbool trywait(); 00181 00182 /// Increment semaphore 00183 void post(); 00184 00185 /// Delete semaphore 00186 ~FXSemaphore(); 00187 }; 00188 00189 00190 /** 00191 * FXThread provides system-independent support for threads. 00192 * Subclasses must implement the run() function do implement 00193 * the desired functionality of the thread. 00194 * The storage of the FXThread object is to be managed by the 00195 * calling thread, not by the thread itself. 00196 */ 00197 class FXAPI FXThread { 00198 private: 00199 FXThreadID tid; 00200 private: 00201 FXThread(const FXThread&); 00202 FXThread &operator=(const FXThread&); 00203 #ifdef WIN32 00204 static unsigned int CALLBACK execute(void*); 00205 #else 00206 static void* execute(void*); 00207 #endif 00208 protected: 00209 00210 /** 00211 * All threads execute by deriving the run method of FXThread. 00212 * If an uncaught exception was thrown, this function returns -1. 00213 */ 00214 virtual FXint run() = 0; 00215 00216 public: 00217 00218 /// Initialize thread object. 00219 FXThread(); 00220 00221 /** 00222 * Return handle of this thread object. 00223 * This handle is valid in the context of the thread which 00224 * called start(). 00225 */ 00226 FXThreadID id() const; 00227 00228 /** 00229 * Return TRUE if this thread is running. 00230 */ 00231 FXbool running() const; 00232 00233 /** 00234 * Start thread; the thread is started as attached. 00235 * The thread is given stacksize for its stack; a value of 00236 * zero for stacksize will give it the default stack size. 00237 */ 00238 FXbool start(unsigned long stacksize=0); 00239 00240 /** 00241 * Suspend calling thread until thread is done. 00242 */ 00243 FXbool join(); 00244 00245 /** 00246 * Suspend calling thread until thread is done, and set code to the 00247 * return value of run() or the argument passed into exit(). 00248 * If an exception happened in the thread, return -1. 00249 */ 00250 FXbool join(FXint& code); 00251 00252 /** 00253 * Cancel the thread, stopping it immediately, running or not. 00254 * If the calling thread is this thread, nothing happens. 00255 * It is probably better to wait until it is finished, in case the 00256 * thread currently holds mutexes. 00257 */ 00258 FXbool cancel(); 00259 00260 /** 00261 * Detach thread, so that a no join() is necessary to harvest the 00262 * resources of this thread. 00263 */ 00264 FXbool detach(); 00265 00266 /** 00267 * Exit the calling thread. 00268 * No destructors are invoked for objects on thread's stack; 00269 * to invoke destructors, throw an exception instead. 00270 */ 00271 static void exit(FXint code=0); 00272 00273 /** 00274 * Make the thread yield its time quantum. 00275 */ 00276 static void yield(); 00277 00278 /** 00279 * Return time in nanoseconds since Epoch (Jan 1, 1970). 00280 */ 00281 static FXlong time(); 00282 00283 /** 00284 * Make the calling thread sleep for a number of nanoseconds. 00285 */ 00286 static void sleep(FXlong nsec); 00287 00288 /** 00289 * Wake at appointed time specified in nanoseconds since Epoch. 00290 */ 00291 static void wakeat(FXlong nsec); 00292 00293 /** 00294 * Return pointer to the FXThread instance associated 00295 * with the calling thread; it returns NULL for the main 00296 * thread and all threads not created by FOX. 00297 */ 00298 static FXThread* self(); 00299 00300 /** 00301 * Return thread id of calling thread. 00302 */ 00303 static FXThreadID current(); 00304 00305 /** 00306 * Set thread priority. 00307 */ 00308 void priority(FXint prio); 00309 00310 /** 00311 * Return thread priority. 00312 */ 00313 FXint priority(); 00314 00315 /** 00316 * Destroy the thread immediately, running or not. 00317 * It is probably better to wait until it is finished, in case 00318 * the thread currently holds mutexes. 00319 */ 00320 virtual ~FXThread(); 00321 }; 00322 00323 } 00324 00325 #endif 00326
Copyright © 1997-2005 Jeroen van der Zijp |