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 PDEFINE_WINMAIN(hInstance, , lpCmdLine, ) \
00071 { \
00072 cls *pInstance = new cls(); \
00073 pInstance->GetArguments().SetArgs(lpCmdLine); \
00074 int terminationValue = pInstance->InternalMain(hInstance); \
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 PProcessIdentifier GetProcessID() const { return m_processID; }
00426
00434 static PProcessIdentifier GetCurrentProcessID();
00435
00438 PTime GetStartTime() const;
00439
00448 PString GetUserName() const;
00449
00472 PBoolean SetUserName(
00473 const PString & username,
00474 PBoolean permanent = false
00475 );
00476
00485 PString GetGroupName() const;
00486
00511 PBoolean SetGroupName(
00512 const PString & groupname,
00513 PBoolean permanent = false
00514 );
00515
00522 int GetMaxHandles() const;
00523
00533 PBoolean SetMaxHandles(
00534 int newLimit
00535 );
00536
00537 #ifdef P_CONFIG_FILE
00538
00540 virtual PString GetConfigurationFile();
00541 #endif
00542
00556 void SetConfigurationPath(
00557 const PString & path
00558 );
00560
00569 static PString GetOSClass();
00570
00577 static PString GetOSName();
00578
00584 static PString GetOSHardware();
00585
00592 static PString GetOSVersion();
00593
00599 static bool IsOSVersion(
00600 unsigned major,
00601 unsigned minor = 0,
00602 unsigned build = 0
00603 );
00604
00612 static PDirectory GetOSConfigDir();
00613
00620 static PString GetLibVersion();
00622
00629 PTimerList * GetTimerList();
00630
00634 void PreInitialise(
00635 int argc,
00636 char ** argv,
00637 char ** envp
00638 );
00639
00643 static void PreShutdown();
00644 static void PostShutdown();
00645
00647 virtual int InternalMain(void * arg = NULL);
00648
00670 class HostSystemURLHandlerInfo
00671 {
00672 public:
00673 HostSystemURLHandlerInfo()
00674 { }
00675
00676 HostSystemURLHandlerInfo(const PString & t)
00677 : type(t)
00678 { }
00679
00680 static bool RegisterTypes(const PString & types, bool force = true);
00681
00682 void SetIcon(const PString & icon);
00683 PString GetIcon() const;
00684
00685 void SetCommand(const PString & key, const PString & command);
00686 PString GetCommand(const PString & key) const;
00687
00688 bool GetFromSystem();
00689 bool CheckIfRegistered();
00690
00691 bool Register();
00692
00693 PString type;
00694
00695 #if _WIN32
00696 PString iconFileName;
00697 PStringToString cmds;
00698 #endif
00699 };
00701
00702 protected:
00703 void Construct();
00704
00705
00706 bool m_library;
00707 int terminationValue;
00708
00709 PString manufacturer;
00710 PString productName;
00711
00712 WORD majorVersion;
00713 WORD minorVersion;
00714 CodeStatus status;
00715 WORD buildNumber;
00716
00717 PFilePath executableFile;
00718 PStringArray configurationPaths;
00719 PArgList arguments;
00720 int maxHandles;
00721
00722 PTime programStartTime;
00723
00724 bool m_shuttingDown;
00725
00726 typedef std::map<PThreadIdentifier, PThread *> ThreadMap;
00727 ThreadMap m_activeThreads;
00728 PMutex m_activeThreadMutex;
00729
00730 PTimerList timers;
00731
00732 PProcessIdentifier m_processID;
00733
00734 friend class PThread;
00735
00736
00737
00738 #ifdef _WIN32
00739 #include "msos/ptlib/pprocess.h"
00740 #else
00741 #include "unix/ptlib/pprocess.h"
00742 #endif
00743 };
00744
00745
00748 class PLibraryProcess : public PProcess
00749 {
00750 PCLASSINFO(PLibraryProcess, PProcess);
00751
00752 public:
00757 PLibraryProcess(
00758 const char * manuf = "",
00759 const char * name = "",
00760 WORD majorVersionNum = 1,
00761 WORD minorVersionNum = 0,
00762 CodeStatus statusCode = ReleaseCode,
00763 WORD buildNum = 1
00764 ) : PProcess(manuf, name, majorVersionNum, minorVersionNum, statusCode, buildNum, true) { }
00766
00768 virtual void Main() { }
00769 };
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 class PProcessStartup : public PObject
00780 {
00781 PCLASSINFO(PProcessStartup, PObject)
00782 public:
00783 virtual void OnStartup() { }
00784 virtual void OnShutdown() { }
00785 };
00786
00787 typedef PFactory<PProcessStartup> PProcessStartupFactory;
00788
00789 #if PTRACING
00790
00791
00792 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
00793
00794 template <unsigned level, unsigned options = P_DEFAULT_TRACE_OPTIONS >
00795 class PTraceLevelSetStartup : public PProcessStartup
00796 {
00797 public:
00798 void OnStartup()
00799 { PTrace::Initialise(level, NULL, options); }
00800 };
00801
00802 #endif // PTRACING
00803
00804
00805 #endif // PTLIB_PROCESS_H
00806
00807
00808