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

FXThread.h
Go to the documentation of this file.
1 /********************************************************************************
2 * *
3 * M u l i t h r e a d i n g S u p p o r t *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2004,2006 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU Lesser General Public *
10 * License as published by the Free Software Foundation; either *
11 * version 2.1 of the License, or (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16 * Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public *
19 * License along with this library; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 *********************************************************************************
22 * $Id: FXThread.h,v 1.40.2.2 2006/07/26 15:25:53 fox Exp $ *
23 ********************************************************************************/
24 #ifndef FXTHREAD_H
25 #define FXTHREAD_H
26 
27 namespace FX {
28 
29 
30 // Thread ID type
31 #ifndef WIN32
32 typedef unsigned long FXThreadID;
33 #else
34 typedef void* FXThreadID;
35 #endif
36 
37 
38 class FXCondition;
39 
40 
41 /**
42 * FXMutex provides a mutex which can be used to enforce critical
43 * sections around updates of data shared by multiple threads.
44 */
45 class FXAPI FXMutex {
46  friend class FXCondition;
47 private:
48  FXuval data[24];
49 private:
50  FXMutex(const FXMutex&);
51  FXMutex &operator=(const FXMutex&);
52 public:
53 
54  /// Initialize the mutex
55  FXMutex(FXbool recursive=FALSE);
56 
57  /// Lock the mutex
58  void lock();
59 
60  /// Return TRUE if succeeded locking the mutex
61  FXbool trylock();
62 
63  /// Return TRUE if mutex is already locked
64  FXbool locked();
65 
66  /// Unlock mutex
67  void unlock();
68 
69  /// Delete the mutex
70  ~FXMutex();
71  };
72 
73 
74 /**
75 * An easy way to establish a correspondence between a C++ scope
76 * and a critical section is to simply declare an FXMutexLock
77 * at the beginning of the scope.
78 * The mutex will be automatically released when the scope is
79 * left (either by natural means or by means of an exception.
80 */
81 class FXAPI FXMutexLock {
82 private:
83  FXMutex& mtx;
84 private:
85  FXMutexLock();
87  FXMutexLock& operator=(const FXMutexLock&);
88 public:
89 
90  /// Construct & lock associated mutex
91  FXMutexLock(FXMutex& m):mtx(m){ lock(); }
92 
93  /// Return reference to associated mutex
94  FXMutex& mutex(){ return mtx; }
95 
96  /// Lock mutex
97  void lock(){ mtx.lock(); }
98 
99  /// Return TRUE if succeeded locking the mutex
100  FXbool trylock(){ return mtx.trylock(); }
101 
102  /// Return TRUE if mutex is already locked
103  FXbool locked(){ return mtx.locked(); }
104 
105  /// Unlock mutex
106  void unlock(){ mtx.unlock(); }
107 
108  /// Destroy and unlock associated mutex
109  ~FXMutexLock(){ unlock(); }
110  };
111 
112 
113 /**
114 * A condition allows one or more threads to synchronize
115 * to an event. When a thread calls wait, the associated
116 * mutex is unlocked while the thread is blocked. When the
117 * condition becomes signaled, the associated mutex is
118 * locked and the thread(s) are reawakened.
119 */
120 class FXAPI FXCondition {
121 private:
122  FXuval data[12];
123 private:
124  FXCondition(const FXCondition&);
125  FXCondition& operator=(const FXCondition&);
126 public:
127 
128  /// Initialize the condition
129  FXCondition();
130 
131  /**
132  * Wait until condition becomes signalled, using given mutex,
133  * which must already have been locked prior to this call.
134  */
135  void wait(FXMutex& mtx);
136 
137  /**
138  * Wait until condition becomes signalled, using given mutex,
139  * which must already have been locked prior to this call.
140  * Returns TRUE if successful, FALSE if timeout occurred.
141  * Note that the wait-time is specified in nanoseconds
142  * since the Epoch (Jan 1, 1970).
143  */
144  FXbool wait(FXMutex& mtx,FXlong nsec);
145 
146  /**
147  * Wake or unblock a single blocked thread
148  */
149  void signal();
150 
151  /**
152  * Wake or unblock all blocked threads
153  */
154  void broadcast();
155 
156  /// Delete the condition
157  ~FXCondition();
158  };
159 
160 
161 /**
162 * A semaphore allows for protection of a resource that can
163 * be accessed by a fixed number of simultaneous threads.
164 */
165 class FXAPI FXSemaphore {
166 private:
167  FXuval data[16];
168 private:
169  FXSemaphore(const FXSemaphore&);
170  FXSemaphore& operator=(const FXSemaphore&);
171 public:
172 
173  /// Initialize semaphore with given count
174  FXSemaphore(FXint initial=1);
175 
176  /// Decrement semaphore
177  void wait();
178 
179  /// Non-blocking semaphore decrement; return true if locked
180  FXbool trywait();
181 
182  /// Increment semaphore
183  void post();
184 
185  /// Delete semaphore
186  ~FXSemaphore();
187  };
188 
189 
190 /**
191 * FXThread provides system-independent support for threads.
192 * Subclasses must implement the run() function do implement
193 * the desired functionality of the thread.
194 * The storage of the FXThread object is to be managed by the
195 * calling thread, not by the thread itself.
196 */
197 class FXAPI FXThread {
198 private:
199  volatile FXThreadID tid;
200 private:
201  FXThread(const FXThread&);
202  FXThread &operator=(const FXThread&);
203 #ifdef WIN32
204  static unsigned int CALLBACK execute(void*);
205 #else
206  static void* execute(void*);
207 #endif
208 protected:
209 
210  /**
211  * All threads execute by deriving the run method of FXThread.
212  * If an uncaught exception was thrown, this function returns -1.
213  */
214  virtual FXint run() = 0;
215 
216 public:
217 
218  /// Initialize thread object.
219  FXThread();
220 
221  /**
222  * Return handle of this thread object.
223  * This handle is valid in the context of the thread which
224  * called start().
225  */
226  FXThreadID id() const;
227 
228  /**
229  * Return TRUE if this thread is running.
230  */
231  FXbool running() const;
232 
233  /**
234  * Start thread; the thread is started as attached.
235  * The thread is given stacksize for its stack; a value of
236  * zero for stacksize will give it the default stack size.
237  */
238  FXbool start(unsigned long stacksize=0);
239 
240  /**
241  * Suspend calling thread until thread is done.
242  */
243  FXbool join();
244 
245  /**
246  * Suspend calling thread until thread is done, and set code to the
247  * return value of run() or the argument passed into exit().
248  * If an exception happened in the thread, return -1.
249  */
250  FXbool join(FXint& code);
251 
252  /**
253  * Cancel the thread, stopping it immediately, running or not.
254  * If the calling thread is this thread, nothing happens.
255  * It is probably better to wait until it is finished, in case the
256  * thread currently holds mutexes.
257  */
258  FXbool cancel();
259 
260  /**
261  * Detach thread, so that a no join() is necessary to harvest the
262  * resources of this thread.
263  */
264  FXbool detach();
265 
266  /**
267  * Exit the calling thread.
268  * No destructors are invoked for objects on thread's stack;
269  * to invoke destructors, throw an exception instead.
270  */
271  static void exit(FXint code=0);
272 
273  /**
274  * Make the thread yield its time quantum.
275  */
276  static void yield();
277 
278  /**
279  * Return time in nanoseconds since Epoch (Jan 1, 1970).
280  */
281  static FXlong time();
282 
283  /**
284  * Make the calling thread sleep for a number of nanoseconds.
285  */
286  static void sleep(FXlong nsec);
287 
288  /**
289  * Wake at appointed time specified in nanoseconds since Epoch.
290  */
291  static void wakeat(FXlong nsec);
292 
293  /**
294  * Return pointer to the FXThread instance associated
295  * with the calling thread; it returns NULL for the main
296  * thread and all threads not created by FOX.
297  */
298  static FXThread* self();
299 
300  /**
301  * Return thread id of calling thread.
302  */
303  static FXThreadID current();
304 
305  /**
306  * Set thread priority.
307  */
308  void priority(FXint prio);
309 
310  /**
311  * Return thread priority.
312  */
313  FXint priority();
314 
315  /**
316  * Destroy the thread immediately, running or not.
317  * It is probably better to wait until it is finished, in case
318  * the thread currently holds mutexes.
319  */
320  virtual ~FXThread();
321  };
322 
323 }
324 
325 #endif
326 
FXString time(FXTime value)
Convert time value to date-string.
FXbool trylock()
Return TRUE if succeeded locking the mutex.
An easy way to establish a correspondence between a C++ scope and a critical section is to simply dec...
Definition: FXThread.h:76
#define FXAPI
Definition: fxdefs.h:122
A semaphore allows for protection of a resource that can be accessed by a fixed number of simultaneou...
Definition: FXThread.h:149
FXuchar FXbool
Definition: fxdefs.h:386
A condition allows one or more threads to synchronize to an event.
Definition: FXThread.h:109
FXThread provides system-independent support for threads.
Definition: FXThread.h:176
void lock()
Lock the mutex.
void unlock()
Unlock mutex.
FXbool locked()
Return TRUE if mutex is already locked.
Definition: FX4Splitter.h:31
int FXint
Definition: fxdefs.h:390
unsigned long FXThreadID
Definition: FXThread.h:32
#define FALSE
Definition: fxdefs.h:35
FXMutex provides a mutex which can be used to enforce critical sections around updates of data shared...
Definition: FXThread.h:45
unsigned long FXuval
Definition: fxdefs.h:429

Copyright © 1997-2005 Jeroen van der Zijp