thread.h

Go to the documentation of this file.
00001 /*
00002  * thread.h
00003  *
00004  * Executable thread encapsulation class (pre-emptive if OS allows).
00005  *
00006  * Portable Windows Library
00007  *
00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
00009  *
00010  * The contents of this file are subject to the Mozilla Public License
00011  * Version 1.0 (the "License"); you may not use this file except in
00012  * compliance with the License. You may obtain a copy of the License at
00013  * http://www.mozilla.org/MPL/
00014  *
00015  * Software distributed under the License is distributed on an "AS IS"
00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00017  * the License for the specific language governing rights and limitations
00018  * under the License.
00019  *
00020  * The Original Code is Portable Windows Library.
00021  *
00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
00023  *
00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
00025  * All Rights Reserved.
00026  *
00027  * Contributor(s): ______________________________________.
00028  *
00029  * $Log: thread.h,v $
00030  * Revision 1.46  2006/10/03 06:30:31  csoutheren
00031  * Fix error in PThreadObj templates
00032  *
00033  * Revision 1.45  2006/07/05 09:14:29  csoutheren
00034  * Fixed startup problems with using Resume in PThread descendants
00035  *
00036  * Revision 1.44  2006/07/05 03:59:19  csoutheren
00037  * Fix PThreadMain2Arg template
00038  *
00039  * Revision 1.43  2006/06/28 11:28:21  csoutheren
00040  * Patch 1456858 - increase default thread stack size
00041  * Thanks to drosario
00042  *
00043  * Revision 1.42  2006/05/25 23:28:27  csoutheren
00044  * Fixed compilation under gcc 4.0
00045  *
00046  * Revision 1.41  2006/05/23 22:11:27  csoutheren
00047  * Fixed compilation under gcc
00048  *
00049  * Revision 1.40  2006/05/23 00:58:05  csoutheren
00050  * Add templates for creating threads
00051  *
00052  * Revision 1.39  2006/01/29 22:35:46  csoutheren
00053  * Added fix for thread termination problems on SMP machines
00054  * Thanks to Derek Smithies
00055  *
00056  * Revision 1.38  2006/01/11 22:27:44  dereksmithies
00057  * Add extra comments describing the usage of Resume() in the constructor of a
00058  * class descended of PThread
00059  *
00060  * Revision 1.37  2005/11/30 12:47:38  csoutheren
00061  * Removed tabs, reformatted some code, and changed tags for Doxygen
00062  *
00063  * Revision 1.36  2005/11/25 03:43:47  csoutheren
00064  * Fixed function argument comments to be compatible with Doxygen
00065  *
00066  * Revision 1.35  2003/10/08 21:39:34  dereksmithies
00067  * Add a #define to cope with backward compatability issues for PThreadIdentifier
00068  * Thanks to Andrey S Pankov and Craig Southeren for their input.
00069  *
00070  * Revision 1.34  2003/09/17 05:41:59  csoutheren
00071  * Removed recursive includes
00072  *
00073  * Revision 1.33  2003/09/17 01:18:02  csoutheren
00074  * Removed recursive include file system and removed all references
00075  * to deprecated coooperative threading support
00076  *
00077  * Revision 1.32  2002/10/04 04:33:27  robertj
00078  * Added functions for getting operating system thread identifier values.
00079  *
00080  * Revision 1.31  2002/09/16 01:08:59  robertj
00081  * Added #define so can select if #pragma interface/implementation is used on
00082  *   platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
00083  *
00084  * Revision 1.30  2002/06/27 06:44:28  robertj
00085  * Changed "" to PString::Empty() where assigning to PString.
00086  *
00087  * Revision 1.29  2002/04/24 01:49:22  robertj
00088  * Fixed error in PTRACE_BLOCk nesting level to now work when no tracing enabled.
00089  *
00090  * Revision 1.28  2002/04/24 01:09:56  robertj
00091  * Fixed problem with PTRACE_BLOCK indent level being correct across threads.
00092  *
00093  * Revision 1.27  2001/09/10 02:51:22  robertj
00094  * Major change to fix problem with error codes being corrupted in a
00095  *   PChannel when have simultaneous reads and writes in threads.
00096  *
00097  * Revision 1.26  2001/05/22 12:49:32  robertj
00098  * Did some seriously wierd rewrite of platform headers to eliminate the
00099  *   stupid GNU compiler warning about braces not matching.
00100  *
00101  * Revision 1.25  2000/11/28 12:55:36  robertj
00102  * Added static function to create a new thread class and automatically
00103  *   run a function on another class in the context of that thread.
00104  *
00105  * Revision 1.24  2000/10/20 05:31:09  robertj
00106  * Added function to change auto delete flag on a thread.
00107  *
00108  * Revision 1.23  2000/06/26 11:17:19  robertj
00109  * Nucleus++ port (incomplete).
00110  *
00111  * Revision 1.22  2000/02/29 12:26:14  robertj
00112  * Added named threads to tracing, thanks to Dave Harvey
00113  *
00114  * Revision 1.21  1999/06/06 05:07:17  robertj
00115  * Fixed documentation error.
00116  *
00117  * Revision 1.20  1999/03/09 02:59:51  robertj
00118  * Changed comments to doc++ compatible documentation.
00119  *
00120  * Revision 1.19  1999/02/16 08:11:17  robertj
00121  * MSVC 6.0 compatibility changes.
00122  *
00123  * Revision 1.18  1998/11/20 03:18:33  robertj
00124  * Added thread WaitForTermination() function.
00125  *
00126  * Revision 1.17  1998/10/31 12:47:59  robertj
00127  * Removed ability to start threads immediately, race condition with vtable (Main() function).
00128  *
00129  * Revision 1.16  1998/09/23 06:21:41  robertj
00130  * Added open source copyright license.
00131  *
00132  * Revision 1.15  1996/03/02 03:15:51  robertj
00133  * Added automatic deletion of thread object instances on thread completion.
00134  *
00135  * Revision 1.14  1995/12/10 11:44:32  robertj
00136  * Fixed bug in non-platform threads and semaphore timeouts.
00137  *
00138  * Revision 1.13  1995/11/21 11:49:44  robertj
00139  * Added timeout on semaphore wait.
00140  *
00141  * Revision 1.12  1995/07/31 12:10:40  robertj
00142  * Added semaphore class.
00143  *
00144  * Revision 1.11  1995/06/17 11:13:35  robertj
00145  * Documentation update.
00146  *
00147  * Revision 1.10  1995/03/14 12:42:49  robertj
00148  * Updated documentation to use HTML codes.
00149  *
00150  * Revision 1.9  1995/01/16  09:42:13  robertj
00151  * Documentation.
00152  *
00153  * Revision 1.8  1994/09/25  10:45:22  robertj
00154  * Virtualised IsNoLongerBlocked for unix platform.
00155  *
00156  * Revision 1.6  1994/08/22  00:46:48  robertj
00157  * Added pragma fro GNU C++ compiler.
00158  *
00159  * Revision 1.5  1994/08/21  23:43:02  robertj
00160  * Added SuspendBlock state to cooperative multi-threading to fix logic fault.
00161  *
00162  * Revision 1.4  1994/08/04  12:32:22  robertj
00163  * Better name of thread block check function.
00164  *
00165  * Revision 1.3  1994/07/21  12:33:49  robertj
00166  * Moved cooperative threads to common.
00167  *
00168  * Revision 1.2  1994/07/02  03:03:49  robertj
00169  * Added restartable threads.
00170  *
00171  * Revision 1.1  1994/06/25  11:55:15  robertj
00172  * Initial revision
00173  *
00174  */
00175 
00176 #ifndef _PTHREAD
00177 #define _PTHREAD
00178 
00179 #ifdef P_USE_PRAGMA
00180 #pragma interface
00181 #endif
00182 
00183 #ifdef Priority
00184 #undef Priority
00185 #endif
00186 
00187 class PSemaphore;
00188 
00189 #define PThreadIdentifer PThreadIdentifier
00190 
00191 typedef P_THREADIDENTIFIER PThreadIdentifier;
00192 
00194 // PThread
00195 
00209 class PThread : public PObject
00210 {
00211   PCLASSINFO(PThread, PObject);
00212 
00213   public:
00216 
00217     enum Priority {
00219       LowestPriority,   
00220 
00222       LowPriority,      
00223 
00225       NormalPriority,   
00226 
00228       HighPriority,     
00229 
00231       HighestPriority,  
00232 
00233       NumPriorities
00234     };
00235 
00237     enum AutoDeleteFlag {
00239       AutoDeleteThread,   
00240 
00242       NoAutoDeleteThread  
00243     };
00244 
00267     PThread(
00268       PINDEX ,                 
00269       AutoDeleteFlag deletion = AutoDeleteThread,
00271       Priority priorityLevel = NormalPriority,  
00272       const PString & threadName = PString::Empty() 
00273     );
00274 
00282     ~PThread();
00284 
00291     void PrintOn(
00292       ostream & strm    
00293     ) const;
00295 
00303     virtual void Restart();
00304 
00316     virtual void Terminate();
00317 
00323     virtual BOOL IsTerminated() const;
00324 
00330     void WaitForTermination() const;
00331     BOOL WaitForTermination(
00332       const PTimeInterval & maxWait  
00333     ) const;
00334 
00347     virtual void Suspend(
00348       BOOL susp = TRUE    
00349     );
00350 
00370     virtual void Resume();
00371 
00379     virtual BOOL IsSuspended() const;
00380 
00382     static void Sleep(
00383       const PTimeInterval & delay   
00384     );
00385 
00389     virtual void SetPriority(
00390       Priority priorityLevel    
00391     );
00392 
00398     virtual Priority GetPriority() const;
00399 
00403     virtual void SetAutoDelete(
00404       AutoDeleteFlag deletion = AutoDeleteThread  
00405     );
00406 
00410     void SetNoAutoDelete() { SetAutoDelete(NoAutoDeleteThread); }
00411 
00417     virtual PString GetThreadName() const;
00418 
00424     virtual void SetThreadName(
00425       const PString & name        
00426     );
00428 
00436     virtual PThreadIdentifier GetThreadId() const;
00437     static PThreadIdentifier GetCurrentThreadId();
00438 
00446     virtual void Main() = 0;
00447 
00457     static PThread * Current();
00458 
00465     static void Yield();
00466 
00471     static PThread * Create(
00472       const PNotifier & notifier,     
00473       INT parameter = 0,              
00474       AutoDeleteFlag deletion = AutoDeleteThread,
00476       Priority priorityLevel = NormalPriority,  
00477       const PString & threadName = PString::Empty(), 
00478       PINDEX stackSize = 65536         
00479     );
00481 
00482   protected:
00483     void InitialiseProcessThread();
00484     /* Initialialise the primordial thread, the one in the PProcess. This is
00485        required due to the bootstrap logic of processes and threads.
00486      */
00487 
00488   private:
00489     PThread();
00490     // Create a new thread instance as part of a PProcess class.
00491 
00492     friend class PProcess;
00493     // So a PProcess can get at PThread() constructor but nothing else.
00494 
00495     PThread(const PThread &) { }
00496     // Empty constructor to prevent copying of thread instances.
00497 
00498     PThread & operator=(const PThread &) { return *this; }
00499     // Empty assignment operator to prevent copying of thread instances.
00500 
00501     BOOL autoDelete;
00502     // Automatically delete the thread on completion.
00503 
00504     // Give the thread a name for debugging purposes.
00505     PString threadName;
00506 
00507   private:
00508     unsigned traceBlockIndentLevel;
00509     friend class PTrace::Block;
00510 
00511 
00512 // Include platform dependent part of class
00513 #ifdef _WIN32
00514 #include "msos/ptlib/thread.h"
00515 #else
00516 #include "unix/ptlib/thread.h"
00517 #endif
00518 };
00519 
00524 class PThreadMain : public PThread
00525 {
00526   PCLASSINFO(PThreadMain, PThread);
00527   public:
00528     PThreadMain(BOOL autoDelete = FALSE)
00529       : PThread(10000, autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread)
00530     { PThread::Resume(); }
00531     virtual void Main() = 0;
00532 };
00533 
00534 template <class Arg1Type>
00535 class PThreadMain1Arg : public PThread
00536 {
00537   PCLASSINFO(PThreadMain1Arg, PThread);
00538   public:
00539     PThreadMain1Arg(Arg1Type _arg1, BOOL autoDelete = FALSE)
00540       : PThread(10000, autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00541         arg1(_arg1)
00542     { PThread::Resume(); }
00543     virtual void Main();
00544 
00545   protected:
00546     Arg1Type arg1;
00547 };
00548 
00549 template <class Arg1Type, class Arg2Type>
00550 class PThreadMain2Arg : public PThread
00551 {
00552   PCLASSINFO(PThreadMain2Arg, PThread);
00553   public:
00554     PThreadMain2Arg(Arg1Type _arg1, Arg2Type _arg2, BOOL autoDelete = FALSE)
00555       : PThread(10000, autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00556         arg1(_arg1), arg2(_arg2)
00557     { PThread::Resume(); }
00558     virtual void Main();
00559 
00560   protected:
00561     Arg1Type arg1;
00562     Arg2Type arg2;
00563 };
00564 
00565 template <class ObjType>
00566 class PThreadObj : public PThread
00567 {
00568   public:
00569   PCLASSINFO(PThreadObj, PThread);
00570   public:
00571     typedef void (ObjType::*ObjTypeFn)(); 
00572     PThreadObj(ObjType & _obj, ObjTypeFn _fn, BOOL autoDelete = FALSE)
00573       : PThread(10000, autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00574         obj(_obj), fn(_fn)
00575     { PThread::Resume(); }
00576     void Main()
00577     { (obj.*fn)(); }
00578 
00579   protected:
00580     ObjType & obj;
00581     ObjTypeFn fn;
00582 };
00583 
00584 template <class ObjType, class Arg1Type>
00585 class PThreadObj1Arg : public PThread
00586 {
00587   PCLASSINFO(PThreadObj1Arg, PThread);
00588   public:
00589     typedef void (ObjType::*ObjTypeFn)(int); 
00590     PThreadObj1Arg(ObjType & _obj, Arg1Type _arg1, ObjTypeFn _fn, BOOL autoDelete = FALSE)
00591       : PThread(10000, autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00592                                 obj(_obj), fn(_fn), arg1(_arg1)
00593     { PThread::Resume(); }
00594     void Main()
00595     { (obj.*fn)(arg1); }
00596 
00597   protected:
00598     ObjType & obj;
00599     ObjTypeFn fn;
00600     Arg1Type arg1;
00601 };
00602 
00603 #endif // _PTHREAD
00604 
00605 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Sep 1 09:41:07 2008 for PWLib by  doxygen 1.5.6