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