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

FXThread.h

Go to the documentation of this file.
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