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 * $Log: pprocess.h,v $ 00030 * Revision 1.71 2005/11/30 12:47:38 csoutheren 00031 * Removed tabs, reformatted some code, and changed tags for Doxygen 00032 * 00033 * Revision 1.70 2005/11/25 03:43:47 csoutheren 00034 * Fixed function argument comments to be compatible with Doxygen 00035 * 00036 * Revision 1.69 2005/01/26 05:37:54 csoutheren 00037 * Added ability to remove config file support 00038 * 00039 * Revision 1.68 2004/06/30 12:17:04 rjongbloed 00040 * Rewrite of plug in system to use single global variable for all factories to avoid all sorts 00041 * of issues with startup orders and Windows DLL multiple instances. 00042 * 00043 * Revision 1.67 2004/05/27 04:46:42 csoutheren 00044 * Removed vestigal Macintosh code 00045 * 00046 * Revision 1.66 2004/05/21 00:28:39 csoutheren 00047 * Moved PProcessStartup creation to PProcess::Initialise 00048 * Added PreShutdown function and called it from ~PProcess to handle PProcessStartup removal 00049 * 00050 * Revision 1.65 2004/05/19 22:27:19 csoutheren 00051 * Added fix for gcc 2.95 00052 * 00053 * Revision 1.64 2004/05/18 21:49:25 csoutheren 00054 * Added ability to display trace output from program startup via environment 00055 * variable or by application creating a PProcessStartup descendant 00056 * 00057 * Revision 1.63 2004/05/18 06:01:06 csoutheren 00058 * Deferred plugin loading until after main has executed by using abstract factory classes 00059 * 00060 * Revision 1.62 2004/05/13 14:54:57 csoutheren 00061 * Implement PProcess startup and shutdown handling using abstract factory classes 00062 * 00063 * Revision 1.61 2003/11/25 08:28:13 rjongbloed 00064 * Removed ability to have platform without threads, win16 finally deprecated 00065 * 00066 * Revision 1.60 2003/09/17 05:41:59 csoutheren 00067 * Removed recursive includes 00068 * 00069 * Revision 1.59 2003/09/17 01:18:02 csoutheren 00070 * Removed recursive include file system and removed all references 00071 * to deprecated coooperative threading support 00072 * 00073 * Revision 1.58 2002/12/11 22:23:59 robertj 00074 * Added ability to set user identity temporarily and permanently. 00075 * Added get and set users group functions. 00076 * 00077 * Revision 1.57 2002/12/02 03:57:18 robertj 00078 * More RTEMS support patches, thank you Vladimir Nesic. 00079 * 00080 * Revision 1.56 2002/10/17 13:44:27 robertj 00081 * Port to RTEMS, thanks Vladimir Nesic. 00082 * 00083 * Revision 1.55 2002/10/17 07:17:42 robertj 00084 * Added ability to increase maximum file handles on a process. 00085 * 00086 * Revision 1.54 2002/10/10 04:43:43 robertj 00087 * VxWorks port, thanks Martijn Roest 00088 * 00089 * Revision 1.53 2002/09/16 01:08:59 robertj 00090 * Added #define so can select if #pragma interface/implementation is used on 00091 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan. 00092 * 00093 * Revision 1.52 2002/07/30 02:55:48 craigs 00094 * Added program start time to PProcess 00095 * Added virtual to GetVersion etc 00096 * 00097 * Revision 1.51 2002/02/14 05:13:33 robertj 00098 * Fixed possible deadlock if a timer is deleted (however indirectly) in the 00099 * OnTimeout of another timer. 00100 * 00101 * Revision 1.50 2001/11/23 06:59:29 robertj 00102 * Added PProcess::SetUserName() function for effective user changes. 00103 * 00104 * Revision 1.49 2001/08/11 07:57:30 rogerh 00105 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com> 00106 * 00107 * Revision 1.48 2001/05/22 12:49:32 robertj 00108 * Did some seriously wierd rewrite of platform headers to eliminate the 00109 * stupid GNU compiler warning about braces not matching. 00110 * 00111 * Revision 1.47 2001/03/09 05:50:48 robertj 00112 * Added ability to set default PConfig file or path to find it. 00113 * 00114 * Revision 1.46 2001/01/02 07:47:44 robertj 00115 * Fixed very narrow race condition in timers (destroyed while in OnTimeout()). 00116 * 00117 * Revision 1.45 2000/08/30 03:16:59 robertj 00118 * Improved multithreaded reliability of the timers under stress. 00119 * 00120 * Revision 1.44 2000/04/03 18:42:40 robertj 00121 * Added function to determine if PProcess instance is initialised. 00122 * 00123 * Revision 1.43 2000/02/29 12:26:14 robertj 00124 * Added named threads to tracing, thanks to Dave Harvey 00125 * 00126 * Revision 1.42 1999/03/09 02:59:50 robertj 00127 * Changed comments to doc++ compatible documentation. 00128 * 00129 * Revision 1.41 1999/02/16 08:11:09 robertj 00130 * MSVC 6.0 compatibility changes. 00131 * 00132 * Revision 1.40 1999/01/30 14:28:10 robertj 00133 * Added GetOSConfigDir() function. 00134 * 00135 * Revision 1.39 1999/01/11 11:27:11 robertj 00136 * Added function to get the hardware process is running on. 00137 * 00138 * Revision 1.38 1998/11/30 02:51:00 robertj 00139 * New directory structure 00140 * 00141 * Revision 1.37 1998/10/18 14:28:44 robertj 00142 * Renamed argv/argc to eliminate accidental usage. 00143 * 00144 * Revision 1.36 1998/10/13 14:06:13 robertj 00145 * Complete rewrite of memory leak detection code. 00146 * 00147 * Revision 1.35 1998/09/23 06:21:10 robertj 00148 * Added open source copyright license. 00149 * 00150 * Revision 1.34 1998/09/14 12:30:38 robertj 00151 * Fixed memory leak dump under windows to not include static globals. 00152 * 00153 * Revision 1.33 1998/04/07 13:33:53 robertj 00154 * Changed startup code to support PApplication class. 00155 * 00156 * Revision 1.32 1998/04/01 01:56:21 robertj 00157 * Fixed standard console mode app main() function generation. 00158 * 00159 * Revision 1.31 1998/03/29 06:16:44 robertj 00160 * Rearranged initialisation sequence so PProcess descendent constructors can do "things". 00161 * 00162 * Revision 1.30 1998/03/20 03:16:10 robertj 00163 * Added special classes for specific sepahores, PMutex and PSyncPoint. 00164 * 00165 * Revision 1.29 1997/07/08 13:13:46 robertj 00166 * DLL support. 00167 * 00168 * Revision 1.28 1997/04/27 05:50:13 robertj 00169 * DLL support. 00170 * 00171 * Revision 1.27 1997/02/05 11:51:56 robertj 00172 * Changed current process function to return reference and validate objects descendancy. 00173 * 00174 * Revision 1.26 1996/06/28 13:17:08 robertj 00175 * Fixed incorrect declaration of internal timer list. 00176 * 00177 * Revision 1.25 1996/06/13 13:30:49 robertj 00178 * Rewrite of auto-delete threads, fixes Windows95 total crash. 00179 * 00180 * Revision 1.24 1996/05/23 09:58:47 robertj 00181 * Changed process.h to pprocess.h to avoid name conflict. 00182 * Added mutex to timer list. 00183 * 00184 * Revision 1.23 1996/05/18 09:18:30 robertj 00185 * Added mutex to timer list. 00186 * 00187 * Revision 1.22 1996/04/29 12:18:48 robertj 00188 * Added function to return process ID. 00189 * 00190 * Revision 1.21 1996/03/12 11:30:21 robertj 00191 * Moved destructor to platform dependent code. 00192 * 00193 * Revision 1.20 1996/02/25 11:15:26 robertj 00194 * Added platform dependent Construct function to PProcess. 00195 * 00196 * Revision 1.19 1996/02/03 11:54:09 robertj 00197 * Added operating system identification functions. 00198 * 00199 * Revision 1.18 1996/01/02 11:57:17 robertj 00200 * Added thread for timers. 00201 * 00202 * Revision 1.17 1995/12/23 03:46:02 robertj 00203 * Changed version numbers. 00204 * 00205 * Revision 1.16 1995/12/10 11:33:36 robertj 00206 * Added extra user information to processes and applications. 00207 * Changes to main() startup mechanism to support Mac. 00208 * 00209 * Revision 1.15 1995/06/17 11:13:05 robertj 00210 * Documentation update. 00211 * 00212 * Revision 1.14 1995/06/17 00:43:10 robertj 00213 * Made PreInitialise virtual for NT service support 00214 * 00215 * Revision 1.13 1995/03/14 12:42:14 robertj 00216 * Updated documentation to use HTML codes. 00217 * 00218 * Revision 1.12 1995/03/12 04:43:26 robertj 00219 * Remvoed redundent destructor. 00220 * 00221 * Revision 1.11 1995/01/11 09:45:09 robertj 00222 * Documentation and normalisation. 00223 * 00224 * Revision 1.10 1994/08/23 11:32:52 robertj 00225 * Oops 00226 * 00227 * Revision 1.9 1994/08/22 00:46:48 robertj 00228 * Added pragma fro GNU C++ compiler. 00229 * 00230 * Revision 1.8 1994/08/21 23:43:02 robertj 00231 * Added function to get the user name of the owner of a process. 00232 * 00233 * Revision 1.7 1994/08/04 11:51:04 robertj 00234 * Moved OperatingSystemYield() to protected for Unix. 00235 * 00236 * Revision 1.6 1994/08/01 03:42:23 robertj 00237 * Destructor needed for heap debugging. 00238 * 00239 * Revision 1.5 1994/07/27 05:58:07 robertj 00240 * Synchronisation. 00241 * 00242 * Revision 1.4 1994/07/21 12:33:49 robertj 00243 * Moved cooperative threads to common. 00244 * 00245 * Revision 1.3 1994/06/25 11:55:15 robertj 00246 * Unix version synchronisation. 00247 * 00248 */ 00249 00250 #ifndef _PPROCESS 00251 #define _PPROCESS 00252 00253 #ifdef P_USE_PRAGMA 00254 #pragma interface 00255 #endif 00256 00257 #include <ptlib/mutex.h> 00258 #include <ptlib/syncpoint.h> 00259 #include <ptlib/pfactory.h> 00260 00261 00268 #ifdef P_VXWORKS 00269 #define PCREATE_PROCESS(cls) \ 00270 PProcess::PreInitialise(0, NULL, NULL); \ 00271 cls instance; \ 00272 instance._main(); 00273 #elif defined(P_RTEMS) 00274 #define PCREATE_PROCESS(cls) \ 00275 extern "C" {\ 00276 void* POSIX_Init( void* argument) \ 00277 { PProcess::PreInitialise(0, 0, 0); \ 00278 static cls instance; \ 00279 exit( instance._main() ); \ 00280 } \ 00281 } 00282 #else 00283 #define PCREATE_PROCESS(cls) \ 00284 int main(int argc, char ** argv, char ** envp) \ 00285 { PProcess::PreInitialise(argc, argv, envp); \ 00286 static cls instance; \ 00287 return instance._main(); \ 00288 } 00289 #endif // P_VXWORKS 00290 00291 /*$MACRO PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build) 00292 This macro is used to declare the components necessary for a user PWLib 00293 process. This will declare the PProcess descendent class, eg PApplication, 00294 and create an instance of the class. See the #PCREATE_PROCESS# macro 00295 for more details. 00296 */ 00297 #define PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build) \ 00298 class cls : public ancestor { \ 00299 PCLASSINFO(cls, ancestor); \ 00300 public: \ 00301 cls() : ancestor(manuf, name, major, minor, status, build) { } \ 00302 private: \ 00303 virtual void Main(); \ 00304 }; 00305 00306 00307 PLIST(PInternalTimerList, PTimer); 00308 00309 class PTimerList : PInternalTimerList // Want this to be private 00310 /* This class defines a list of #PTimer# objects. It is primarily used 00311 internally by the library and the user should never create an instance of 00312 it. The #PProcess# instance for the application maintains an instance 00313 of all of the timers created so that it may decrements them at regular 00314 intervals. 00315 */ 00316 { 00317 PCLASSINFO(PTimerList, PInternalTimerList); 00318 00319 public: 00320 PTimerList(); 00321 // Create a new timer list 00322 00323 PTimeInterval Process(); 00324 /* Decrement all the created timers and dispatch to their callback 00325 functions if they have expired. The #PTimer::Tick()# function 00326 value is used to determine the time elapsed since the last call to 00327 Process(). 00328 00329 The return value is the number of milliseconds until the next timer 00330 needs to be despatched. The function need not be called again for this 00331 amount of time, though it can (and usually is). 00332 00333 @return 00334 maximum time interval before function should be called again. 00335 */ 00336 00337 private: 00338 PMutex listMutex, processingMutex, inTimeoutMutex; 00339 // Mutual exclusion for multi tasking 00340 00341 PTimeInterval lastSample; 00342 // The last system timer tick value that was used to process timers. 00343 00344 PTimer * currentTimer; 00345 // The timer which is currently being handled 00346 00347 friend class PTimer; 00348 }; 00349 00350 00352 // PProcess 00353 00366 class PProcess : public PThread 00367 { 00368 PCLASSINFO(PProcess, PThread); 00369 00370 public: 00373 00374 enum CodeStatus { 00376 AlphaCode, 00378 BetaCode, 00380 ReleaseCode, 00381 NumCodeStatuses 00382 }; 00383 00386 PProcess( 00387 const char * manuf = "", 00388 const char * name = "", 00389 WORD majorVersion = 1, 00390 WORD minorVersion = 0, 00391 CodeStatus status = ReleaseCode, 00392 WORD buildNumber = 1 00393 ); 00395 00404 Comparison Compare( 00405 const PObject & obj 00406 ) const; 00408 00413 virtual void Terminate(); 00414 00420 virtual PString GetThreadName() const; 00421 00427 virtual void SetThreadName( 00428 const PString & name 00429 ); 00431 00440 static PProcess & Current(); 00441 00448 static BOOL IsInitialised(); 00449 00456 void SetTerminationValue( 00457 int value 00458 ); 00459 00469 int GetTerminationValue() const; 00470 00477 PArgList & GetArguments(); 00478 00488 virtual const PString & GetManufacturer() const; 00489 00499 virtual const PString & GetName() const; 00500 00515 virtual PString GetVersion( 00516 BOOL full = TRUE 00517 ) const; 00518 00524 const PFilePath & GetFile() const; 00525 00533 DWORD GetProcessID() const; 00534 00543 PString GetUserName() const; 00544 00567 BOOL SetUserName( 00568 const PString & username, 00569 BOOL permanent = FALSE 00570 ); 00571 00580 PString GetGroupName() const; 00581 00606 BOOL SetGroupName( 00607 const PString & groupname, 00608 BOOL permanent = FALSE 00609 ); 00610 00617 int GetMaxHandles() const; 00618 00628 BOOL SetMaxHandles( 00629 int newLimit 00630 ); 00631 00632 #ifdef P_CONFIG_FILE 00633 00635 virtual PString GetConfigurationFile(); 00636 #endif 00637 00651 void SetConfigurationPath( 00652 const PString & path 00653 ); 00655 00664 static PString GetOSClass(); 00665 00672 static PString GetOSName(); 00673 00679 static PString GetOSHardware(); 00680 00687 static PString GetOSVersion(); 00688 00696 static PDirectory GetOSConfigDir(); 00698 00699 PTimerList * GetTimerList(); 00700 /* Get the list of timers handled by the application. This is an internal 00701 function and should not need to be called by the user. 00702 00703 @return 00704 list of timers. 00705 */ 00706 00707 static void PreInitialise( 00708 int argc, // Number of program arguments. 00709 char ** argv, // Array of strings for program arguments. 00710 char ** envp // Array of string for the system environment 00711 ); 00712 /* Internal initialisation function called directly from 00713 #_main()#. The user should never call this function. 00714 */ 00715 00716 static void PreShutdown(); 00717 /* Internal shutdown function called directly from the ~PProcess 00718 #_main()#. The user should never call this function. 00719 */ 00720 00721 virtual int _main(void * arg = NULL); 00722 // Main function for process, called from real main after initialisation 00723 00724 PTime GetStartTime() const; 00725 /* return the time at which the program was started 00726 */ 00727 00728 private: 00729 void Construct(); 00730 00731 // Member variables 00732 static int p_argc; 00733 static char ** p_argv; 00734 static char ** p_envp; 00735 // main arguments 00736 00737 int terminationValue; 00738 // Application return value 00739 00740 PString manufacturer; 00741 // Application manufacturer name. 00742 00743 PString productName; 00744 // Application executable base name from argv[0] 00745 00746 WORD majorVersion; 00747 // Major version number of the product 00748 00749 WORD minorVersion; 00750 // Minor version number of the product 00751 00752 CodeStatus status; 00753 // Development status of the product 00754 00755 WORD buildNumber; 00756 // Build number of the product 00757 00758 PFilePath executableFile; 00759 // Application executable file from argv[0] (not open) 00760 00761 PStringList configurationPaths; 00762 // Explicit file or set of directories to find default PConfig 00763 00764 PArgList arguments; 00765 // The list of arguments 00766 00767 PTimerList timers; 00768 // List of active timers in system 00769 00770 PTime programStartTime; 00771 // time at which process was intantiated, i.e. started 00772 00773 int maxHandles; 00774 // Maximum number of file handles process can open. 00775 00776 00777 friend class PThread; 00778 00779 00780 // Include platform dependent part of class 00781 #ifdef _WIN32 00782 #include "msos/ptlib/pprocess.h" 00783 #else 00784 #include "unix/ptlib/pprocess.h" 00785 #endif 00786 }; 00787 00788 /* 00789 * one instance of this class (or any descendants) will be instantiated 00790 * via PGenericFactory<PProessStartup> one "main" has been started, and then 00791 * the OnStartup() function will be called. The OnShutdown function will 00792 * be called after main exits, and the instances will be destroyed if they 00793 * are not singletons 00794 */ 00795 class PProcessStartup : public PObject 00796 { 00797 PCLASSINFO(PProcessStartup, PObject) 00798 public: 00799 virtual void OnStartup() { } 00800 virtual void OnShutdown() { } 00801 }; 00802 00803 typedef PFactory<PProcessStartup> PProcessStartupFactory; 00804 00805 // using an inline definition rather than a #define crashes gcc 2.95. Go figure 00806 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine ) 00807 00808 template <unsigned _level, unsigned _options = P_DEFAULT_TRACE_OPTIONS > 00809 class PTraceLevelSetStartup : public PProcessStartup 00810 { 00811 public: 00812 void OnStartup() 00813 { PTrace::Initialise(_level, NULL, _options); } 00814 }; 00815 00816 #endif 00817 00818 // End Of File ///////////////////////////////////////////////////////////////