# pprocess.h

Go to the documentation of this file.

    00001 /*
    00002  * pprocess.h
    00003  *
    00004  * Operating System Process (running program executable) class.
    00005  *
    00006  * Portable Windows Library
    00007  *
    00008  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Portable Windows Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00023  *
    00024  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
    00025  * All Rights Reserved.
    00026  *
    00027  * Contributor(s): ______________________________________.
    00028  *
    00029  * $Revision: 27817 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2012-06-12 21:52:14 -0500 (Tue, 12 Jun 2012) $
    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 /*$MACRO PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build)
    00091    This macro is used to declare the components necessary for a user PWLib
    00092    process. This will declare the PProcess descendent class, eg PApplication,
    00093    and create an instance of the class. See the <code>PCREATE_PROCESS</code> macro
    00094    for more details.
    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 /* This class defines a list of <code>PTimer</code> objects. It is primarily used
    00108    internally by the library and the user should never create an instance of
    00109    it. The <code>PProcess</code> instance for the application maintains an instance
    00110    of all of the timers created so that it may decrements them at regular
    00111    intervals.
    00112  */
    00113 {
    00114   PCLASSINFO(PTimerList, PObject);
    00115
    00116   public:
    00117     // Create a new timer list
    00118     PTimerList();
    00119
    00120     /* Decrement all the created timers and dispatch to their callback
    00121        functions if they have expired. The <code>PTimer::Tick()</code> function
    00122        value is used to determine the time elapsed since the last call to
    00123        Process().
    00124
    00125        The return value is the number of milliseconds until the next timer
    00126        needs to be despatched. The function need not be called again for this
    00127        amount of time, though it can (and usually is).
    00128
    00129        @return
    00130        maximum time interval before function should be called again.
    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     // queue of timer action requests
    00165     PMutex m_queueMutex;
    00166     typedef std::queue<RequestType> RequestQueueType;
    00167     RequestQueueType m_requestQueue;
    00168
    00169     // add an active timer to the lists
    00170     void AddActiveTimer(const RequestType & request);
    00171
    00172     //  counter to keep track of timer IDs
    00173     mutable PAtomicInteger timerId;
    00174
    00175     // map used to store active timer information
    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     // set used to store timer expiry times, in order
    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     // The last system timer tick value that was used to process timers.
    00205     PTimeInterval m_lastSample;
    00206
    00207     // thread that handles the timer stuff
    00208     PThread * m_timerThread;
    00209 };
    00210
    00211
    00213 // PProcess
    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,     // Number of program arguments.
    00636       char ** argv, // Array of strings for program arguments.
    00637       char ** envp  // Array of string for the system environment
    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   // Member variables
    00706     bool m_library;                   // Indication PTLib is being used as a library for an external process.
    00707     int  terminationValue;            // Application return value
    00708
    00709     PString manufacturer;             // Application manufacturer name.
    00710     PString productName;              // Application executable base name from argv[0]
    00711
    00712     WORD       majorVersion;          // Major version number of the product
    00713     WORD       minorVersion;          // Minor version number of the product
    00714     CodeStatus status;                // Development status of the product
    00715     WORD       buildNumber;           // Build number of the product
    00716
    00717     PFilePath    executableFile;      // Application executable file from argv[0] (not open)
    00718     PStringArray configurationPaths;  // Explicit file or set of directories to find default PConfig
    00719     PArgList     arguments;           // The list of arguments
    00720     int          maxHandles;          // Maximum number of file handles process can open.
    00721
    00722     PTime programStartTime;           // time at which process was intantiated, i.e. started
    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 // Include platform dependent part of class
    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  *  one instance of this class (or any descendants) will be instantiated
    00774  *  via PGenericFactory<PProessStartup> one "main" has been started, and then
    00775  *  the OnStartup() function will be called. The OnShutdown function will
    00776  *  be called after main exits, and the instances will be destroyed if they
    00777  *  are not singletons
    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 // using an inline definition rather than a #define crashes gcc 2.95. Go figure
    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 // End Of File ///////////////////////////////////////////////////////////////