00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
00349
00350
00351
00352 private:
00353 PThread();
00354
00355
00356 friend class PProcess;
00357
00358
00359 PThread(const PThread &) : PObject () { }
00360
00361
00362 PThread & operator=(const PThread &) { return *this; }
00363
00364
00365 PBoolean autoDelete;
00366
00367
00368
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
00384 #ifdef _WIN32
00385 #include "msos/ptlib/thread.h"
00386 #else
00387 #include "unix/ptlib/thread.h"
00388 #endif
00389 };
00390
00391
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
00408
00409
00410
00411
00412
00413
00414
00415
00416
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
00437
00438
00439
00440
00441
00442
00443
00444
00445
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
00471
00472
00473
00474
00475
00476
00477
00478
00479
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
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
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
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
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