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: 24524 $
00030  * $Author: rjongbloed $
00031  * $Date: 2010-06-21 20:05:24 -0500 (Mon, 21 Jun 2010) $
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 /*$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     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,     // Number of program arguments.
00627       char ** argv, // Array of strings for program arguments.
00628       char ** envp  // Array of string for the system environment
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   // Member variables
00697     int terminationValue;
00698     // Application return value
00699 
00700     PString manufacturer;
00701     // Application manufacturer name.
00702 
00703     PString productName;
00704     // Application executable base name from argv[0]
00705 
00706     WORD majorVersion;
00707     // Major version number of the product
00708     
00709     WORD minorVersion;
00710     // Minor version number of the product
00711     
00712     CodeStatus status;
00713     // Development status of the product
00714     
00715     WORD buildNumber;
00716     // Build number of the product
00717 
00718     PFilePath executableFile;
00719     // Application executable file from argv[0] (not open)
00720 
00721     PStringArray configurationPaths;
00722     // Explicit file or set of directories to find default PConfig
00723 
00724     PArgList arguments;
00725     // The list of arguments
00726 
00727     PTimerList timers;
00728     // List of active timers in system
00729 
00730     PTime programStartTime;
00731     // time at which process was intantiated, i.e. started
00732 
00733     int maxHandles;
00734     // Maximum number of file handles process can open.
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 // Include platform dependent part of class
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  *  one instance of this class (or any descendants) will be instantiated
00784  *  via PGenericFactory<PProessStartup> one "main" has been started, and then
00785  *  the OnStartup() function will be called. The OnShutdown function will
00786  *  be called after main exits, and the instances will be destroyed if they
00787  *  are not singletons
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 // using an inline definition rather than a #define crashes gcc 2.95. Go figure
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 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7