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: 24177 $
00030  * $Author: rjongbloed $
00031  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 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 
00592     static PDirectory GetOSConfigDir();
00593 
00600     static PString GetLibVersion();
00602 
00609     PTimerList * GetTimerList();
00610 
00614     void PreInitialise(
00615       int argc,     // Number of program arguments.
00616       char ** argv, // Array of strings for program arguments.
00617       char ** envp  // Array of string for the system environment
00618     );
00619 
00623     static void PreShutdown();
00624     static void PostShutdown();
00625 
00627     virtual int InternalMain(void * arg = NULL);
00628 
00650     class HostSystemURLHandlerInfo 
00651     {
00652       public:
00653         HostSystemURLHandlerInfo()
00654         { }
00655 
00656         HostSystemURLHandlerInfo(const PString & t)
00657           : type(t)
00658         { }
00659 
00660         static bool RegisterTypes(const PString & types, bool force = true);
00661 
00662         void SetIcon(const PString & icon);
00663         PString GetIcon() const;
00664 
00665         void SetCommand(const PString & key, const PString & command);
00666         PString GetCommand(const PString & key) const;
00667 
00668         bool GetFromSystem();
00669         bool CheckIfRegistered();
00670 
00671         bool Register();
00672 
00673         PString type;
00674 
00675     #if _WIN32
00676         PString iconFileName;
00677         PStringToString cmds;
00678     #endif
00679     };
00681 
00682   protected:
00683     void Construct();
00684 
00685   // Member variables
00686     int terminationValue;
00687     // Application return value
00688 
00689     PString manufacturer;
00690     // Application manufacturer name.
00691 
00692     PString productName;
00693     // Application executable base name from argv[0]
00694 
00695     WORD majorVersion;
00696     // Major version number of the product
00697     
00698     WORD minorVersion;
00699     // Minor version number of the product
00700     
00701     CodeStatus status;
00702     // Development status of the product
00703     
00704     WORD buildNumber;
00705     // Build number of the product
00706 
00707     PFilePath executableFile;
00708     // Application executable file from argv[0] (not open)
00709 
00710     PStringArray configurationPaths;
00711     // Explicit file or set of directories to find default PConfig
00712 
00713     PArgList arguments;
00714     // The list of arguments
00715 
00716     PTimerList timers;
00717     // List of active timers in system
00718 
00719     PTime programStartTime;
00720     // time at which process was intantiated, i.e. started
00721 
00722     int maxHandles;
00723     // Maximum number of file handles process can open.
00724 
00725     bool m_library;
00726 
00727     bool m_shuttingDown;
00728 
00729     typedef std::map<PThreadIdentifier, PThread *> ThreadMap;
00730     ThreadMap m_activeThreads;
00731     PMutex    m_activeThreadMutex;
00732     
00733   friend class PThread;
00734 
00735 
00736 // Include platform dependent part of class
00737 #ifdef _WIN32
00738 #include "msos/ptlib/pprocess.h"
00739 #else
00740 #include "unix/ptlib/pprocess.h"
00741 #endif
00742 };
00743 
00744 
00747  class PLibraryProcess : public PProcess
00748  {
00749   PCLASSINFO(PLibraryProcess, PProcess);
00750 
00751   public:
00756     PLibraryProcess(
00757       const char * manuf = "",         
00758       const char * name = "",          
00759       WORD majorVersionNum = 1,           
00760       WORD minorVersionNum = 0,           
00761       CodeStatus statusCode = ReleaseCode, 
00762       WORD buildNum = 1             
00763     ) : PProcess(manuf, name, majorVersionNum, minorVersionNum, statusCode, buildNum, true) { }
00765 
00767     virtual void Main() { }
00768 };
00769 
00770 
00771 /*
00772  *  one instance of this class (or any descendants) will be instantiated
00773  *  via PGenericFactory<PProessStartup> one "main" has been started, and then
00774  *  the OnStartup() function will be called. The OnShutdown function will
00775  *  be called after main exits, and the instances will be destroyed if they
00776  *  are not singletons
00777  */
00778 class PProcessStartup : public PObject
00779 {
00780   PCLASSINFO(PProcessStartup, PObject)
00781   public:
00782     virtual void OnStartup()  { }
00783     virtual void OnShutdown() { }
00784 };
00785 
00786 typedef PFactory<PProcessStartup> PProcessStartupFactory;
00787 
00788 #if PTRACING
00789 
00790 // using an inline definition rather than a #define crashes gcc 2.95. Go figure
00791 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
00792 
00793 template <unsigned level, unsigned options = P_DEFAULT_TRACE_OPTIONS >
00794 class PTraceLevelSetStartup : public PProcessStartup
00795 {
00796   public:
00797     void OnStartup()
00798     { PTrace::Initialise(level, NULL, options); }
00799 };
00800 
00801 #endif // PTRACING
00802 
00803 
00804 #endif // PTLIB_PROCESS_H
00805 
00806 
00807 // End Of File ///////////////////////////////////////////////////////////////

Generated on Thu May 27 01:49:40 2010 for PTLib by  doxygen 1.4.7