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 ///////////////////////////////////////////////////////////////

Generated on Fri Feb 15 20:58:31 2013 for PTLib by  doxygen 1.4.7