PTLib  Version 2.10.10
thread.h
Go to the documentation of this file.
1 /*
2  * thread.h
3  *
4  * Executable thread encapsulation class (pre-emptive if OS allows).
5  *
6  * Portable Tools Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
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/
14  *
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
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 28050 $
30  * $Author: rjongbloed $
31  * $Date: 2012-07-18 02:15:30 -0500 (Wed, 18 Jul 2012) $
32  */
33 
34 #ifndef PTLIB_THREAD_H
35 #define PTLIB_THREAD_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #ifdef Priority
42 #undef Priority
43 #endif
44 
45 #include <ptlib/mutex.h>
46 
47 class PSemaphore;
48 
49 
51 // PThread
52 
66 class PThread : public PObject
67 {
68  PCLASSINFO(PThread, PObject);
69 
70  public:
73  enum Priority {
76 
78 
80 
82 
84 
86  };
87 
92 
95  };
96 
119  PThread(
120  PINDEX,
121  AutoDeleteFlag deletion = AutoDeleteThread,
123  Priority priorityLevel = NormalPriority,
124  const PString & threadName = PString::Empty()
125  );
126 
134  ~PThread();
136 
143  void PrintOn(
144  ostream & strm
145  ) const;
147 
155  virtual void Restart();
156 
168  virtual void Terminate();
169 
175  virtual PBoolean IsTerminated() const;
176 
179  void WaitForTermination() const;
180 
187  const PTimeInterval & maxWait
188  ) const;
189 
202  virtual void Suspend(
203  PBoolean susp = true
204  );
205 
225  virtual void Resume();
226 
234  virtual PBoolean IsSuspended() const;
235 
237  static void Sleep(
238  const PTimeInterval & delay
239  );
240 
244  virtual void SetPriority(
245  Priority priorityLevel
246  );
247 
253  virtual Priority GetPriority() const;
254 
258  virtual void SetAutoDelete(
259  AutoDeleteFlag deletion = AutoDeleteThread
260  );
261 
266 
272  virtual PString GetThreadName() const;
273 
279  virtual void SetThreadName(
280  const PString & name
281  );
283 
291  virtual PThreadIdentifier GetThreadId() const { return m_threadId; }
292  static PThreadIdentifier GetCurrentThreadId();
293 
295  struct Times
296  {
300  friend ostream & operator<<(ostream & strm, const Times & times);
301  };
302 
305  bool GetTimes(
306  Times & times
307  );
308 
316  virtual void Main() = 0;
317 
327  static PThread * Current();
328 
335  static void Yield();
336 
341  static PThread * Create(
342  const PNotifier & notifier,
343  INT parameter = 0,
344  AutoDeleteFlag deletion = AutoDeleteThread,
346  Priority priorityLevel = NormalPriority,
347  const PString & threadName = PString::Empty(),
348  PINDEX stackSize = 65536
349  );
350  static PThread * Create(
351  const PNotifier & notifier,
352  const PString & threadName
353  ) { return Create(notifier, 0, NoAutoDeleteThread, NormalPriority, threadName); }
355 
356  bool IsAutoDelete() const { return m_autoDelete; }
357 
358  private:
359  PThread(bool isProcess);
360  // Create a new thread instance as part of a <code>PProcess</code> class.
361 
362  friend class PProcess;
363  friend class PExternalThread;
364  friend class PHouseKeepingThread;
365  // So a PProcess can get at PThread() constructor but nothing else.
366 
367  PThread(const PThread &) : PObject () { }
368  // Empty constructor to prevent copying of thread instances.
369 
370  PThread & operator=(const PThread &) { return *this; }
371  // Empty assignment operator to prevent copying of thread instances.
372 
373  protected:
375  bool m_autoDelete; // Automatically delete the thread on completion.
377 
378  PString m_threadName; // Give the thread a name for debugging purposes.
380 
381  PThreadIdentifier m_threadId;
382 
383 #if PTRACING
384  public:
385  struct TraceInfo {
386  TraceInfo()
387  { traceBlockIndentLevel = 0; }
388 
389  PStack<PStringStream> traceStreams;
390  unsigned traceLevel;
391  unsigned traceBlockIndentLevel;
392  };
393 
394 #ifndef P_HAS_THREADLOCAL_STORAGE
395  private:
396  friend class PTrace;
397  TraceInfo traceInfo;
398 #endif // P_HAS_THREADLOCAL_STORAGE
399 #endif // PTRACING
400 
401 // Include platform dependent part of class
402 #ifdef _WIN32
403 #include "msos/ptlib/thread.h"
404 #else
405 #include "unix/ptlib/thread.h"
406 #endif
407 };
408 
409 // Include definition of platform dependent thread ID format
410 #if defined(_WIN32) && !defined(_WIN32_WCE)
411  #define PTHREAD_ID_FMT "%u"
412 #else
413  #define PTHREAD_ID_FMT "0x%lx"
414 #endif
415 
416 #ifdef _MSC_VER
417 #pragma warning(disable:4355)
418 #endif
419 
424 /*
425  This class automates calling a global function with no arguments within it's own thread.
426  It is used as follows:
427 
428  void GlobalFunction()
429  {
430  }
431 
432  ...
433  PString arg;
434  new PThreadMain(&GlobalFunction)
435  */
436 class PThreadMain : public PThread
437 {
438  PCLASSINFO(PThreadMain, PThread);
439  public:
440  typedef void (*FnType)();
441  PThreadMain(FnType function, bool autoDel = false)
443  , m_function(function)
444  { PThread::Resume(); }
445  PThreadMain(const char * file, int line, FnType function, bool autoDel = false)
447  psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, file, line))
448  , m_function(function)
449  { PThread::Resume(); }
450  virtual void Main()
451  { (*m_function)(); }
452 
453  protected:
455 };
456 
457 /*
458  This template automates calling a global function with one argument within it's own thread.
459  It is used as follows:
460 
461  void GlobalFunction(PString arg)
462  {
463  }
464 
465  ...
466  PString arg;
467  new PThread1Arg<PString>(arg, &GlobalFunction)
468  */
469 template<typename Arg1Type>
470 class PThread1Arg : public PThread
471 {
472  PCLASSINFO(PThread1Arg, PThread);
473  public:
474  typedef void (*FnType)(Arg1Type arg1);
475 
476  PThread1Arg(Arg1Type arg1, FnType function, bool autoDel = false)
478  , m_function(function)
479  , m_arg1(arg1)
480  { PThread::Resume(); }
481  PThread1Arg(const char * file, int line, Arg1Type arg1, FnType function, bool autoDel = false)
483  psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, file, line))
484  , m_function(function)
485  , m_arg1(arg1)
486  { PThread::Resume(); }
487  virtual void Main()
488  { (*m_function)(m_arg1); }
489 
490  protected:
492  Arg1Type m_arg1;
493 };
494 
495 
496 /*
497  This template automates calling a global function with two arguments within it's own thread.
498  It is used as follows:
499 
500  void GlobalFunction(PString arg1, int arg2)
501  {
502  }
503 
504  ...
505  PString arg;
506  new PThread2Arg<PString, int>(arg1, arg2, &GlobalFunction)
507  */
508 template<typename Arg1Type, typename Arg2Type>
509 class PThread2Arg : public PThread
510 {
511  PCLASSINFO(PThread2Arg, PThread);
512  public:
513  typedef void (*FnType)(Arg1Type arg1, Arg2Type arg2);
514  PThread2Arg(Arg1Type arg1, Arg2Type arg2, FnType function, bool autoDel = false)
516  , m_function(function)
517  , m_arg1(arg1)
518  , m_arg2(arg2)
519  { PThread::Resume(); }
520  PThread2Arg(const char * file, int line, Arg1Type arg1, Arg2Type arg2, FnType function, bool autoDel = false)
522  psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, file, line))
523  , m_function(function)
524  , m_arg1(arg1)
525  , m_arg2(arg2)
526  { PThread::Resume(); }
527  virtual void Main()
528  { (*m_function)(m_arg1, m_arg2); }
529 
530  protected:
532  Arg1Type m_arg1;
533  Arg2Type m_arg2;
534 };
535 
536 /*
537  This template automates calling a global function with three arguments within it's own thread.
538  It is used as follows:
539 
540  void GlobalFunction(PString arg1, int arg2, int arg3)
541  {
542  }
543 
544  ...
545  PString arg;
546  new PThread3Arg<PString, int, int>(arg1, arg2, arg3, &GlobalFunction)
547  */
548 template<typename Arg1Type, typename Arg2Type, typename Arg3Type>
549 class PThread3Arg : public PThread
550 {
551  PCLASSINFO(PThread3Arg, PThread);
552  public:
553  typedef void (*FnType)(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3);
554  PThread3Arg(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, FnType function, bool autoDel = false)
556  , m_function(function)
557  , m_arg1(arg1)
558  , m_arg2(arg2)
559  , m_arg3(arg3)
560  { PThread::Resume(); }
561  PThread3Arg(const char * file, int line, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, FnType function, bool autoDel = false)
563  psprintf("%s:%08x-%s:%i", GetClass(), (void *)this, file, line))
564  , m_function(function)
565  , m_arg1(arg1)
566  , m_arg2(arg2)
567  , m_arg3(arg3)
568  { PThread::Resume(); }
569  virtual void Main()
570  { (*m_function)(m_arg1, m_arg2, m_arg3); }
571 
572  protected:
574  Arg1Type m_arg1;
575  Arg2Type m_arg2;
576  Arg2Type m_arg3;
577 };
578 
579 /*
580  This template automates calling a member function with no arguments within it's own thread.
581  It is used as follows:
582 
583  class Example {
584  public:
585  void Function()
586  {
587  }
588  };
589 
590  ...
591  Example ex;
592  new PThreadObj<Example>(ex, &Example::Function)
593  */
594 
595 template <typename ObjType>
596 class PThreadObj : public PThread
597 {
598  PCLASSINFO(PThreadObj, PThread);
599  public:
600  typedef void (ObjType::*ObjTypeFn)();
601 
603  ObjType & obj,
604  ObjTypeFn function,
605  bool autoDel = false,
606  const char * name = NULL,
608  ) : PThread(10000,
610  priority,
611  name)
612  , m_object(obj)
613  , m_function(function)
614  {
615  PThread::Resume();
616  }
617 
618  void Main()
619  {
620  (m_object.*m_function)();
621  }
622 
623  protected:
624  ObjType & m_object;
626 };
627 
628 
629 /*
630  This template automates calling a member function with one argument within it's own thread.
631  It is used as follows:
632 
633  class Example {
634  public:
635  void Function(PString arg)
636  {
637  }
638  };
639 
640  ...
641  Example ex;
642  PString str;
643  new PThreadObj1Arg<Example>(ex, str, &Example::Function)
644  */
645 template <class ObjType, typename Arg1Type>
646 class PThreadObj1Arg : public PThread
647 {
648  PCLASSINFO(PThreadObj1Arg, PThread);
649  public:
650  typedef void (ObjType::*ObjTypeFn)(Arg1Type);
651 
653  ObjType & obj,
654  Arg1Type arg1,
655  ObjTypeFn function,
656  bool autoDel = false,
657  const char * name = NULL,
659  ) : PThread(10000,
661  priority,
662  name)
663  , m_object(obj)
664  , m_function(function)
665  , m_arg1(arg1)
666  {
667  PThread::Resume();
668  }
669 
670  void Main()
671  {
673  }
674 
675  protected:
676  ObjType & m_object;
678  Arg1Type m_arg1;
679 };
680 
681 template <class ObjType, typename Arg1Type, typename Arg2Type>
682 class PThreadObj2Arg : public PThread
683 {
684  PCLASSINFO(PThreadObj2Arg, PThread);
685  public:
686  typedef void (ObjType::*ObjTypeFn)(Arg1Type, Arg2Type);
687 
689  ObjType & obj,
690  Arg1Type arg1,
691  Arg2Type arg2,
692  ObjTypeFn function,
693  bool autoDel = false,
694  const char * name = NULL,
696  ) : PThread(10000,
698  priority,
699  name)
700  , m_object(obj)
701  , m_function(function)
702  , m_arg1(arg1)
703  , m_arg2(arg2)
704  {
705  PThread::Resume();
706  }
707 
708  void Main()
709  {
711  }
712 
713  protected:
714  ObjType & m_object;
716  Arg1Type m_arg1;
717  Arg2Type m_arg2;
718 };
719 
720 
722 //
723 // PThreadLocalStorage
724 //
725 
726 #ifdef _WIN32
727 
728 #define P_HAS_THREADLOCAL_STORAGE 1
729 
730 template <class Storage_T>
731 class PThreadLocalStorage
732 {
733  public:
734  typedef DWORD Key_T;
735  typedef Storage_T value_type;
736 
737  PThreadLocalStorage()
738  { key = TlsAlloc(); }
739 
740  ~PThreadLocalStorage()
741  { TlsFree(key); }
742 
743  Key_T GetKey() const
744  { return key; }
745 
746  value_type * Get()
747  { return (value_type *) TlsGetValue(key); }
748 
749  void Set(value_type * v)
750  { TlsSetValue(key, (LPVOID)v); }
751 
752  protected:
753  DWORD key;
754 };
755 
756 #elif defined(P_PTHREADS)
757 
758 #include <pthread.h>
759 
760 #define P_HAS_THREADLOCAL_STORAGE 1
761 
762 template <class Storage_T>
763 class PThreadLocalStorage
764 {
765  public:
766  typedef pthread_key_t Key_T;
767  typedef Storage_T value_type;
768 
769  PThreadLocalStorage()
770  { pthread_key_create(&key, NULL); }
771 
772  ~PThreadLocalStorage()
773  { pthread_key_delete(key); }
774 
775  Key_T GetKey() const
776  { return key; }
777 
778  value_type * Get()
779  { return (value_type *)pthread_getspecific(key); }
780 
781  void Set(value_type * v)
782  { pthread_setspecific(key, v); }
783 
784  private:
785  Key_T key;
786 };
787 
788 #else
789 
790 #undef P_HAS_THREADLOCAL_STORAGE 1
791 #warning("Thread local storage not supported");
792 
793 #endif
794 
795 
796 #ifdef _MSC_VER
797 #pragma warning(default:4355)
798 #endif
799 
800 #endif // PTLIB_THREAD_H
801 
802 // End Of File ///////////////////////////////////////////////////////////////
Runs approximately twice as often as normal.
Definition: thread.h:81
Arg2Type m_arg2
Definition: thread.h:717
void WaitForTermination() const
Block and wait for the thread to terminate.
AutoDeleteFlag
Codes for thread autodelete flag.
Definition: thread.h:89
PThread1Arg(Arg1Type arg1, FnType function, bool autoDel=false)
Definition: thread.h:476
This class defines a thread synchronisation object.
Definition: semaphor.h:78
virtual PString GetThreadName() const
Get the name of the thread.
Class to encapsulate tracing functions.
Definition: object.h:292
Arg1Type m_arg1
Definition: thread.h:532
Times for execution of the thread.
Definition: thread.h:295
FnType m_function
Definition: thread.h:573
This class defines an arbitrary time interval to millisecond accuracy.
Definition: timeint.h:55
Will only run if all other threads are blocked.
Definition: thread.h:75
Runs approximately half as often as normal.
Definition: thread.h:77
virtual PBoolean IsTerminated() const
Determine if the thread has been terminated or ran to completion.
virtual void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:450
Class specialisation for PNotifierTemplate
void(ObjType::* ObjTypeFn)(Arg1Type, Arg2Type)
Definition: thread.h:686
PThread3Arg(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, FnType function, bool autoDel=false)
Definition: thread.h:554
void(* FnType)()
Definition: thread.h:440
static PThread * Create(const PNotifier &notifier, const PString &threadName)
Definition: thread.h:350
Arg1Type m_arg1
Definition: thread.h:716
~PThread()
Destroy the thread, this simply calls the Terminate() function with all its restrictions and penaltie...
void(ObjType::* ObjTypeFn)(Arg1Type)
Definition: thread.h:650
Arg2Type m_arg3
Definition: thread.h:576
void(* FnType)(Arg1Type arg1, Arg2Type arg2)
Definition: thread.h:513
friend class PHouseKeepingThread
Definition: thread.h:364
Arg2Type m_arg2
Definition: thread.h:575
Definition: thread.h:682
virtual void Main()=0
User override function for the main execution routine of the thread.
Arg1Type m_arg1
Definition: thread.h:492
ObjTypeFn m_function
Definition: thread.h:677
virtual void Resume()
Resume thread execution, this is identical to Suspend(false).
Definition: thread.h:646
FnType m_function
Definition: thread.h:531
PThreadMain(FnType function, bool autoDel=false)
Definition: thread.h:441
virtual void Suspend(PBoolean susp=true)
Suspend or resume the thread.
Is only thread that will run, unless blocked.
Definition: thread.h:83
Priority
Codes for thread priorities.
Definition: thread.h:74
Define some templates to simplify the declaration of simple PThread descendants with one or two param...
Definition: thread.h:436
bool m_autoDelete
Definition: thread.h:375
PThreadMain(const char *file, int line, FnType function, bool autoDel=false)
Definition: thread.h:445
Arg1Type m_arg1
Definition: thread.h:678
void PrintOn(ostream &strm) const
Standard stream print function.
static void Sleep(const PTimeInterval &delay)
Suspend the current thread for the specified amount of time.
virtual void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:487
virtual void Terminate()
Terminate the thread.
This class represents an operating system process.
Definition: pprocess.h:227
PString m_threadName
Definition: thread.h:378
BOOL PBoolean
Definition: object.h:102
Definition: thread.h:85
virtual PThreadIdentifier GetThreadId() const
Get operating system specific thread identifier for this thread.
Definition: thread.h:291
ObjType & m_object
Definition: thread.h:624
virtual const char * GetClass(unsigned ancestor=0) const
Get the current dynamic type of the object instance.
Definition: object.h:1158
void(* FnType)(Arg1Type arg1)
Definition: thread.h:474
ObjType & m_object
Definition: thread.h:714
virtual void SetAutoDelete(AutoDeleteFlag deletion=AutoDeleteThread)
Set the flag indicating thread object is to be automatically deleted when the thread ends...
bool m_isProcess
Definition: thread.h:374
PThreadObj(ObjType &obj, ObjTypeFn function, bool autoDel=false, const char *name=NULL, PThread::Priority priority=PThread::NormalPriority)
Definition: thread.h:602
PThread2Arg(const char *file, int line, Arg1Type arg1, Arg2Type arg2, FnType function, bool autoDel=false)
Definition: thread.h:520
The character string class.
Definition: pstring.h:108
static void Yield()
Yield to another thread without blocking.
FnType m_function
Definition: thread.h:454
PTimeInterval m_kernel
Total kernel CPU time in milliseconds.
Definition: thread.h:298
static PString Empty()
Return an empty string.
Don't delete thread as it may not be on heap.
Definition: thread.h:94
virtual void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:569
PThread3Arg(const char *file, int line, Arg1Type arg1, Arg2Type arg2, Arg3Type arg3, FnType function, bool autoDel=false)
Definition: thread.h:561
Definition: thread.h:596
void SetNoAutoDelete()
Reet the flag indicating thread object is to be automatically deleted when the thread ends...
Definition: thread.h:265
This class defines a thread of execution in the system.
Definition: thread.h:66
Definition: thread.h:509
PTimeInterval m_real
Total real time since thread start in milliseconds.
Definition: thread.h:297
virtual void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:527
PMutex m_threadNameMutex
Definition: thread.h:379
Definition: thread.h:549
Arg2Type m_arg2
Definition: thread.h:533
bool GetTimes(Times &times)
Get the thread execution times.
static PThreadIdentifier GetCurrentThreadId()
void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:618
static PThread * Create(const PNotifier &notifier, INT parameter=0, AutoDeleteFlag deletion=AutoDeleteThread, Priority priorityLevel=NormalPriority, const PString &threadName=PString::Empty(), PINDEX stackSize=65536)
Create a simple thread executing the specified notifier.
void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:670
Definition: thread.h:470
This template class maps the PAbstractList to a specific object type, and adds functionality that all...
Definition: lists.h:582
bool IsAutoDelete() const
Definition: thread.h:356
void(ObjType::* ObjTypeFn)()
Definition: thread.h:600
static PThread * Current()
Get the currently running thread object instance.
virtual void Restart()
Restart a terminated thread using the same stack priority etc that was current when the thread termin...
Automatically delete thread object on termination.
Definition: thread.h:91
virtual PBoolean IsSuspended() const
Determine if the thread is currently suspended.
Synonym for PTimedMutex.
void(* FnType)(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3)
Definition: thread.h:553
PINDEX m_originalStackSize
Definition: thread.h:376
virtual void SetThreadName(const PString &name)
Change the name of the thread.
PThreadObj1Arg(ObjType &obj, Arg1Type arg1, ObjTypeFn function, bool autoDel=false, const char *name=NULL, PThread::Priority priority=PThread::NormalPriority)
Definition: thread.h:652
virtual Priority GetPriority() const
Get the current priority of the thread in the current process.
void Main()
User override function for the main execution routine of the thread.
Definition: thread.h:708
PThread(PINDEX, AutoDeleteFlag deletion=AutoDeleteThread, Priority priorityLevel=NormalPriority, const PString &threadName=PString::Empty())
Create a new thread instance.
PString psprintf(const char *fmt,...)
The same as the standard C snprintf(fmt, 1000, ...), but returns a PString instead of a const char *...
ObjType & m_object
Definition: thread.h:676
Ultimate parent class for all objects in the class library.
Definition: object.h:1118
Normal priority for a thread.
Definition: thread.h:79
Arg1Type m_arg1
Definition: thread.h:574
friend class PExternalThread
Definition: thread.h:363
PThreadObj2Arg(ObjType &obj, Arg1Type arg1, Arg2Type arg2, ObjTypeFn function, bool autoDel=false, const char *name=NULL, PThread::Priority priority=PThread::NormalPriority)
Definition: thread.h:688
PTimeInterval m_user
Total user CPU time in milliseconds.
Definition: thread.h:299
PThread2Arg(Arg1Type arg1, Arg2Type arg2, FnType function, bool autoDel=false)
Definition: thread.h:514
friend ostream & operator<<(ostream &strm, const Times &times)
PThreadIdentifier m_threadId
Definition: thread.h:381
virtual void SetPriority(Priority priorityLevel)
Set the priority of the thread relative to other threads in the current process.
ObjTypeFn m_function
Definition: thread.h:715
ObjTypeFn m_function
Definition: thread.h:625
PThread1Arg(const char *file, int line, Arg1Type arg1, FnType function, bool autoDel=false)
Definition: thread.h:481
FnType m_function
Definition: thread.h:491