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