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 class PSemaphore;
00046
00047 #define PThreadIdentifer PThreadIdentifier
00048
00049 typedef P_THREADIDENTIFIER PThreadIdentifier;
00050
00052
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
00343
00344
00345
00346 private:
00347 PThread();
00348
00349
00350 friend class PProcess;
00351
00352
00353 PThread(const PThread &) : PObject () { }
00354
00355
00356 PThread & operator=(const PThread &) { return *this; }
00357
00358
00359 PBoolean autoDelete;
00360
00361
00362
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
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
00394
00395
00396
00397
00398
00399
00400
00401
00402
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
00423
00424
00425
00426
00427
00428
00429
00430
00431
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
00457
00458
00459
00460
00461
00462
00463
00464
00465
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
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
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
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
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