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
00590 static bool IsOSVersion(
00591 unsigned major,
00592 unsigned minor = 0,
00593 unsigned build = 0
00594 );
00595
00603 static PDirectory GetOSConfigDir();
00604
00611 static PString GetLibVersion();
00613
00620 PTimerList * GetTimerList();
00621
00625 void PreInitialise(
00626 int argc,
00627 char ** argv,
00628 char ** envp
00629 );
00630
00634 static void PreShutdown();
00635 static void PostShutdown();
00636
00638 virtual int InternalMain(void * arg = NULL);
00639
00661 class HostSystemURLHandlerInfo
00662 {
00663 public:
00664 HostSystemURLHandlerInfo()
00665 { }
00666
00667 HostSystemURLHandlerInfo(const PString & t)
00668 : type(t)
00669 { }
00670
00671 static bool RegisterTypes(const PString & types, bool force = true);
00672
00673 void SetIcon(const PString & icon);
00674 PString GetIcon() const;
00675
00676 void SetCommand(const PString & key, const PString & command);
00677 PString GetCommand(const PString & key) const;
00678
00679 bool GetFromSystem();
00680 bool CheckIfRegistered();
00681
00682 bool Register();
00683
00684 PString type;
00685
00686 #if _WIN32
00687 PString iconFileName;
00688 PStringToString cmds;
00689 #endif
00690 };
00692
00693 protected:
00694 void Construct();
00695
00696
00697 int terminationValue;
00698
00699
00700 PString manufacturer;
00701
00702
00703 PString productName;
00704
00705
00706 WORD majorVersion;
00707
00708
00709 WORD minorVersion;
00710
00711
00712 CodeStatus status;
00713
00714
00715 WORD buildNumber;
00716
00717
00718 PFilePath executableFile;
00719
00720
00721 PStringArray configurationPaths;
00722
00723
00724 PArgList arguments;
00725
00726
00727 PTimerList timers;
00728
00729
00730 PTime programStartTime;
00731
00732
00733 int maxHandles;
00734
00735
00736 bool m_library;
00737
00738 bool m_shuttingDown;
00739
00740 typedef std::map<PThreadIdentifier, PThread *> ThreadMap;
00741 ThreadMap m_activeThreads;
00742 PMutex m_activeThreadMutex;
00743
00744 friend class PThread;
00745
00746
00747
00748 #ifdef _WIN32
00749 #include "msos/ptlib/pprocess.h"
00750 #else
00751 #include "unix/ptlib/pprocess.h"
00752 #endif
00753 };
00754
00755
00758 class PLibraryProcess : public PProcess
00759 {
00760 PCLASSINFO(PLibraryProcess, PProcess);
00761
00762 public:
00767 PLibraryProcess(
00768 const char * manuf = "",
00769 const char * name = "",
00770 WORD majorVersionNum = 1,
00771 WORD minorVersionNum = 0,
00772 CodeStatus statusCode = ReleaseCode,
00773 WORD buildNum = 1
00774 ) : PProcess(manuf, name, majorVersionNum, minorVersionNum, statusCode, buildNum, true) { }
00776
00778 virtual void Main() { }
00779 };
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 class PProcessStartup : public PObject
00790 {
00791 PCLASSINFO(PProcessStartup, PObject)
00792 public:
00793 virtual void OnStartup() { }
00794 virtual void OnShutdown() { }
00795 };
00796
00797 typedef PFactory<PProcessStartup> PProcessStartupFactory;
00798
00799 #if PTRACING
00800
00801
00802 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
00803
00804 template <unsigned level, unsigned options = P_DEFAULT_TRACE_OPTIONS >
00805 class PTraceLevelSetStartup : public PProcessStartup
00806 {
00807 public:
00808 void OnStartup()
00809 { PTrace::Initialise(level, NULL, options); }
00810 };
00811
00812 #endif // PTRACING
00813
00814
00815 #endif // PTLIB_PROCESS_H
00816
00817
00818