Made some subtle changes to the way the static variables are instantiated in
[pwlib.git] / include / ptlib / pprocess.h
blob398b3b6aef50676253b8495ca61d5ad722843c01
1 /*
2 * pprocess.h
4 * Operating System Process (running program executable) class.
6 * Portable Windows Library
8 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
20 * The Original Code is Portable Windows Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25 * All Rights Reserved.
27 * Contributor(s): ______________________________________.
29 * $Log$
30 * Revision 1.66 2004/05/21 00:28:39 csoutheren
31 * Moved PProcessStartup creation to PProcess::Initialise
32 * Added PreShutdown function and called it from ~PProcess to handle PProcessStartup removal
34 * Revision 1.65 2004/05/19 22:27:19 csoutheren
35 * Added fix for gcc 2.95
37 * Revision 1.64 2004/05/18 21:49:25 csoutheren
38 * Added ability to display trace output from program startup via environment
39 * variable or by application creating a PProcessStartup descendant
41 * Revision 1.63 2004/05/18 06:01:06 csoutheren
42 * Deferred plugin loading until after main has executed by using abstract factory classes
44 * Revision 1.62 2004/05/13 14:54:57 csoutheren
45 * Implement PProcess startup and shutdown handling using abstract factory classes
47 * Revision 1.61 2003/11/25 08:28:13 rjongbloed
48 * Removed ability to have platform without threads, win16 finally deprecated
50 * Revision 1.60 2003/09/17 05:41:59 csoutheren
51 * Removed recursive includes
53 * Revision 1.59 2003/09/17 01:18:02 csoutheren
54 * Removed recursive include file system and removed all references
55 * to deprecated coooperative threading support
57 * Revision 1.58 2002/12/11 22:23:59 robertj
58 * Added ability to set user identity temporarily and permanently.
59 * Added get and set users group functions.
61 * Revision 1.57 2002/12/02 03:57:18 robertj
62 * More RTEMS support patches, thank you Vladimir Nesic.
64 * Revision 1.56 2002/10/17 13:44:27 robertj
65 * Port to RTEMS, thanks Vladimir Nesic.
67 * Revision 1.55 2002/10/17 07:17:42 robertj
68 * Added ability to increase maximum file handles on a process.
70 * Revision 1.54 2002/10/10 04:43:43 robertj
71 * VxWorks port, thanks Martijn Roest
73 * Revision 1.53 2002/09/16 01:08:59 robertj
74 * Added #define so can select if #pragma interface/implementation is used on
75 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
77 * Revision 1.52 2002/07/30 02:55:48 craigs
78 * Added program start time to PProcess
79 * Added virtual to GetVersion etc
81 * Revision 1.51 2002/02/14 05:13:33 robertj
82 * Fixed possible deadlock if a timer is deleted (however indirectly) in the
83 * OnTimeout of another timer.
85 * Revision 1.50 2001/11/23 06:59:29 robertj
86 * Added PProcess::SetUserName() function for effective user changes.
88 * Revision 1.49 2001/08/11 07:57:30 rogerh
89 * Add Mac OS Carbon changes from John Woods <jfw@jfwhome.funhouse.com>
91 * Revision 1.48 2001/05/22 12:49:32 robertj
92 * Did some seriously wierd rewrite of platform headers to eliminate the
93 * stupid GNU compiler warning about braces not matching.
95 * Revision 1.47 2001/03/09 05:50:48 robertj
96 * Added ability to set default PConfig file or path to find it.
98 * Revision 1.46 2001/01/02 07:47:44 robertj
99 * Fixed very narrow race condition in timers (destroyed while in OnTimeout()).
101 * Revision 1.45 2000/08/30 03:16:59 robertj
102 * Improved multithreaded reliability of the timers under stress.
104 * Revision 1.44 2000/04/03 18:42:40 robertj
105 * Added function to determine if PProcess instance is initialised.
107 * Revision 1.43 2000/02/29 12:26:14 robertj
108 * Added named threads to tracing, thanks to Dave Harvey
110 * Revision 1.42 1999/03/09 02:59:50 robertj
111 * Changed comments to doc++ compatible documentation.
113 * Revision 1.41 1999/02/16 08:11:09 robertj
114 * MSVC 6.0 compatibility changes.
116 * Revision 1.40 1999/01/30 14:28:10 robertj
117 * Added GetOSConfigDir() function.
119 * Revision 1.39 1999/01/11 11:27:11 robertj
120 * Added function to get the hardware process is running on.
122 * Revision 1.38 1998/11/30 02:51:00 robertj
123 * New directory structure
125 * Revision 1.37 1998/10/18 14:28:44 robertj
126 * Renamed argv/argc to eliminate accidental usage.
128 * Revision 1.36 1998/10/13 14:06:13 robertj
129 * Complete rewrite of memory leak detection code.
131 * Revision 1.35 1998/09/23 06:21:10 robertj
132 * Added open source copyright license.
134 * Revision 1.34 1998/09/14 12:30:38 robertj
135 * Fixed memory leak dump under windows to not include static globals.
137 * Revision 1.33 1998/04/07 13:33:53 robertj
138 * Changed startup code to support PApplication class.
140 * Revision 1.32 1998/04/01 01:56:21 robertj
141 * Fixed standard console mode app main() function generation.
143 * Revision 1.31 1998/03/29 06:16:44 robertj
144 * Rearranged initialisation sequence so PProcess descendent constructors can do "things".
146 * Revision 1.30 1998/03/20 03:16:10 robertj
147 * Added special classes for specific sepahores, PMutex and PSyncPoint.
149 * Revision 1.29 1997/07/08 13:13:46 robertj
150 * DLL support.
152 * Revision 1.28 1997/04/27 05:50:13 robertj
153 * DLL support.
155 * Revision 1.27 1997/02/05 11:51:56 robertj
156 * Changed current process function to return reference and validate objects descendancy.
158 * Revision 1.26 1996/06/28 13:17:08 robertj
159 * Fixed incorrect declaration of internal timer list.
161 * Revision 1.25 1996/06/13 13:30:49 robertj
162 * Rewrite of auto-delete threads, fixes Windows95 total crash.
164 * Revision 1.24 1996/05/23 09:58:47 robertj
165 * Changed process.h to pprocess.h to avoid name conflict.
166 * Added mutex to timer list.
168 * Revision 1.23 1996/05/18 09:18:30 robertj
169 * Added mutex to timer list.
171 * Revision 1.22 1996/04/29 12:18:48 robertj
172 * Added function to return process ID.
174 * Revision 1.21 1996/03/12 11:30:21 robertj
175 * Moved destructor to platform dependent code.
177 * Revision 1.20 1996/02/25 11:15:26 robertj
178 * Added platform dependent Construct function to PProcess.
180 * Revision 1.19 1996/02/03 11:54:09 robertj
181 * Added operating system identification functions.
183 * Revision 1.18 1996/01/02 11:57:17 robertj
184 * Added thread for timers.
186 * Revision 1.17 1995/12/23 03:46:02 robertj
187 * Changed version numbers.
189 * Revision 1.16 1995/12/10 11:33:36 robertj
190 * Added extra user information to processes and applications.
191 * Changes to main() startup mechanism to support Mac.
193 * Revision 1.15 1995/06/17 11:13:05 robertj
194 * Documentation update.
196 * Revision 1.14 1995/06/17 00:43:10 robertj
197 * Made PreInitialise virtual for NT service support
199 * Revision 1.13 1995/03/14 12:42:14 robertj
200 * Updated documentation to use HTML codes.
202 * Revision 1.12 1995/03/12 04:43:26 robertj
203 * Remvoed redundent destructor.
205 * Revision 1.11 1995/01/11 09:45:09 robertj
206 * Documentation and normalisation.
208 * Revision 1.10 1994/08/23 11:32:52 robertj
209 * Oops
211 * Revision 1.9 1994/08/22 00:46:48 robertj
212 * Added pragma fro GNU C++ compiler.
214 * Revision 1.8 1994/08/21 23:43:02 robertj
215 * Added function to get the user name of the owner of a process.
217 * Revision 1.7 1994/08/04 11:51:04 robertj
218 * Moved OperatingSystemYield() to protected for Unix.
220 * Revision 1.6 1994/08/01 03:42:23 robertj
221 * Destructor needed for heap debugging.
223 * Revision 1.5 1994/07/27 05:58:07 robertj
224 * Synchronisation.
226 * Revision 1.4 1994/07/21 12:33:49 robertj
227 * Moved cooperative threads to common.
229 * Revision 1.3 1994/06/25 11:55:15 robertj
230 * Unix version synchronisation.
234 #ifndef _PPROCESS
235 #define _PPROCESS
237 #ifdef P_USE_PRAGMA
238 #pragma interface
239 #endif
241 #include <ptlib/mutex.h>
242 #include <ptlib/syncpoint.h>
243 #include <ptlib/pfactory.h>
246 /**Create a process.
247 This macro is used to create the components necessary for a user PWLib
248 process. For a PWLib program to work correctly on all platforms the
249 #main()# function must be defined in the same module as the
250 instance of the application.
252 #ifndef P_MAC_MPTHREADS
253 #ifdef P_VXWORKS
254 #define PCREATE_PROCESS(cls) \
255 PProcess::PreInitialise(0, NULL, NULL); \
256 cls instance; \
257 instance._main();
258 #elif defined(P_RTEMS)
259 #define PCREATE_PROCESS(cls) \
260 extern "C" {\
261 void* POSIX_Init( void* argument) \
262 { PProcess::PreInitialise(0, 0, 0); \
263 static cls instance; \
264 exit( instance._main() ); \
267 #else
268 #define PCREATE_PROCESS(cls) \
269 int main(int argc, char ** argv, char ** envp) \
270 { PProcess::PreInitialise(argc, argv, envp); \
271 static cls instance; \
272 return instance._main(); \
274 #endif // P_VXWORKS
275 #else // Mac MP Tasks implementation
276 // Alas, a Macintosh main thread has a number of important responsibilities.
277 // The goal of this code is to warm up the Toolbox and create an independant
278 // thread for the application object. I'm trying to wrap a generic Mac main
279 // function around an existing derived PProcess class; a real Mac application
280 // may want to duplicate this code in a more suitable form after rewriting the
281 // canonical Main() implementation.
282 // I have changed the process instance variable to be automatic rather than
283 // static duration so I can tear down the Mac MP framework.
284 // In practice, I think it is better to hand-craft the main function, but this
285 // allows the asn compiler to build and run.
286 // The declarations are available in <ptlib/MacMainIf.h>.
287 #define PCREATE_PROCESS(cls) \
288 extern "C" { \
289 extern int MacInitialisePWLibEvents(void); \
290 typedef long(*callback_api_c)(void*); \
291 extern int SpawnProcessInContext(callback_api_c); \
292 extern void RunApplicationEventLoop(void); \
293 static long PWTrampoline(void *ignored) \
295 cls instance; \
296 return instance._main(); \
298 }; \
299 int main(int argc, char ** argv, char ** envp) \
301 int err; \
302 MacInitialisePWLibEvents(); \
303 PProcess::PreInitialise(argc, argv, envp); \
304 err = SpawnProcessInContext(PWTrampoline); \
305 if (err == 0) RunApplicationEventLoop(); \
306 return err; \
308 #endif
310 /*$MACRO PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build)
311 This macro is used to declare the components necessary for a user PWLib
312 process. This will declare the PProcess descendent class, eg PApplication,
313 and create an instance of the class. See the #PCREATE_PROCESS# macro
314 for more details.
316 #define PDECLARE_PROCESS(cls,ancestor,manuf,name,major,minor,status,build) \
317 class cls : public ancestor { \
318 PCLASSINFO(cls, ancestor); \
319 public: \
320 cls() : ancestor(manuf, name, major, minor, status, build) { } \
321 private: \
322 virtual void Main(); \
326 PLIST(PInternalTimerList, PTimer);
328 class PTimerList : PInternalTimerList // Want this to be private
329 /* This class defines a list of #PTimer# objects. It is primarily used
330 internally by the library and the user should never create an instance of
331 it. The #PProcess# instance for the application maintains an instance
332 of all of the timers created so that it may decrements them at regular
333 intervals.
336 PCLASSINFO(PTimerList, PInternalTimerList);
338 public:
339 PTimerList();
340 // Create a new timer list
342 PTimeInterval Process();
343 /* Decrement all the created timers and dispatch to their callback
344 functions if they have expired. The #PTimer::Tick()# function
345 value is used to determine the time elapsed since the last call to
346 Process().
348 The return value is the number of milliseconds until the next timer
349 needs to be despatched. The function need not be called again for this
350 amount of time, though it can (and usually is).
352 @return
353 maximum time interval before function should be called again.
356 private:
357 PMutex listMutex, processingMutex, inTimeoutMutex;
358 // Mutual exclusion for multi tasking
360 PTimeInterval lastSample;
361 // The last system timer tick value that was used to process timers.
363 PTimer * currentTimer;
364 // The timer which is currently being handled
366 friend class PTimer;
370 ///////////////////////////////////////////////////////////////////////////////
371 // PProcess
373 /**This class represents an operating system process. This is a running
374 "programme" in the context of the operating system. Note that there can
375 only be one instance of a PProcess class in a given programme.
377 The instance of a PProcess or its GUI descendent #PApplication# is
378 usually a static variable created by the application writer. This is the
379 initial "anchor" point for all data structures in an application. As the
380 application writer never needs to access the standard system
381 #main()# function, it is in the library, the programmes
382 execution begins with the virtual function #PThread::Main()# on a
383 process.
385 class PProcess : public PThread
387 PCLASSINFO(PProcess, PThread);
389 public:
390 /**@name Construction */
391 //@{
392 /// Release status for the program.
393 enum CodeStatus {
394 /// Code is still very much under construction.
395 AlphaCode,
396 /// Code is largely complete and is under test.
397 BetaCode,
398 /// Code has all known bugs removed and is shipping.
399 ReleaseCode,
400 NumCodeStatuses
403 /** Create a new process instance.
405 PProcess(
406 const char * manuf = "", /// Name of manufacturer
407 const char * name = "", /// Name of product
408 WORD majorVersion = 1, /// Major version number of the product
409 WORD minorVersion = 0, /// Minor version number of the product
410 CodeStatus status = ReleaseCode, /// Development status of the product
411 WORD buildNumber = 1 /// Build number of the product
413 //@}
415 /**@name Overrides from class PObject */
416 //@{
417 /**Compare two process instances. This should almost never be called as
418 a programme only has access to a single process, its own.
420 @return
421 #EqualTo# if the two process object have the same name.
423 Comparison Compare(
424 const PObject & obj /// Other process to compare against.
425 ) const;
426 //@}
428 /**@name Overrides from class PThread */
429 //@{
430 /**Terminate the process. Usually only used in abnormal abort situation.
432 virtual void Terminate();
434 /** Get the name of the thread. Thread names are a optional debugging aid.
436 @return
437 current thread name.
439 virtual PString GetThreadName() const;
441 /** Change the name of the thread. Thread names are a optional debugging aid.
443 @return
444 current thread name.
446 virtual void SetThreadName(
447 const PString & name /// New name for the thread.
449 //@}
451 /**@name Process information functions */
452 //@{
453 /**Get the current processes object instance. The {\it current process}
454 is the one the application is running in.
456 @return
457 pointer to current process instance.
459 static PProcess & Current();
461 /**Determine if the current processes object instance has been initialised.
462 If this returns TRUE it is safe to use the PProcess::Current() function.
464 @return
465 TRUE if process class has been initialised.
467 static BOOL IsInitialised();
469 /**Set the termination value for the process.
471 The termination value is an operating system dependent integer which
472 indicates the processes termiantion value. It can be considered a
473 "return value" for an entire programme.
475 void SetTerminationValue(
476 int value /// Value to return a process termination status.
479 /**Get the termination value for the process.
481 The termination value is an operating system dependent integer which
482 indicates the processes termiantion value. It can be considered a
483 "return value" for an entire programme.
485 @return
486 integer termination value.
488 int GetTerminationValue() const;
490 /**Get the programme arguments. Programme arguments are a set of strings
491 provided to the programme in a platform dependent manner.
493 @return
494 argument handling class instance.
496 PArgList & GetArguments();
498 /**Get the name of the manufacturer of the software. This is used in the
499 default "About" dialog box and for determining the location of the
500 configuration information as used by the #PConfig# class.
502 The default for this information is the empty string.
504 @return
505 string for the manufacturer name eg "Equivalence".
507 virtual const PString & GetManufacturer() const;
509 /**Get the name of the process. This is used in the
510 default "About" dialog box and for determining the location of the
511 configuration information as used by the #PConfig# class.
513 The default is the title part of the executable image file.
515 @return
516 string for the process name eg "MyApp".
518 virtual const PString & GetName() const;
520 /**Get the version of the software. This is used in the default "About"
521 dialog box and for determining the location of the configuration
522 information as used by the #PConfig# class.
524 If the #full# parameter is TRUE then a version string
525 built from the major, minor, status and build veriosn codes is
526 returned. If FALSE then only the major and minor versions are
527 returned.
529 The default for this information is "1.0".
531 @return
532 string for the version eg "1.0b3".
534 virtual PString GetVersion(
535 BOOL full = TRUE /// TRUE for full version, FALSE for short version.
536 ) const;
538 /**Get the processes executable image file path.
540 @return
541 file path for program.
543 const PFilePath & GetFile() const;
545 /**Get the platform dependent process identifier for the process. This is
546 an arbitrary (and unique) integer attached to a process by the operating
547 system.
549 @return
550 Process ID for process.
552 DWORD GetProcessID() const;
554 /**Get the effective user name of the owner of the process, eg "root" etc.
555 This is a platform dependent string only provided by platforms that are
556 multi-user. Note that some value may be returned as a "simulated" user.
557 For example, in MS-DOS an environment variable
559 @return
560 user name of processes owner.
562 PString GetUserName() const;
564 /**Set the effective owner of the process.
565 This is a platform dependent string only provided by platforms that are
566 multi-user.
568 For unix systems if the username may consist exclusively of digits and
569 there is no actual username consisting of that string then the numeric
570 uid value is used. For example "0" is the superuser. For the rare
571 occassions where the users name is the same as their uid, if the
572 username field starts with a '#' then the numeric form is forced.
574 If an empty string is provided then original user that executed the
575 process in the first place (the real user) is set as the effective user.
577 The permanent flag indicates that the user will not be able to simple
578 change back to the original user as indicated above, ie for unix
579 systems setuid() is used instead of seteuid(). This is not necessarily
580 meaningful for all platforms.
582 @return
583 TRUE if processes owner changed. The most common reason for failure is
584 that the process does not have the privilege to change the effective user.
586 BOOL SetUserName(
587 const PString & username, /// New user name or uid
588 BOOL permanent = FALSE /// Flag for if effective or real user
591 /**Get the effective group name of the owner of the process, eg "root" etc.
592 This is a platform dependent string only provided by platforms that are
593 multi-user. Note that some value may be returned as a "simulated" user.
594 For example, in MS-DOS an environment variable
596 @return
597 group name of processes owner.
599 PString GetGroupName() const;
601 /**Set the effective group of the process.
602 This is a platform dependent string only provided by platforms that are
603 multi-user.
605 For unix systems if the groupname may consist exclusively of digits and
606 there is no actual groupname consisting of that string then the numeric
607 uid value is used. For example "0" is the superuser. For the rare
608 occassions where the groups name is the same as their uid, if the
609 groupname field starts with a '#' then the numeric form is forced.
611 If an empty string is provided then original group that executed the
612 process in the first place (the real group) is set as the effective
613 group.
615 The permanent flag indicates that the group will not be able to simply
616 change back to the original group as indicated above, ie for unix
617 systems setgid() is used instead of setegid(). This is not necessarily
618 meaningful for all platforms.
620 @return
621 TRUE if processes group changed. The most common reason for failure is
622 that the process does not have the privilege to change the effective
623 group.
625 BOOL SetGroupName(
626 const PString & groupname, /// New group name or gid
627 BOOL permanent = FALSE /// Flag for if effective or real group
630 /**Get the maximum file handle value for the process.
631 For some platforms this is meaningless.
633 @return
634 user name of processes owner.
636 int GetMaxHandles() const;
638 /**Set the maximum number of file handles for the process.
639 For unix systems the user must be run with the approriate privileges
640 before this function can set the value above the system limit.
642 For some platforms this is meaningless.
644 @return
645 TRUE if successfully set the maximum file hadles.
647 BOOL SetMaxHandles(
648 int newLimit /// New limit on file handles
651 /**Get the default file to use in PConfig instances.
653 virtual PString GetConfigurationFile();
655 /**Set the default file or set of directories to search for use in PConfig.
656 To find the .ini file for use in the default PConfig() instance, this
657 explicit filename is used, or if it is a set of directories separated
658 by either ':' or ';' characters, then the application base name postfixed
659 with ".ini" is searched for through those directories.
661 The search is actually done when the GetConfigurationFile() is called,
662 this function only sets the internal variable.
664 Note for Windows, a path beginning with "HKEY_LOCAL_MACHINE\\" or
665 "HKEY_CURRENT_USER\\" will actually search teh system registry for the
666 application base name only (no ".ini") in that folder of the registry.
668 void SetConfigurationPath(
669 const PString & path /// Explicit file or set of directories
671 //@}
673 /**@name Operating System information functions */
674 //@{
675 /**Get the class of the operating system the process is running on, eg
676 "unix".
678 @return
679 String for OS class.
681 static PString GetOSClass();
683 /**Get the name of the operating system the process is running on, eg
684 "Linux".
686 @return
687 String for OS name.
689 static PString GetOSName();
691 /**Get the hardware the process is running on, eg "sparc".
693 @return
694 String for OS name.
696 static PString GetOSHardware();
698 /**Get the version of the operating system the process is running on, eg
699 "2.0.33".
701 @return
702 String for OS version.
704 static PString GetOSVersion();
706 /**Get the configuration directory of the operating system the process is
707 running on, eg "/etc" for Unix, "c:\windows" for Win95 or
708 "c:\winnt\system32\drivers\etc" for NT.
710 @return
711 Directory for OS configuration files.
713 static PDirectory GetOSConfigDir();
714 //@}
716 PTimerList * GetTimerList();
717 /* Get the list of timers handled by the application. This is an internal
718 function and should not need to be called by the user.
720 @return
721 list of timers.
724 static void PreInitialise(
725 int argc, // Number of program arguments.
726 char ** argv, // Array of strings for program arguments.
727 char ** envp // Array of string for the system environment
729 /* Internal initialisation function called directly from
730 #_main()#. The user should never call this function.
733 static void PreShutdown();
734 /* Internal shutdown function called directly from the ~PProcess
735 #_main()#. The user should never call this function.
738 virtual int _main(void * arg = NULL);
739 // Main function for process, called from real main after initialisation
741 PTime GetStartTime() const;
742 /* return the time at which the program was started
745 private:
746 void Construct();
748 // Member variables
749 static int p_argc;
750 static char ** p_argv;
751 static char ** p_envp;
752 // main arguments
754 int terminationValue;
755 // Application return value
757 PString manufacturer;
758 // Application manufacturer name.
760 PString productName;
761 // Application executable base name from argv[0]
763 WORD majorVersion;
764 // Major version number of the product
766 WORD minorVersion;
767 // Minor version number of the product
769 CodeStatus status;
770 // Development status of the product
772 WORD buildNumber;
773 // Build number of the product
775 PFilePath executableFile;
776 // Application executable file from argv[0] (not open)
778 PStringList configurationPaths;
779 // Explicit file or set of directories to find default PConfig
781 PArgList arguments;
782 // The list of arguments
784 PTimerList timers;
785 // List of active timers in system
787 PTime programStartTime;
788 // time at which process was intantiated, i.e. started
790 int maxHandles;
791 // Maximum number of file handles process can open.
794 friend class PThread;
797 // Include platform dependent part of class
798 #ifdef _WIN32
799 #include "msos/ptlib/pprocess.h"
800 #else
801 #include "unix/ptlib/pprocess.h"
802 #endif
806 * one instance of this class (or any descendants) will be instantiated
807 * via PGenericFactory<PProessStartup> one "main" has been started, and then
808 * the OnStartup() function will be called. The OnShutdown function will
809 * be called after main exits, and the instances will be destroyed if they
810 * are not singletons
812 class PProcessStartup : public PObject
814 PCLASSINFO(PProcessStartup, PObject)
815 public:
816 virtual void OnStartup() { }
817 virtual void OnShutdown() { }
820 typedef PGenericFactory<PProcessStartup> PProcessStartupFactory;
822 // using an inline definition rather than a #define crashes gcc 2.95. Go figure
823 #define P_DEFAULT_TRACE_OPTIONS ( PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine )
825 template <unsigned _level, unsigned _options = P_DEFAULT_TRACE_OPTIONS >
826 class PTraceLevelSetStartup : public PProcessStartup
828 public:
829 void OnStartup()
830 { PTrace::Initialise(_level, NULL, _options); }
833 #endif
835 // End Of File ///////////////////////////////////////////////////////////////