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  * $Revision: 19844 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-03-31 01:07:22 +0000 (Mon, 31 Mar 2008) $
00032  */
00033 
00034 #ifndef _PTHREAD
00035 #define _PTHREAD
00036 
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040 
00041 #ifdef Priority
00042 #undef Priority
00043 #endif
00044 
00045 #include <ptlib/mutex.h>
00046 
00047 class PSemaphore;
00048 
00049 #define PThreadIdentifer PThreadIdentifier
00050 
00051 typedef P_THREADIDENTIFIER PThreadIdentifier;
00052 
00054 // PThread
00055 
00069 class PThread : public PObject
00070 {
00071   PCLASSINFO(PThread, PObject);
00072 
00073   public:
00076 
00077     enum Priority {
00079       LowestPriority,   
00080 
00082       LowPriority,      
00083 
00085       NormalPriority,   
00086 
00088       HighPriority,     
00089 
00091       HighestPriority,  
00092 
00093       NumPriorities
00094     };
00095 
00097     enum AutoDeleteFlag {
00099       AutoDeleteThread,   
00100 
00102       NoAutoDeleteThread  
00103     };
00104 
00127     PThread(
00128       PINDEX ,                 
00129       AutoDeleteFlag deletion = AutoDeleteThread,
00131       Priority priorityLevel = NormalPriority,  
00132       const PString & threadName = PString::Empty() 
00133     );
00134 
00142     ~PThread();
00144 
00151     void PrintOn(
00152       ostream & strm    
00153     ) const;
00155 
00163     virtual void Restart();
00164 
00176     virtual void Terminate();
00177 
00183     virtual PBoolean IsTerminated() const;
00184 
00190     void WaitForTermination() const;
00191     PBoolean WaitForTermination(
00192       const PTimeInterval & maxWait  
00193     ) const;
00194 
00207     virtual void Suspend(
00208       PBoolean susp = PTrue    
00209     );
00210 
00230     virtual void Resume();
00231 
00239     virtual PBoolean IsSuspended() const;
00240 
00242     static void Sleep(
00243       const PTimeInterval & delay   
00244     );
00245 
00249     virtual void SetPriority(
00250       Priority priorityLevel    
00251     );
00252 
00258     virtual Priority GetPriority() const;
00259 
00263     virtual void SetAutoDelete(
00264       AutoDeleteFlag deletion = AutoDeleteThread  
00265     );
00266 
00270     void SetNoAutoDelete() { SetAutoDelete(NoAutoDeleteThread); }
00271 
00277     virtual PString GetThreadName() const;
00278 
00284     virtual void SetThreadName(
00285       const PString & name        
00286     );
00288 
00296     virtual PThreadIdentifier GetThreadId() const;
00297     static PThreadIdentifier GetCurrentThreadId();
00298 
00306     virtual void Main() = 0;
00307 
00317     static PThread * Current();
00318 
00325     static void Yield();
00326 
00331     static PThread * Create(
00332       const PNotifier & notifier,     
00333       INT parameter = 0,              
00334       AutoDeleteFlag deletion = AutoDeleteThread,
00336       Priority priorityLevel = NormalPriority,  
00337       const PString & threadName = PString::Empty(), 
00338       PINDEX stackSize = 65536         
00339     );
00340     static PThread * Create(
00341       const PNotifier & notifier,     
00342       const PString & threadName      
00343     ) { return Create(notifier, 0, NoAutoDeleteThread, NormalPriority, threadName); }
00345 
00346   protected:
00347     void InitialiseProcessThread();
00348     /* Initialialise the primordial thread, the one in the PProcess. This is
00349        required due to the bootstrap logic of processes and threads.
00350      */
00351 
00352   private:
00353     PThread();
00354     // Create a new thread instance as part of a PProcess class.
00355 
00356     friend class PProcess;
00357     // So a PProcess can get at PThread() constructor but nothing else.
00358 
00359     PThread(const PThread &) : PObject () { }
00360     // Empty constructor to prevent copying of thread instances.
00361 
00362     PThread & operator=(const PThread &) { return *this; }
00363     // Empty assignment operator to prevent copying of thread instances.
00364 
00365     PBoolean autoDelete;
00366     // Automatically delete the thread on completion.
00367 
00368     // Give the thread a name for debugging purposes.
00369     PString threadName;
00370     PMutex threadNameMutex;
00371 
00372   private:
00373 #if PTRACING
00374     PStack<PStringStream> traceStreams;
00375     unsigned traceLevel;
00376     friend class PTrace;
00377 
00378     unsigned traceBlockIndentLevel;
00379     friend class PTrace::Block;
00380 #endif
00381 
00382 
00383 // Include platform dependent part of class
00384 #ifdef _WIN32
00385 #include "msos/ptlib/thread.h"
00386 #else
00387 #include "unix/ptlib/thread.h"
00388 #endif
00389 };
00390 
00391 // Include definition of platform dependent thread ID format
00392 #if defined(_WIN32) && !defined(_WIN32_WCE)
00393   #define PTHREAD_ID_FMT ":%u"
00394 #else
00395   #define PTHREAD_ID_FMT ":0x%x"
00396 #endif
00397 
00398 #ifdef _MSC_VER
00399 #pragma warning(disable:4355)
00400 #endif
00401 
00406 /*
00407    This class automates calling a global function with no arguments within it's own thread.
00408    It is used as follows:
00409 
00410    void GlobalFunction()
00411    {
00412    }
00413 
00414    ...
00415    PString arg;
00416    new PThreadMain(&GlobalFunction)
00417  */
00418 class PThreadMain : public PThread
00419 {
00420   PCLASSINFO(PThreadMain, PThread);
00421   public:
00422     typedef void (*FnType)(); 
00423     PThreadMain(FnType _fn, PBoolean _autoDelete = PFalse)
00424       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn)
00425     { PThread::Resume(); }
00426     PThreadMain(const char * _file, int _line, FnType _fn, PBoolean _autoDelete = PFalse)
00427       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread,  NormalPriority,
00428         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn)
00429     { PThread::Resume(); }
00430     virtual void Main()
00431     { (*fn)(); }
00432     FnType fn;
00433 };
00434 
00435 /*
00436    This template automates calling a global function with one argument within it's own thread.
00437    It is used as follows:
00438 
00439    void GlobalFunction(PString arg)
00440    {
00441    }
00442 
00443    ...
00444    PString arg;
00445    new PThread1Arg<PString>(arg, &GlobalFunction)
00446  */
00447 template<typename Arg1Type>
00448 class PThread1Arg : public PThread
00449 {
00450   PCLASSINFO(PThread1Arg, PThread);
00451   public:
00452     typedef void (*FnType)(Arg1Type arg1); 
00453     PThread1Arg(Arg1Type _arg1, FnType _fn, PBoolean _autoDelete = PFalse)
00454       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn),
00455         arg1(_arg1)
00456     { PThread::Resume(); }
00457     PThread1Arg(const char * _file, int _line, Arg1Type _arg1, FnType _fn, PBoolean _autoDelete = PFalse)
00458       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread,  NormalPriority,
00459         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn),
00460         arg1(_arg1)
00461     { PThread::Resume(); }
00462     virtual void Main()
00463     { (*fn)(arg1); }
00464     FnType fn;
00465     Arg1Type arg1;
00466 };
00467 
00468 
00469 /*
00470    This template automates calling a global function with two arguments within it's own thread.
00471    It is used as follows:
00472 
00473    void GlobalFunction(PString arg1, int arg2)
00474    {
00475    }
00476 
00477    ...
00478    PString arg;
00479    new PThread2Arg<PString, int>(arg, &GlobalFunction)
00480  */
00481 template<typename Arg1Type, typename Arg2Type>
00482 class PThread2Arg : public PThread
00483 {
00484   PCLASSINFO(PThread2Arg, PThread);
00485   public:
00486     typedef void (*FnType)(Arg1Type arg1, Arg2Type arg2); 
00487     PThread2Arg(Arg1Type _arg1, Arg2Type _arg2, FnType _fn, PBoolean _autoDelete = PFalse)
00488       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn),
00489         arg1(_arg1), arg2(_arg2)
00490     { PThread::Resume(); }
00491     PThread2Arg(const char * _file, int _line, Arg1Type _arg1, Arg2Type _arg2, FnType _fn, PBoolean _autoDelete = PFalse)
00492       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00493         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn),
00494         arg1(_arg1), arg2(_arg2)
00495     { PThread::Resume(); }
00496     virtual void Main()
00497     { (*fn)(arg1, arg2); }
00498     FnType fn;
00499     Arg1Type arg1;
00500     Arg2Type arg2;
00501 };
00502 
00503 /*
00504    This template automates calling a member function with no arguments within it's own thread.
00505    It is used as follows:
00506 
00507    class Example {
00508      public:
00509       void Function()
00510       {
00511       }
00512    };
00513 
00514    ...
00515    Example ex;
00516    new PThreadObj<Example>(ex, &Example::Function)
00517  */
00518 
00519 template <typename ObjType>
00520 class PThreadObj : public PThread
00521 {
00522   public:
00523   PCLASSINFO(PThreadObj, PThread);
00524   public:
00525     typedef void (ObjType::*ObjTypeFn)(); 
00526     PThreadObj(ObjType & _obj, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00527       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00528         obj(_obj), fn(_fn)
00529     { PThread::Resume(); }
00530     PThreadObj(const char * _file, int _line, ObjType & _obj, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00531       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00532         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)),
00533         obj(_obj), fn(_fn)
00534     { PThread::Resume(); }
00535     void Main()
00536     { (obj.*fn)(); }
00537 
00538   protected:
00539     ObjType & obj;
00540     ObjTypeFn fn;
00541 };
00542 
00543 
00544 /*
00545    This template automates calling a member function with one argument within it's own thread.
00546    It is used as follows:
00547 
00548    class Example {
00549      public:
00550       void Function(PString arg)
00551       {
00552       }
00553    };
00554 
00555    ...
00556    Example ex;
00557    PString str;
00558    new PThreadObj1Arg<Example>(ex, str, &Example::Function)
00559  */
00560 template <class ObjType, typename Arg1Type>
00561 class PThreadObj1Arg : public PThread
00562 {
00563   PCLASSINFO(PThreadObj1Arg, PThread);
00564   public:
00565     typedef void (ObjType::*ObjTypeFn)(Arg1Type); 
00566     PThreadObj1Arg(ObjType & _obj, Arg1Type _arg1, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00567       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00568                                 obj(_obj), fn(_fn), arg1(_arg1)
00569     { PThread::Resume(); }
00570     PThreadObj1Arg(const char * _file, int _line, ObjType & _obj, Arg1Type _arg1, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00571       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00572                                 psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)),
00573                                 obj(_obj), fn(_fn), arg1(_arg1)
00574     { PThread::Resume(); }
00575     void Main()
00576     { (obj.*fn)(arg1); }
00577 
00578   protected:
00579     ObjType & obj;
00580     ObjTypeFn fn;
00581     Arg1Type arg1;
00582 };
00583 
00584 template <class ObjType, typename Arg1Type, typename Arg2Type>
00585 class PThreadObj2Arg : public PThread
00586 {
00587   PCLASSINFO(PThreadObj2Arg, PThread);
00588   public:
00589     typedef void (ObjType::*ObjTypeFn)(Arg1Type, Arg2Type); 
00590     PThreadObj2Arg(ObjType & _obj, Arg1Type _arg1, Arg2Type _arg2, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00591       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00592                                 obj(_obj), fn(_fn), arg1(_arg1), arg2(_arg2)
00593     { PThread::Resume(); }
00594     PThreadObj2Arg(const char * _file, int _line, ObjType & _obj, Arg1Type _arg1, Arg2Type _arg2, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00595       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00596                                 psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)),
00597                                 obj(_obj), fn(_fn), arg1(_arg1), arg2(_arg2)
00598     { PThread::Resume(); }
00599     void Main()
00600     { (obj.*fn)(arg1, arg2); }
00601 
00602   protected:
00603     ObjType & obj;
00604     ObjTypeFn fn;
00605     Arg1Type arg1;
00606     Arg1Type arg2;
00607 };
00608 
00609 #ifdef _MSC_VER
00610 #pragma warning(default:4355)
00611 #endif
00612 
00613 #endif // _PTHREAD
00614 
00615 // End Of File ///////////////////////////////////////////////////////////////

Generated on Wed May 7 00:47:56 2008 for PTLib by  doxygen 1.5.1