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: 19008 $
00030  * $Author: rjongbloed $
00031  * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
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 class PSemaphore;
00046 
00047 #define PThreadIdentifer PThreadIdentifier
00048 
00049 typedef P_THREADIDENTIFIER PThreadIdentifier;
00050 
00052 // PThread
00053 
00067 class PThread : public PObject
00068 {
00069   PCLASSINFO(PThread, PObject);
00070 
00071   public:
00074 
00075     enum Priority {
00077       LowestPriority,   
00078 
00080       LowPriority,      
00081 
00083       NormalPriority,   
00084 
00086       HighPriority,     
00087 
00089       HighestPriority,  
00090 
00091       NumPriorities
00092     };
00093 
00095     enum AutoDeleteFlag {
00097       AutoDeleteThread,   
00098 
00100       NoAutoDeleteThread  
00101     };
00102 
00125     PThread(
00126       PINDEX ,                 
00127       AutoDeleteFlag deletion = AutoDeleteThread,
00129       Priority priorityLevel = NormalPriority,  
00130       const PString & threadName = PString::Empty() 
00131     );
00132 
00140     ~PThread();
00142 
00149     void PrintOn(
00150       ostream & strm    
00151     ) const;
00153 
00161     virtual void Restart();
00162 
00174     virtual void Terminate();
00175 
00181     virtual PBoolean IsTerminated() const;
00182 
00188     void WaitForTermination() const;
00189     PBoolean WaitForTermination(
00190       const PTimeInterval & maxWait  
00191     ) const;
00192 
00205     virtual void Suspend(
00206       PBoolean susp = PTrue    
00207     );
00208 
00228     virtual void Resume();
00229 
00237     virtual PBoolean IsSuspended() const;
00238 
00240     static void Sleep(
00241       const PTimeInterval & delay   
00242     );
00243 
00247     virtual void SetPriority(
00248       Priority priorityLevel    
00249     );
00250 
00256     virtual Priority GetPriority() const;
00257 
00261     virtual void SetAutoDelete(
00262       AutoDeleteFlag deletion = AutoDeleteThread  
00263     );
00264 
00268     void SetNoAutoDelete() { SetAutoDelete(NoAutoDeleteThread); }
00269 
00275     virtual PString GetThreadName() const;
00276 
00282     virtual void SetThreadName(
00283       const PString & name        
00284     );
00286 
00294     virtual PThreadIdentifier GetThreadId() const;
00295     static PThreadIdentifier GetCurrentThreadId();
00296 
00304     virtual void Main() = 0;
00305 
00315     static PThread * Current();
00316 
00323     static void Yield();
00324 
00329     static PThread * Create(
00330       const PNotifier & notifier,     
00331       INT parameter = 0,              
00332       AutoDeleteFlag deletion = AutoDeleteThread,
00334       Priority priorityLevel = NormalPriority,  
00335       const PString & threadName = PString::Empty(), 
00336       PINDEX stackSize = 65536         
00337     );
00339 
00340   protected:
00341     void InitialiseProcessThread();
00342     /* Initialialise the primordial thread, the one in the PProcess. This is
00343        required due to the bootstrap logic of processes and threads.
00344      */
00345 
00346   private:
00347     PThread();
00348     // Create a new thread instance as part of a PProcess class.
00349 
00350     friend class PProcess;
00351     // So a PProcess can get at PThread() constructor but nothing else.
00352 
00353     PThread(const PThread &) : PObject () { }
00354     // Empty constructor to prevent copying of thread instances.
00355 
00356     PThread & operator=(const PThread &) { return *this; }
00357     // Empty assignment operator to prevent copying of thread instances.
00358 
00359     PBoolean autoDelete;
00360     // Automatically delete the thread on completion.
00361 
00362     // Give the thread a name for debugging purposes.
00363     PString threadName;
00364 
00365   private:
00366 #if PTRACING
00367     PStringStream traceStream;
00368     unsigned      traceLevel;
00369     friend class PTrace;
00370 
00371     unsigned traceBlockIndentLevel;
00372     friend class PTrace::Block;
00373 #endif
00374 
00375 
00376 // Include platform dependent part of class
00377 #ifdef _WIN32
00378 #include "msos/ptlib/thread.h"
00379 #else
00380 #include "unix/ptlib/thread.h"
00381 #endif
00382 };
00383 
00384 #ifdef _MSC_VER
00385 #pragma warning(disable:4355)
00386 #endif
00387 
00392 /*
00393    This class automates calling a global function with no arguments within it's own thread.
00394    It is used as follows:
00395 
00396    void GlobalFunction()
00397    {
00398    }
00399 
00400    ...
00401    PString arg;
00402    new PThreadMain(&GlobalFunction)
00403  */
00404 class PThreadMain : public PThread
00405 {
00406   PCLASSINFO(PThreadMain, PThread);
00407   public:
00408     typedef void (*FnType)(); 
00409     PThreadMain(FnType _fn, PBoolean _autoDelete = PFalse)
00410       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn)
00411     { PThread::Resume(); }
00412     PThreadMain(const char * _file, int _line, FnType _fn, PBoolean _autoDelete = PFalse)
00413       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread,  NormalPriority,
00414         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn)
00415     { PThread::Resume(); }
00416     virtual void Main()
00417     { (*fn)(); }
00418     FnType fn;
00419 };
00420 
00421 /*
00422    This template automates calling a global function with one argument within it's own thread.
00423    It is used as follows:
00424 
00425    void GlobalFunction(PString arg)
00426    {
00427    }
00428 
00429    ...
00430    PString arg;
00431    new PThread1Arg<PString>(arg, &GlobalFunction)
00432  */
00433 template<typename Arg1Type>
00434 class PThread1Arg : public PThread
00435 {
00436   PCLASSINFO(PThread1Arg, PThread);
00437   public:
00438     typedef void (*FnType)(Arg1Type arg1); 
00439     PThread1Arg(Arg1Type _arg1, FnType _fn, PBoolean _autoDelete = PFalse)
00440       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn),
00441         arg1(_arg1)
00442     { PThread::Resume(); }
00443     PThread1Arg(const char * _file, int _line, Arg1Type _arg1, FnType _fn, PBoolean _autoDelete = PFalse)
00444       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread,  NormalPriority,
00445         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn),
00446         arg1(_arg1)
00447     { PThread::Resume(); }
00448     virtual void Main()
00449     { (*fn)(arg1); }
00450     FnType fn;
00451     Arg1Type arg1;
00452 };
00453 
00454 
00455 /*
00456    This template automates calling a global function with two arguments within it's own thread.
00457    It is used as follows:
00458 
00459    void GlobalFunction(PString arg1, int arg2)
00460    {
00461    }
00462 
00463    ...
00464    PString arg;
00465    new PThread2Arg<PString, int>(arg, &GlobalFunction)
00466  */
00467 template<typename Arg1Type, typename Arg2Type>
00468 class PThread2Arg : public PThread
00469 {
00470   PCLASSINFO(PThread2Arg, PThread);
00471   public:
00472     typedef void (*FnType)(Arg1Type arg1, Arg2Type arg2); 
00473     PThread2Arg(Arg1Type _arg1, Arg2Type _arg2, FnType _fn, PBoolean _autoDelete = PFalse)
00474       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread), fn(_fn),
00475         arg1(_arg1), arg2(_arg2)
00476     { PThread::Resume(); }
00477     PThread2Arg(const char * _file, int _line, Arg1Type _arg1, Arg2Type _arg2, FnType _fn, PBoolean _autoDelete = PFalse)
00478       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00479         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)), fn(_fn),
00480         arg1(_arg1), arg2(_arg2)
00481     { PThread::Resume(); }
00482     virtual void Main()
00483     { (*fn)(arg1, arg2); }
00484     FnType fn;
00485     Arg1Type arg1;
00486     Arg2Type arg2;
00487 };
00488 
00489 /*
00490    This template automates calling a member function with no arguments within it's own thread.
00491    It is used as follows:
00492 
00493    class Example {
00494      public:
00495       void Function()
00496       {
00497       }
00498    };
00499 
00500    ...
00501    Example ex;
00502    new PThreadObj<Example>(ex, &Example::Function)
00503  */
00504 
00505 template <typename ObjType>
00506 class PThreadObj : public PThread
00507 {
00508   public:
00509   PCLASSINFO(PThreadObj, PThread);
00510   public:
00511     typedef void (ObjType::*ObjTypeFn)(); 
00512     PThreadObj(ObjType & _obj, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00513       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00514         obj(_obj), fn(_fn)
00515     { PThread::Resume(); }
00516     PThreadObj(const char * _file, int _line, ObjType & _obj, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00517       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00518         psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)),
00519         obj(_obj), fn(_fn)
00520     { PThread::Resume(); }
00521     void Main()
00522     { (obj.*fn)(); }
00523 
00524   protected:
00525     ObjType & obj;
00526     ObjTypeFn fn;
00527 };
00528 
00529 
00530 /*
00531    This template automates calling a member function with one argument within it's own thread.
00532    It is used as follows:
00533 
00534    class Example {
00535      public:
00536       void Function(PString arg)
00537       {
00538       }
00539    };
00540 
00541    ...
00542    Example ex;
00543    PString str;
00544    new PThreadObj1Arg<Example>(ex, str, &Example::Function)
00545  */
00546 template <class ObjType, typename Arg1Type>
00547 class PThreadObj1Arg : public PThread
00548 {
00549   PCLASSINFO(PThreadObj1Arg, PThread);
00550   public:
00551     typedef void (ObjType::*ObjTypeFn)(Arg1Type); 
00552     PThreadObj1Arg(ObjType & _obj, Arg1Type _arg1, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00553       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread),
00554                                 obj(_obj), fn(_fn), arg1(_arg1)
00555     { PThread::Resume(); }
00556     PThreadObj1Arg(const char * _file, int _line, ObjType & _obj, Arg1Type _arg1, ObjTypeFn _fn, PBoolean _autoDelete = PFalse)
00557       : PThread(10000, _autoDelete ? PThread::AutoDeleteThread : PThread::NoAutoDeleteThread, NormalPriority,
00558                                 psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, _file, _line)),
00559                                 obj(_obj), fn(_fn), arg1(_arg1)
00560     { PThread::Resume(); }
00561     void Main()
00562     { (obj.*fn)(arg1); }
00563 
00564   protected:
00565     ObjType & obj;
00566     ObjTypeFn fn;
00567     Arg1Type arg1;
00568 };
00569 
00570 #ifdef _MSC_VER
00571 #pragma warning(default:4355)
00572 #endif
00573 
00574 #endif // _PTHREAD
00575 
00576 // End Of File ///////////////////////////////////////////////////////////////

Generated on Mon Dec 10 11:18:57 2007 for PTLib by  doxygen 1.5.1