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 PTLIB_PROCESS_H
00035 #define PTLIB_PROCESS_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <ptlib/mutex.h>
00042 #include <ptlib/syncpoint.h>
00043 #include <ptlib/thread.h>
00044 #include <ptlib/pfactory.h>
00045
00046 #include <queue>
00047 #include <set>
00048
00055 #ifdef P_VXWORKS
00056 #define PCREATE_PROCESS(cls) \
00057 cls instance; \
00058 instance.InternalMain();
00059 #elif defined(P_RTEMS)
00060 #define PCREATE_PROCESS(cls) \
00061 extern "C" {\
00062 void* POSIX_Init( void* argument) \
00063 { \
00064 static cls instance; \
00065 exit( instance.InternalMain() ); \
00066 } \
00067 }
00068 #elif defined(_WIN32_WCE)
00069 #define PCREATE_PROCESS(cls) \
00070 int WinMain(HINSTANCE hInst, HINSTANCE, LPWSTR cmdLine, int) \
00071 { \
00072 cls *pInstance = new cls(); \
00073 pInstance->GetArguments().SetArgs(cmdLine); \
00074 int terminationValue = pInstance->InternalMain(hInst); \
00075 delete pInstance; \
00076 return terminationValue; \
00077 }
00078 #else
00079 #define PCREATE_PROCESS(cls) \
00080 int main(int argc, char ** argv, char ** envp) \
00081 { \
00082 cls *pInstance = new cls(); \
00083 pInstance->PreInitialise(argc, argv, envp); \
00084 int terminationValue = pInstance->InternalMain(); \
00085 delete pInstance; \
00086 return terminationValue; \
00087 }
00088 #endif // P_VXWORKS
00089
00090
00091
00092
00093
00094
00095
00096 #define PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build) \
00097 class cls : public ancestor { \
00098 PCLASSINFO(cls, ancestor); \
00099 public: \
00100 cls() : ancestor(manuf, name, major, minor, status, build) { } \
00101 private: \
00102 virtual void Main(); \
00103 };
00104
00105
00106 class PTimerList : public PObject
00107
00108
00109
00110
00111
00112
00113 {
00114 PCLASSINFO(PTimerList, PObject);
00115
00116 public:
00117
00118 PTimerList();
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 PTimeInterval Process();
00133
00134 PTimer::IDType GetNewTimerId() const { return ++timerId; }
00135
00136 class RequestType {
00137 public:
00138 enum Action {
00139 Stop,
00140 Start
00141 } m_action;
00142
00143 RequestType(Action act, PTimer * t)
00144 : m_action(act)
00145 , m_timer(t)
00146 , m_id(t->GetTimerId())
00147 , m_absoluteTime(t->GetAbsoluteTime())
00148 , m_serialNumber(t->GetNextSerialNumber())
00149 , m_sync(NULL)
00150 { }
00151
00152 PTimer * m_timer;
00153 PTimer::IDType m_id;
00154 PInt64 m_absoluteTime;
00155 PAtomicInteger::IntegerType m_serialNumber;
00156 PSyncPoint * m_sync;
00157 };
00158
00159 void QueueRequest(RequestType::Action action, PTimer * timer, bool isSync = true);
00160
00161 void ProcessTimerQueue();
00162
00163 private:
00164
00165 PMutex m_queueMutex;
00166 typedef std::queue<RequestType> RequestQueueType;
00167 RequestQueueType m_requestQueue;
00168
00169
00170 void AddActiveTimer(const RequestType & request);
00171
00172
00173 mutable PAtomicInteger timerId;
00174
00175
00176 struct ActiveTimerInfo {
00177 ActiveTimerInfo(PTimer * t, PAtomicInteger::IntegerType serialNumber)
00178 : m_timer(t), m_serialNumber(serialNumber) { }
00179 PTimer * m_timer;
00180 PAtomicInteger::IntegerType m_serialNumber;
00181 };
00182 typedef std::map<PTimer::IDType, ActiveTimerInfo> ActiveTimerInfoMap;
00183 ActiveTimerInfoMap m_activeTimers;
00184
00185
00186 struct TimerExpiryInfo {
00187 TimerExpiryInfo(PTimer::IDType id, PInt64 expireTime, PAtomicInteger::IntegerType serialNumber)
00188 : m_timerId(id), m_expireTime(expireTime), m_serialNumber(serialNumber) { }
00189 PTimer::IDType m_timerId;
00190 PInt64 m_expireTime;
00191 PAtomicInteger::IntegerType m_serialNumber;
00192 };
00193
00194 struct TimerExpiryInfo_compare
00195 : public binary_function<TimerExpiryInfo, TimerExpiryInfo, bool>
00196 {
00197 bool operator()(const TimerExpiryInfo & _Left, const TimerExpiryInfo & _Right) const
00198 { return (_Left.m_expireTime < _Right.m_expireTime); }
00199 };
00200
00201 typedef std::multiset<TimerExpiryInfo, TimerExpiryInfo_compare> TimerExpiryInfoList;
00202 TimerExpiryInfoList m_expiryList;
00203
00204
00205 PTimeInterval m_lastSample;
00206
00207
00208 PThread * m_timerThread;
00209 };
00210
00211
00213
00214
00227 class PProcess : public PThread
00228 {
00229 PCLASSINFO(PProcess, PThread);
00230
00231 public:
00234
00235 enum CodeStatus {
00237 AlphaCode,
00239 BetaCode,
00241 ReleaseCode,
00242 NumCodeStatuses
00243 };
00244
00247 PProcess(
00248 const char * manuf = "",
00249 const char * name = "",
00250 WORD majorVersion = 1,
00251 WORD minorVersion = 0,
00252 CodeStatus status = ReleaseCode,
00253 WORD buildNumber = 1,
00254 bool library = false
00255 );
00257
00266 Comparison Compare(
00267 const PObject & obj
00268 ) const;
00270
00275 virtual void Terminate();
00276
00282 virtual PString GetThreadName() const;
00283
00289 virtual void SetThreadName(
00290 const PString & name
00291 );
00293
00302 static PProcess & Current();
00303
00307 virtual void OnThreadStart(
00308 PThread & thread
00309 );
00310
00314 virtual void OnThreadEnded(
00315 PThread & thread
00316 );
00317
00330 virtual bool OnInterrupt(
00331 bool terminating
00332 );
00333
00340 static PBoolean IsInitialised();
00341
00348 void SetTerminationValue(
00349 int value
00350 );
00351
00361 int GetTerminationValue() const;
00362
00369 PArgList & GetArguments();
00370
00380 virtual const PString & GetManufacturer() const;
00381
00391 virtual const PString & GetName() const;
00392
00407 virtual PString GetVersion(
00408 PBoolean full = true
00409 ) const;
00410
00416 const PFilePath & GetFile() const;
00417
00425 DWORD GetProcessID() const;
00426
00429 PTime GetStartTime() const;
00430
00439 PString GetUserName() const;
00440
00463 PBoolean SetUserName(
00464 const PString & username,
00465 PBoolean permanent = false
00466 );
00467
00476 PString GetGroupName() const;
00477
00502 PBoolean SetGroupName(
00503 const PString & groupname,
00504 PBoolean permanent = false
00505 );
00506
00513 int GetMaxHandles() const;
00514
00524 PBoolean SetMaxHandles(
00525 int newLimit
00526 );
00527
00528 #ifdef P_CONFIG_FILE
00529
00531 virtual PString GetConfigurationFile();
00532 #endif
00533
00547 void SetConfigurationPath(
00548 const PString & path
00549 );
00551
00560 static PString GetOSClass();
00561
00568 static PString GetOSName();
00569
00575 static PString GetOSHardware();
00576
00583 static PString GetOSVersion();
00584
00592 static PDirectory GetOSConfigDir();
00593
00600 static PString GetLibVersion();
00602
00609 PTimerList * GetTimerList();
00610
00614 void PreInitialise(
00615 int argc,
00616 char ** argv,
00617 char ** envp
00618 );
00619
00623 static void PreShutdown();
00624 static void PostShutdown();
00625
00627 virtual int InternalMain(void * arg = NULL);
00628
00650 class HostSystemURLHandlerInfo
00651 {
00652 public:
00653 HostSystemURLHandlerInfo()
00654 { }
00655
00656 HostSystemURLHandlerInfo(const PString & t)
00657 : type(t)
00658 { }
00659
00660 static bool RegisterTypes(const PString & types, bool force = true);
00661
00662 void SetIcon(const PString & icon);
00663 PString GetIcon() const;
00664
00665 void SetCommand(const PString & key, const PString & command);
00666 PString GetCommand(const PString & key) const;
00667
00668 bool GetFromSystem();
00669 bool CheckIfRegistered();
00670
00671 bool Register();
00672
00673 PString type;
00674
00675 #if _WIN32
00676 PString iconFileName;
00677 PStringToString cmds;
00678 #endif
00679 };
00681
00682 protected:
00683 void Construct();
00684
00685
00686 int terminationValue;
00687
00688
00689 PString manufacturer;
00690
00691
00692 PString productName;
00693
00694
00695 WORD majorVersion;
00696
00697
00698 WORD minorVersion;
00699
00700
00701 CodeStatus status;
00702
00703
00704 WORD buildNumber;
00705
00706
00707 PFilePath executableFile;
00708
00709
00710 PStringArray configurationPaths;
00711
00712
00713 PArgList arguments;
00714
00715
00716 PTimerList timers;
00717
00718
00719 PTime programStartTime;
00720
00721
00722 int maxHandles;
00723
00724
00725 bool m_library;
00726
00727 bool m_shuttingDown;
00728
00729 typedef std::map<PThreadIdentifier, PThread *> ThreadMap;
00730 ThreadMap m_activeThreads;
00731 PMutex m_activeThreadMutex;
00732
00733 friend class PThread;
00734
00735
00736
00737 #ifdef _WIN32
00738 #include "msos/ptlib/pprocess.h"
00739 #else
00740 #include "unix/ptlib/pprocess.h"
00741 #endif
00742 };
00743
00744
00747 class PLibraryProcess : public PProcess
00748 {
00749 PCLASSINFO(PLibraryProcess, PProcess);
00750
00751 public:
00756 PLibraryProcess(
00757 const char * manuf = "",
00758 const char * name = "",
00759 WORD majorVersionNum = 1,
00760 WORD minorVersionNum = 0,
00761 CodeStatus statusCode = ReleaseCode,
00762 WORD buildNum = 1
00763 ) : PProcess(manuf, name, majorVersionNum, minorVersionNum, statusCode, buildNum, true) { }
00765
00767 virtual void Main() { }
00768 };
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 class PProcessStartup : public PObject
00779 {
00780 PCLASSINFO(PProcessStartup, PObject)
00781 public:
00782 virtual void OnStartup() { }
00783 virtual void OnShutdown() { }
00784 };
00785
00786 typedef PFactory<PProcessStartup> PProcessStartupFactory;
00787
00788 #if PTRACING
00789
00790
00791 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
00792
00793 template <unsigned level, unsigned options = P_DEFAULT_TRACE_OPTIONS >
00794 class PTraceLevelSetStartup : public PProcessStartup
00795 {
00796 public:
00797 void OnStartup()
00798 { PTrace::Initialise(level, NULL, options); }
00799 };
00800
00801 #endif // PTRACING
00802
00803
00804 #endif // PTLIB_PROCESS_H
00805
00806
00807