4 * Executable thread encapsulation class (pre-emptive if OS allows).
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
30 * Revision 1.35 2003/10/08 21:39:34 dereksmithies
31 * Add a #define to cope with backward compatability issues for PThreadIdentifier
32 * Thanks to Andrey S Pankov and Craig Southeren for their input.
34 * Revision 1.34 2003/09/17 05:41:59 csoutheren
35 * Removed recursive includes
37 * Revision 1.33 2003/09/17 01:18:02 csoutheren
38 * Removed recursive include file system and removed all references
39 * to deprecated coooperative threading support
41 * Revision 1.32 2002/10/04 04:33:27 robertj
42 * Added functions for getting operating system thread identifier values.
44 * Revision 1.31 2002/09/16 01:08:59 robertj
45 * Added #define so can select if #pragma interface/implementation is used on
46 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
48 * Revision 1.30 2002/06/27 06:44:28 robertj
49 * Changed "" to PString::Empty() where assigning to PString.
51 * Revision 1.29 2002/04/24 01:49:22 robertj
52 * Fixed error in PTRACE_BLOCk nesting level to now work when no tracing enabled.
54 * Revision 1.28 2002/04/24 01:09:56 robertj
55 * Fixed problem with PTRACE_BLOCK indent level being correct across threads.
57 * Revision 1.27 2001/09/10 02:51:22 robertj
58 * Major change to fix problem with error codes being corrupted in a
59 * PChannel when have simultaneous reads and writes in threads.
61 * Revision 1.26 2001/05/22 12:49:32 robertj
62 * Did some seriously wierd rewrite of platform headers to eliminate the
63 * stupid GNU compiler warning about braces not matching.
65 * Revision 1.25 2000/11/28 12:55:36 robertj
66 * Added static function to create a new thread class and automatically
67 * run a function on another class in the context of that thread.
69 * Revision 1.24 2000/10/20 05:31:09 robertj
70 * Added function to change auto delete flag on a thread.
72 * Revision 1.23 2000/06/26 11:17:19 robertj
73 * Nucleus++ port (incomplete).
75 * Revision 1.22 2000/02/29 12:26:14 robertj
76 * Added named threads to tracing, thanks to Dave Harvey
78 * Revision 1.21 1999/06/06 05:07:17 robertj
79 * Fixed documentation error.
81 * Revision 1.20 1999/03/09 02:59:51 robertj
82 * Changed comments to doc++ compatible documentation.
84 * Revision 1.19 1999/02/16 08:11:17 robertj
85 * MSVC 6.0 compatibility changes.
87 * Revision 1.18 1998/11/20 03:18:33 robertj
88 * Added thread WaitForTermination() function.
90 * Revision 1.17 1998/10/31 12:47:59 robertj
91 * Removed ability to start threads immediately, race condition with vtable (Main() function).
93 * Revision 1.16 1998/09/23 06:21:41 robertj
94 * Added open source copyright license.
96 * Revision 1.15 1996/03/02 03:15:51 robertj
97 * Added automatic deletion of thread object instances on thread completion.
99 * Revision 1.14 1995/12/10 11:44:32 robertj
100 * Fixed bug in non-platform threads and semaphore timeouts.
102 * Revision 1.13 1995/11/21 11:49:44 robertj
103 * Added timeout on semaphore wait.
105 * Revision 1.12 1995/07/31 12:10:40 robertj
106 * Added semaphore class.
108 * Revision 1.11 1995/06/17 11:13:35 robertj
109 * Documentation update.
111 * Revision 1.10 1995/03/14 12:42:49 robertj
112 * Updated documentation to use HTML codes.
114 * Revision 1.9 1995/01/16 09:42:13 robertj
117 * Revision 1.8 1994/09/25 10:45:22 robertj
118 * Virtualised IsNoLongerBlocked for unix platform.
120 * Revision 1.6 1994/08/22 00:46:48 robertj
121 * Added pragma fro GNU C++ compiler.
123 * Revision 1.5 1994/08/21 23:43:02 robertj
124 * Added SuspendBlock state to cooperative multi-threading to fix logic fault.
126 * Revision 1.4 1994/08/04 12:32:22 robertj
127 * Better name of thread block check function.
129 * Revision 1.3 1994/07/21 12:33:49 robertj
130 * Moved cooperative threads to common.
132 * Revision 1.2 1994/07/02 03:03:49 robertj
133 * Added restartable threads.
135 * Revision 1.1 1994/06/25 11:55:15 robertj
153 #define PThreadIdentifer PThreadIdentifier
155 typedef P_THREADIDENTIFIER PThreadIdentifier
;
157 ///////////////////////////////////////////////////////////////////////////////
160 /** This class defines a thread of execution in the system. A {\it thread} is
161 an independent flow of processor instructions. This differs from a
162 {\it process} which also embodies a program address space and resource
163 allocation. So threads can share memory and resources as they run in the
164 context of a given process. A process always contains at least one thread.
165 This is reflected in this library by the #PProcess# class being
166 descended from the PThread class.
168 The implementation of a thread is platform dependent, but it is
169 assumed that the platform has some support for native threads.
170 Previous versions of PWLib has some support for co-operative
171 threads, but this has been removed
173 class PThread
: public PObject
175 PCLASSINFO(PThread
, PObject
);
178 /**@name Construction */
180 /// Codes for thread priorities.
182 /// Will only run if all other threads are blocked.
185 /// Runs approximately half as often as normal.
188 /// Normal priority for a thread.
191 /// Runs approximately twice as often as normal.
194 /// Is only thread that will run, unless blocked.
200 /// Codes for thread autodelete flag
201 enum AutoDeleteFlag
{
202 /// Automatically delete thread object on termination.
205 /// Don't delete thread as it may not be on heap.
209 /** Create a new thread instance. Unless the #startSuspended#
210 parameter is TRUE, the threads #Main()# function is called to
211 execute the code for the thread.
213 Note that the exact timing of the execution of code in threads can
214 never be predicted. Thus you you can get a race condition on
215 intialising a descendent class. To avoid this problem a thread is
216 always started suspended. You must call the Resume() function after
217 your descendent class construction is complete.
219 If synchronisation is required between threads then the use of
220 semaphores is essential.
222 If the #deletion# is set to #AutoDeleteThread#
223 then the PThread is assumed to be allocated with the new operator and
224 may be freed using the delete operator as soon as the thread is
225 terminated or executes to completion (usually the latter).
227 The stack size argument retained only for source code compatibility for
228 previous implementations. It is not used in the current code and
229 may be removed in subsequent versions.
232 PINDEX
, /// Not used - previously stack size
233 AutoDeleteFlag deletion
= AutoDeleteThread
,
234 /// Automatically delete PThread instance on termination of thread.
235 Priority priorityLevel
= NormalPriority
, /// Initial priority of thread.
236 const PString
& threadName
= PString::Empty() /// The name of the thread (for Debug/Trace)
239 /** Destroy the thread, this simply calls the #Terminate()# function
240 with all its restrictions and penalties. See that function for more
243 Note that the correct way for a thread to terminate is to return from
244 the #Main()# function.
249 /**@name Overrides from PObject */
251 /**Standard stream print function.
252 The PObject class has a << operator defined that calls this function
256 ostream
& strm
/// Stream to output text representation
260 /**@name Control functions */
262 /** Restart a terminated thread using the same stack priority etc that
263 was current when the thread terminated.
265 If the thread is still running then this function is ignored.
267 virtual void Restart();
269 /** Terminate the thread. It is highly recommended that this is not used
270 except in abnormal abort situations as not all clean up of resources
271 allocated to the thread will be executed. This is especially true in
272 C++ as the destructors of objects that are automatic variables are not
273 called causing at the very least the possiblity of memory leaks.
275 Note that the correct way for a thread to terminate is to return from
276 the #Main()# function or self terminate by calling
277 #Terminate()# within the context of the thread which can then
278 assure that all resources are cleaned up.
280 virtual void Terminate();
282 /** Determine if the thread has been terminated or ran to completion.
285 TRUE if the thread has been terminated.
287 virtual BOOL
IsTerminated() const;
289 /** Block and wait for the thread to terminate.
292 FALSE if the thread has not terminated and the timeout has expired.
294 void WaitForTermination() const;
295 BOOL
WaitForTermination(
296 const PTimeInterval
& maxWait
/// Maximum time to wait for termination.
299 /** Suspend or resume the thread.
301 If #susp# is TRUE this increments an internal count of
302 suspensions that must be matched by an equal number of calls to
303 #Resume()# or #Suspend(FALSE)# before the
304 thread actually executes again.
306 If #susp# is FALSE then this decrements the internal count of
307 suspensions. If the count is <= 0 then the thread will run. Note that
308 the thread will not be suspended until an equal number of
309 #Suspend(TRUE)# calls are made.
311 virtual void Suspend(
312 BOOL susp
= TRUE
/// Flag to suspend or resume a thread.
315 /** Resume thread execution, this is identical to
318 virtual void Resume();
320 /** Determine if the thread is currently suspended. This checks the
321 suspension count and if greater than zero returns TRUE for a suspended
325 TRUE if thread is suspended.
327 virtual BOOL
IsSuspended() const;
329 /// Suspend the current thread for the specified amount of time.
331 const PTimeInterval
& delay
/// Time interval to sleep for.
334 /** Set the priority of the thread relative to other threads in the current
337 virtual void SetPriority(
338 Priority priorityLevel
/// New priority for thread.
341 /** Get the current priority of the thread in the current process.
344 current thread priority.
346 virtual Priority
GetPriority() const;
348 /** Set the flag indicating thread object is to be automatically deleted
349 when the thread ends.
351 virtual void SetAutoDelete(
352 AutoDeleteFlag deletion
= AutoDeleteThread
/// New auto delete setting.
355 /** Reet the flag indicating thread object is to be automatically deleted
356 when the thread ends.
358 void SetNoAutoDelete() { SetAutoDelete(NoAutoDeleteThread
); }
360 /** Get the name of the thread. Thread names are a optional debugging aid.
365 virtual PString
GetThreadName() const;
367 /** Change the name of the thread. Thread names are a optional debugging aid.
372 virtual void SetThreadName(
373 const PString
& name
/// New name for the thread.
377 /**@name Miscellaneous */
379 /**Get operating system specific thread identifier for this thread.
381 virtual PThreadIdentifier
GetThreadId() const;
383 /**Get operating system specific thread identifier for current thread.
385 static PThreadIdentifier
GetCurrentThreadId();
387 /** User override function for the main execution routine of the thread. A
388 descendent class must provide the code that will be executed in the
389 thread within this function.
391 Note that the correct way for a thread to terminate is to return from
394 virtual void Main() = 0;
396 /** Get the currently running thread object instance. It is possible, even
397 likely, that the smae code may be executed in the context of differenct
398 threads. Under some circumstances it may be necessary to know what the
399 current codes thread is and this static function provides that
403 pointer to current thread.
405 static PThread
* Current();
407 /** Yield to another thread without blocking.
408 This duplicates the implicit thread yield that may occur on some
409 I/O operations or system calls.
411 This may not be implemented on all platforms.
415 /**Create a simple thread executing the specified notifier.
416 This creates a simple PThread class that automatically executes the
417 function defined by the PNotifier in the context of a new thread.
419 static PThread
* Create(
420 const PNotifier
& notifier
, /// Function to execute in thread.
421 INT parameter
= 0, /// Parameter value to pass to notifier.
422 AutoDeleteFlag deletion
= AutoDeleteThread
,
423 /// Automatically delete PThread instance on termination of thread.
424 Priority priorityLevel
= NormalPriority
, /// Initial priority of thread.
425 const PString
& threadName
= PString::Empty(), /// The name of the thread (for Debug/Trace)
426 PINDEX stackSize
= 10000 /// Stack size on some platforms
431 void InitialiseProcessThread();
432 /* Initialialise the primordial thread, the one in the PProcess. This is
433 required due to the bootstrap logic of processes and threads.
438 // Create a new thread instance as part of a PProcess class.
440 friend class PProcess
;
441 // So a PProcess can get at PThread() constructor but nothing else.
443 PThread(const PThread
&) { }
444 // Empty constructor to prevent copying of thread instances.
446 PThread
& operator=(const PThread
&) { return *this; }
447 // Empty assignment operator to prevent copying of thread instances.
450 // Automatically delete the thread on completion.
452 // Give the thread a name for debugging purposes.
456 unsigned traceBlockIndentLevel
;
457 friend class PTrace::Block
;
460 // Include platform dependent part of class
462 #include "msos/ptlib/thread.h"
464 #include "unix/ptlib/thread.h"
470 // End Of File ///////////////////////////////////////////////////////////////