PTLib  Version 2.12.9
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
pprocess.h
Go to the documentation of this file.
1 /*
2  * pprocess.h
3  *
4  * Operating System Process (running program executable) class.
5  *
6  * Portable Windows Library
7  *
8  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Portable Windows Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25  * All Rights Reserved.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 30255 $
30  * $Author: rjongbloed $
31  * $Date: 2013-08-07 13:53:48 +1000 (Wed, 07 Aug 2013) $
32  */
33 
34 #ifndef PTLIB_PROCESS_H
35 #define PTLIB_PROCESS_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <ptlib/mutex.h>
43 #include <ptlib/thread.h>
44 #include <ptlib/pfactory.h>
45 
46 #include <queue>
47 #include <set>
48 
55 #ifdef P_VXWORKS
56 #define PCREATE_PROCESS(cls) \
57  cls instance; \
58  instance.InternalMain();
59 #elif defined(P_RTEMS)
60 #define PCREATE_PROCESS(cls) \
61 extern "C" {\
62  void* POSIX_Init( void* argument) \
63  { \
64  static cls instance; \
65  exit( instance.InternalMain() ); \
66  } \
67 }
68 #elif defined(_WIN32_WCE)
69 #define PCREATE_PROCESS(cls) \
70  PDEFINE_WINMAIN(hInstance, , lpCmdLine, ) \
71  { \
72  cls *pInstance = new cls(); \
73  pInstance->GetArguments().SetArgs(lpCmdLine); \
74  int terminationValue = pInstance->InternalMain(hInstance); \
75  delete pInstance; \
76  return terminationValue; \
77  }
78 #else
79 #define PCREATE_PROCESS(cls) \
80  int main(int argc, char * argv[]) \
81  { \
82  cls *pInstance = new cls(); \
83  pInstance->PreInitialise(argc, argv); \
84  int terminationValue = pInstance->InternalMain(); \
85  delete pInstance; \
86  return terminationValue; \
87  }
88 #endif // P_VXWORKS
89 
90 /*$MACRO PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build)
91  This macro is used to declare the components necessary for a user PWLib
92  process. This will declare the PProcess descendent class, eg PApplication,
93  and create an instance of the class. See the <code>PCREATE_PROCESS</code> macro
94  for more details.
95  */
96 #define PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build) \
97  class cls : public ancestor { \
98  PCLASSINFO(cls, ancestor); \
99  public: \
100  cls() : ancestor(manuf, name, major, minor, status, build) { } \
101  private: \
102  virtual void Main(); \
103  };
104 
105 
106 class PTimerList : public PObject
107 /* This class defines a list of <code>PTimer</code> objects. It is primarily used
108  internally by the library and the user should never create an instance of
109  it. The <code>PProcess</code> instance for the application maintains an instance
110  of all of the timers created so that it may decrements them at regular
111  intervals.
112  */
113 {
114  PCLASSINFO(PTimerList, PObject);
115 
116  public:
117  // Create a new timer list
118  PTimerList();
119 
120  /* Decrement all the created timers and dispatch to their callback
121  functions if they have expired. The <code>PTimer::Tick()</code> function
122  value is used to determine the time elapsed since the last call to
123  Process().
124 
125  The return value is the number of milliseconds until the next timer
126  needs to be despatched. The function need not be called again for this
127  amount of time, though it can (and usually is).
128 
129  @return
130  maximum time interval before function should be called again.
131  */
133 
134  PTimer::IDType GetNewTimerId() const { return ++timerId; }
135 
136  class RequestType {
137  public:
138  enum Action {
142  } m_action;
143 
145  : m_action(act)
146  , m_timer(t)
147  , m_id(t->GetTimerId())
148  , m_absoluteTime(t->GetAbsoluteTime())
149  , m_serialNumber(t->GetNextSerialNumber())
150  , m_sync(NULL)
151  { }
152 
158  };
159 
160  void QueueRequest(RequestType::Action action, PTimer * timer, bool isSync = true);
161 
162  void ProcessTimerQueue();
163 
164  private:
165  // queue of timer action requests
166  PMutex m_queueMutex;
167  typedef std::queue<RequestType> RequestQueueType;
168  RequestQueueType m_requestQueue;
169 
170  // counter to keep track of timer IDs
171  mutable PAtomicInteger timerId;
172 
173  // map used to store active timer information
174  struct ActiveTimerInfo {
175  ActiveTimerInfo(PTimer * t, PAtomicInteger::IntegerType serialNumber)
176  : m_timer(t), m_serialNumber(serialNumber) { }
177  PTimer * m_timer;
178  PAtomicInteger::IntegerType m_serialNumber;
179  };
180  typedef std::map<PTimer::IDType, ActiveTimerInfo> ActiveTimerInfoMap;
181  ActiveTimerInfoMap m_activeTimers;
182 
183  // set used to store timer expiry times, in order
184  struct TimerExpiryInfo {
185  TimerExpiryInfo(PTimer::IDType id, PInt64 expireTime, PAtomicInteger::IntegerType serialNumber)
186  : m_timerId(id), m_expireTime(expireTime), m_serialNumber(serialNumber) { }
187  PTimer::IDType m_timerId;
188  PInt64 m_expireTime;
189  PAtomicInteger::IntegerType m_serialNumber;
190  };
191 
192  struct TimerExpiryInfo_compare
193  : public binary_function<TimerExpiryInfo, TimerExpiryInfo, bool>
194  {
195  bool operator()(const TimerExpiryInfo & _Left, const TimerExpiryInfo & _Right) const
196  { return (_Left.m_expireTime < _Right.m_expireTime); }
197  };
198 
199  typedef std::multiset<TimerExpiryInfo, TimerExpiryInfo_compare> TimerExpiryInfoList;
200  TimerExpiryInfoList m_expiryList;
201 
202  // The last system timer tick value that was used to process timers.
203  PTimeInterval m_lastSample;
204 
205  // thread that handles the timer stuff
206  PThread * m_timerThread;
207 };
208 
209 
211 // PProcess
212 
225 class PProcess : public PThread
226 {
227  PCLASSINFO(PProcess, PThread);
228 
229  public:
232 
233  enum CodeStatus {
241  };
242 
245  PProcess(
246  const char * manuf = "",
247  const char * name = "",
248  WORD majorVersion = 1,
249  WORD minorVersion = 0,
251  WORD buildNumber = 1,
252  bool library = false,
253  bool suppressStartup = false
254  );
256 
266  const PObject & obj
267  ) const;
269 
274  virtual void Terminate();
276 
285  static PProcess & Current();
286 
289  void Startup();
290 
294  virtual void OnThreadStart(
295  PThread & thread
296  );
297 
301  virtual void OnThreadEnded(
302  PThread & thread
303  );
304 
317  virtual bool OnInterrupt(
318  bool terminating
319  );
320 
327  static PBoolean IsInitialised();
328 
335  void SetTerminationValue(
336  int value
337  );
338 
348  int GetTerminationValue() const;
349 
357 
367  virtual const PString & GetManufacturer() const;
368 
378  virtual const PString & GetName() const;
379 
394  virtual PString GetVersion(
395  PBoolean full = true
396  ) const;
397 
403  const PFilePath & GetFile() const;
404 
412  PProcessIdentifier GetProcessID() const { return m_processID; }
413 
421  static PProcessIdentifier GetCurrentProcessID();
422 
425  PTime GetStartTime() const;
426 
435  PString GetUserName() const;
436 
460  const PString & username,
461  PBoolean permanent = false
462  );
463 
469 
478  PString GetGroupName() const;
479 
505  const PString & groupname,
506  PBoolean permanent = false
507  );
508 
515  int GetMaxHandles() const;
516 
527  int newLimit
528  );
529 
530 #if P_CONFIG_FILE
531 
533  virtual PString GetConfigurationFile();
534 
549  const PString & path
550  );
551 #endif // P_CONFIG_FILE
552 
553 
562  static PString GetOSClass();
563 
570  static PString GetOSName();
571 
577  static PString GetOSHardware();
578 
585  static PString GetOSVersion();
586 
592  static bool IsOSVersion(
593  unsigned major,
594  unsigned minor = 0,
595  unsigned build = 0
596  );
597 
605  static PDirectory GetOSConfigDir();
606 
613  static PString GetLibVersion();
615 
623 
627  void PreInitialise(
628  int argc, // Number of program arguments.
629  char ** argv // Array of strings for program arguments.
630  );
631 
635  void PreShutdown();
636  static void PostShutdown();
637 
639  virtual int InternalMain(void * arg = NULL);
640 
663  {
664  public:
666  { }
667 
669  : type(t)
670  { }
671 
672  static bool RegisterTypes(const PString & types, bool force = true);
673 
674  void SetIcon(const PString & icon);
675  PString GetIcon() const;
676 
677  void SetCommand(const PString & key, const PString & command);
678  PString GetCommand(const PString & key) const;
679 
680  bool GetFromSystem();
681  bool CheckIfRegistered();
682 
683  bool Register();
684 
686 
687  #if _WIN32
688  PString iconFileName;
689  PStringToString cmds;
690  #endif
691  };
693 
694  PThread * GetThread(PThreadIdentifier threadId) const;
695  bool SignalTimerChange();
696 
697  protected:
698  void Construct();
699 
700  // Member variables
701  bool m_library; // Indication PTLib is being used as a library for an external process.
702  int terminationValue; // Application return value
703 
704  PString manufacturer; // Application manufacturer name.
705  PString productName; // Application executable base name from argv[0]
706 
707  WORD majorVersion; // Major version number of the product
708  WORD minorVersion; // Minor version number of the product
709  CodeStatus status; // Development status of the product
710  WORD buildNumber; // Build number of the product
711 
712  PFilePath executableFile; // Application executable file from argv[0] (not open)
713  PStringArray configurationPaths; // Explicit file or set of directories to find default PConfig
714  PArgList arguments; // The list of arguments
715  int maxHandles; // Maximum number of file handles process can open.
716 
717  PTime programStartTime; // time at which process was intantiated, i.e. started
718 
721 
722  typedef std::map<PThreadIdentifier, PThread *> ThreadMap;
724  void InternalThreadStarted(PThread * thread);
725  void InternalThreadEnded(PThread * thread);
726 
729  void InternalSetAutoDeleteThread(PThread * thread);
731 
733  PThread * m_houseKeeper; // Thread for doing timers, thread clean up etc.
735  void HouseKeeping();
736 
738 
739  PProcessIdentifier m_processID;
740 
741  friend class PThread;
742 
743 
744 // Include platform dependent part of class
745 #ifdef _WIN32
746 #include "msos/ptlib/pprocess.h"
747 #else
748 #include "unix/ptlib/pprocess.h"
749 #endif
750 };
751 
752 
755  class PLibraryProcess : public PProcess
756  {
757  PCLASSINFO(PLibraryProcess, PProcess);
758 
759  public:
765  const char * manuf = "",
766  const char * name = "",
767  WORD majorVersionNum = 1,
768  WORD minorVersionNum = 0,
769  CodeStatus statusCode = ReleaseCode,
770  WORD buildNum = 1
771  ) : PProcess(manuf, name, majorVersionNum, minorVersionNum, statusCode, buildNum, true) { }
773 
775  virtual void Main() { }
776 };
777 
778 
779 /*
780  * one instance of this class (or any descendants) will be instantiated
781  * via PGenericFactory<PProessStartup> one "main" has been started, and then
782  * the OnStartup() function will be called. The OnShutdown function will
783  * be called after main exits, and the instances will be destroyed if they
784  * are not singletons
785  */
786 class PProcessStartup : public PObject
787 {
789  public:
790  virtual void OnStartup() { }
791  virtual void OnShutdown() { }
792 };
793 
795 
796 #if PTRACING
797 
798 // using an inline definition rather than a #define crashes gcc 2.95. Go figure
799 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
800 
801 template <unsigned level, unsigned options = P_DEFAULT_TRACE_OPTIONS >
802 class PTraceLevelSetStartup : public PProcessStartup
803 {
804  public:
805  void OnStartup()
806  { PTrace::Initialise(level, NULL, options); }
807 };
808 
809 #endif // PTRACING
810 
811 
812 #endif // PTLIB_PROCESS_H
813 
814 
815 // End Of File ///////////////////////////////////////////////////////////////