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