00001 // -*- C++ -*- 00002 00003 //==================================================================== 00004 /** 00005 * @file Service_Config.h 00006 * 00007 * $Id: Service_Config.h 79332 2007-08-13 20:30:44Z sowayaa $ 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //==================================================================== 00012 00013 #ifndef ACE_SERVICE_CONFIG_H 00014 #define ACE_SERVICE_CONFIG_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include /**/ "ace/config-all.h" 00019 #include "ace/Default_Constants.h" 00020 #include "ace/Service_Gestalt.h" 00021 #include "ace/TSS_T.h" 00022 00023 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00024 # pragma once 00025 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00026 00027 #include "ace/OS_NS_signal.h" 00028 00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00030 00031 // Forward decl. 00032 class ACE_Service_Object; 00033 class ACE_Service_Type; 00034 class ACE_Service_Type_Impl; 00035 class ACE_Service_Repository; 00036 class ACE_Sig_Adapter; 00037 class ACE_Allocator; 00038 class ACE_Reactor; 00039 class ACE_Thread_Manager; 00040 class ACE_DLL; 00041 00042 #if (ACE_USES_CLASSIC_SVC_CONF == 1) 00043 #define ACE_STATIC_SERVICE_DIRECTIVE(ident, parameters) \ 00044 ACE_TEXT ("static ") \ 00045 ACE_TEXT (ident) \ 00046 ACE_TEXT (" \"") \ 00047 ACE_TEXT (parameters) \ 00048 ACE_TEXT ("\"") 00049 #define ACE_DYNAMIC_SERVICE_DIRECTIVE(ident, libpathname, objectclass, parameters) \ 00050 ACE_TEXT ("dynamic ") \ 00051 ACE_TEXT (ident) \ 00052 ACE_TEXT (" Service_Object * ") \ 00053 ACE_TEXT (libpathname) \ 00054 ACE_TEXT (":") \ 00055 ACE_TEXT (objectclass) \ 00056 ACE_TEXT ("() \"") \ 00057 ACE_TEXT (parameters) \ 00058 ACE_TEXT ("\"") 00059 #define ACE_REMOVE_SERVICE_DIRECTIVE(ident) \ 00060 ACE_TEXT ("remove ") \ 00061 ACE_TEXT (ident) 00062 class ACE_Svc_Conf_Param; 00063 #else 00064 #define ACE_STATIC_SERVICE_DIRECTIVE(ident, parameters) \ 00065 ACE_TEXT ("<ACE_Svc_Conf><static id=\"") \ 00066 ACE_TEXT (ident) \ 00067 ACE_TEXT ("\" params=\"") \ 00068 ACE_TEXT (parameters) \ 00069 ACE_TEXT ("\"/></ACE_Svc_Conf>") 00070 #define ACE_DYNAMIC_SERVICE_DIRECTIVE(ident, libpathname, objectclass, parameters) \ 00071 ACE_TEXT ("<ACE_Svc_Conf><dynamic id=\"") \ 00072 ACE_TEXT (ident) \ 00073 ACE_TEXT ("\" type=\"Service_Object\">") \ 00074 ACE_TEXT ("<initializer path=\"") \ 00075 ACE_TEXT (libpathname) \ 00076 ACE_TEXT ("\" init=\"") \ 00077 ACE_TEXT (objectclass) \ 00078 ACE_TEXT ("\"") \ 00079 ACE_TEXT (" params=\"") \ 00080 ACE_TEXT (parameters) \ 00081 ACE_TEXT ("\"/></dynamic></ACE_Svc_Conf>") 00082 #define ACE_REMOVE_SERVICE_DIRECTIVE(ident) \ 00083 ACE_TEXT ("<ACE_Svc_Conf><remove id=\"") \ 00084 ACE_TEXT (ident) \ 00085 ACE_TEXT ("\"></remove></ACE_Svc_Conf>") 00086 class ACE_XML_Svc_Conf; 00087 #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ 00088 00089 ACE_END_VERSIONED_NAMESPACE_DECL 00090 00091 extern "C" 00092 { 00093 typedef ACE_Service_Object *(*ACE_SERVICE_ALLOCATOR) (ACE_Service_Object_Exterminator *); 00094 } 00095 00096 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00097 00098 /** 00099 * @class ACE_Static_Svc_Descriptor 00100 * 00101 * @brief Holds the information necessary to describe a statically linked 00102 * Svc. 00103 */ 00104 class ACE_Static_Svc_Descriptor 00105 { 00106 public: 00107 /// Name of the service. 00108 const ACE_TCHAR *name_; 00109 00110 /// Type of service. 00111 int type_; 00112 00113 /// Factory function that allocates the service. 00114 ACE_SERVICE_ALLOCATOR alloc_; 00115 00116 /// Bitmask flags indicating how the framework should delete memory. 00117 u_int flags_; 00118 00119 /// Flag indicating whether the service starts out active. 00120 int active_; 00121 00122 /// Dump the state of an object. 00123 void dump (void) const; 00124 00125 /// Declare the dynamic allocation hooks. 00126 ACE_ALLOC_HOOK_DECLARE; 00127 00128 public: 00129 /// Compare two service descriptors for equality. 00130 bool operator== (ACE_Static_Svc_Descriptor &) const; 00131 00132 /// Compare two service descriptors for inequality. 00133 bool operator!= (ACE_Static_Svc_Descriptor &) const; 00134 }; 00135 00136 #define ACE_Component_Config ACE_Service_Config 00137 00138 /// This specialization enures ACE_TSS will _not_ perform a delete on 00139 /// (ACE_Service_Gestalt*) p upon thread exit, when TSS is cleaned 00140 /// up. Note that the tss_ member will be destroyed with the 00141 /// ACE_Object_Manager's ACE_Service_Config singleton, so no leaks 00142 /// will be introduced. 00143 /// We need this non-ownership ACE_TSS because the SC instance is 00144 /// really owned by the Object Manager and only it must do the cleanup. 00145 /// 00146 /// Naturally, things would be simpler, if we could 00147 /// avoid using the TSS altogether but we need the ability to 00148 /// temporarily designate a different SC instance as the "default." 00149 /// So, the solution is a hybrid, or non-owner ACE_TSS. See bugzila 00150 /// 2980 for a description of a test case where ACE_TSS::cleanup() is 00151 /// called before ~ACE_Object_Manager. 00152 00153 # if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00154 // Since ACE_TSS<>::cleanup() is only defined in 00155 // multithreaded builds ... 00156 template<> inline void 00157 ACE_TSS<ACE_Service_Gestalt>::cleanup (void*ptr) 00158 { 00159 // Borland C++ 2007 *needs* the parameter 00160 // name, but it is not clear why ... 00161 ACE_UNUSED_ARG (ptr); 00162 } 00163 # else 00164 template<> inline 00165 ACE_TSS<ACE_Service_Gestalt>::~ACE_TSS (void) 00166 { 00167 // Without threads, the ACE_TSS cleanup is done by ~ACE_TSS() 00168 } 00169 # endif /* ACE_MT_SAFE */ 00170 00171 00172 /** 00173 * @class ACE_Service_Config 00174 * 00175 * @brief Supplies common server operations for dynamic and static 00176 * configuration of service. 00177 * 00178 * The ACE_Service_Config uses the Monostate pattern. Therefore, 00179 * you can only have one of these instantiated per-process. It 00180 * represents the process-wide collection of services, which is 00181 * typicaly shared among all other configurable entities. The only 00182 * ACE_Service_Config instance is registered with and owned by the 00183 * ACE_Object_Manager. 00184 * 00185 * By contrast, the ACE_Service_Gestalt represents the collection 00186 * of services, pertaining to a configurable entity. Typicaly, a 00187 * "configurable entity" is an instance, which owns an instance of 00188 * ACE_Service_Gestalt in order to ensure full controll over the 00189 * services it needs. 00190 * 00191 * Another facet of ACE_Service_Config is that for a given thread, 00192 * it provides access to its current, process-global 00193 * ACE_Service_Gestalt instance through its curent() method. 00194 * 00195 * @note The signal_handler_ static member is allocated by the 00196 * ACE_Object_Manager. The ACE_Service_Config constructor 00197 * uses signal_handler_. Therefore, if the program has any 00198 * static ACE_Service_Config objects, there might be 00199 * initialization order problems. They can be minimized, but 00200 * not eliminated, by _not_ #defining 00201 * ACE_HAS_NONSTATIC_OBJECT_MANAGER. 00202 */ 00203 class ACE_Export ACE_Service_Config: public ACE_Service_Gestalt 00204 { 00205 00206 public: 00207 00208 // = Initialization and termination methods. 00209 00210 /** 00211 * Initialize the Service Repository. Note that initialising @a 00212 * signum to a negative number will prevent a signal handler being 00213 * registered when the repository is opened. 00214 */ 00215 ACE_Service_Config (int ignore_static_svcs = 1, 00216 size_t size = ACE_Service_Gestalt::MAX_SERVICES, 00217 int signum = SIGHUP); 00218 00219 /** 00220 * Performs an open without parsing command-line arguments. The 00221 * @a logger_key indicates where to write the logging output, which 00222 * is typically either a STREAM pipe or a socket address. 00223 */ 00224 ACE_Service_Config (const ACE_TCHAR program_name[], 00225 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY); 00226 00227 /// Perform user-specified close activities and remove dynamic 00228 /// memory. 00229 virtual ~ACE_Service_Config (void); 00230 00231 protected: 00232 00233 /** 00234 * Performs an open without parsing command-line arguments. 00235 * Implements whats different in the opening sequence 00236 * for this class, as opposed to the base class. 00237 * 00238 * The @a logger_key indicates where to write the logging output, which 00239 * is typically either a STREAM pipe or a socket address. If 00240 * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file 00241 * will be ignored. If @a ignore_debug_flag is non-0 then the 00242 * application is responsible for setting the 00243 * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of 00244 * errors that occurred on failure and 0 otherwise. 00245 */ 00246 virtual int open_i (const ACE_TCHAR program_name[], 00247 const ACE_TCHAR *logger_key, 00248 bool ignore_static_svcs, 00249 bool ignore_default_svc_conf_file, 00250 bool ignore_debug_flag); 00251 00252 /** 00253 * Implements whats different in the command line parameter processing 00254 * for this class, as opposed to the base class. 00255 */ 00256 virtual int parse_args_i (int argc, ACE_TCHAR *argv[]); 00257 00258 /** 00259 * A Wrapper for the TSS-stored pointer to the "current" 00260 * configuration Gestalt. Static initializers from any DLL loaded 00261 * through the SC will find the SC instance through the TSS pointer, 00262 * instead of the global singleton. This makes it possible to ensure 00263 * that the new services are loaded in the correct Gestalt, 00264 * independent of which thread is actually using the SC at the time 00265 * to do so. 00266 */ 00267 ACE_TSS <ACE_Service_Gestalt> tss_; 00268 00269 /// = Static interfaces 00270 00271 public: 00272 /** 00273 * Mutator to set the (TSS) global instance. Intended for use by 00274 * helper classes like @see ACE_Service_Config_Guard. Stack-based 00275 * instances of it can temporarily change which Gestalt is 00276 * considered global by any static initializer (especially those in 00277 * DLLs, loaded at run-time). 00278 */ 00279 static ACE_Service_Gestalt* current (ACE_Service_Gestalt*); 00280 00281 /** 00282 * Returns a process-wide global singleton instance in contrast with 00283 * current (), which may return a different instance at different 00284 * times, dependent on the context. Use of this method is 00285 * discouraged as it allows circumvention of the mechanism for 00286 * dynamically loading services. Use with extreme caution! 00287 */ 00288 static ACE_Service_Config* global (void); 00289 00290 /// Accessor for the "current" service gestalt 00291 static ACE_Service_Gestalt* current (void); 00292 00293 /** 00294 * This is what the static service initializators are hard-wired to 00295 * use, so in order to avoid interface changes this method merely 00296 * forwards to @c ACE_Service_Config::current. This enables us to 00297 * enforce which Service Gestalt is used for services registering 00298 * through static initializers. Especially important for DLL-based 00299 * dynamic services, which can contain their own static services and 00300 * static initializers. 00301 */ 00302 static ACE_Service_Gestalt* instance (void); 00303 00304 /** 00305 * Performs an open without parsing command-line arguments. The 00306 * @a logger_key indicates where to write the logging output, which 00307 * is typically either a STREAM pipe or a socket address. If 00308 * @a ignore_static_svcs is 1 then static services are not loaded, 00309 * otherwise, they are loaded. If @a ignore_default_svc_conf_file is 00310 * non-0 then the <svc.conf> configuration file will be ignored. 00311 * Returns zero upon success, -1 if the file is not found or cannot 00312 * be opened (errno is set accordingly), otherwise returns the 00313 * number of errors encountered loading the services in the 00314 * specified svc.conf configuration file. If @a ignore_debug_flag is 00315 * non-0 then the application is responsible for setting the 00316 * @c ACE_Log_Msg::priority_mask appropriately. 00317 */ 00318 static int open (const ACE_TCHAR program_name[], 00319 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, 00320 bool ignore_static_svcs = true, 00321 bool ignore_default_svc_conf_file = false, 00322 bool ignore_debug_flag = false); 00323 00324 /** 00325 * This is the primary entry point into the ACE_Service_Config (the 00326 * constructor just handles simple initializations). It parses 00327 * arguments passed in from @a argc and @a argv parameters. The 00328 * arguments that are valid in a call to this method include: 00329 * 00330 * - '-b' Option to indicate that we should be a daemon. Note that when 00331 * this option is used, the process will be daemonized before the 00332 * service configuration file(s) are read. During daemonization, 00333 * (on POSIX systems) the current directory will be changed to "/" 00334 * so the caller should either fully specify the file names, or 00335 * execute a @c chroot() to the appropriate directory. 00336 * @sa ACE::daemonize(). 00337 * - '-d' Turn on debugging mode 00338 * - '-f' Specifies a configuration file name other than the default 00339 * svc.conf. Can be specified multiple times to use multiple files. 00340 * - '-k' Specifies the rendezvous point to use for the ACE distributed 00341 * logger. 00342 * - '-y' Explicitly enables the use of static services. This flag 00343 * overrides the @a ignore_static_svcs parameter value. 00344 * - '-n' Explicitly disables the use of static services. This flag 00345 * overrides the @a ignore_static_svcs parameter value. 00346 * - '-p' Specifies a pathname which is used to store the process id. 00347 * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing 00348 * of the configuration file(s). Ignored for platforms that do not 00349 * have POSIX signals, such as Windows. 00350 * - '-S' Specifies a service directive string. Enclose the string in quotes 00351 * and escape any embedded quotes with a backslash. This option 00352 * specifies service directives without the need for a configuration 00353 * file. 00354 * 00355 * @param argc The number of commandline arguments. 00356 * @param argv The array with commandline arguments 00357 * @param logger_key Indicates where to write the logging output, 00358 * which is typically either a STREAM pipe or a 00359 * socket address. 00360 * @param ignore_static_svcs If 1 then static services are not loaded, 00361 * otherwise, they are loaded. 00362 * @param ignore_default_svc_conf_file If non-0 then the @c svc.conf 00363 * configuration file will be ignored. 00364 * @param ignore_debug_flag If non-0 then the application is responsible 00365 * for setting the @c ACE_Log_Msg::priority_mask 00366 * appropriately. 00367 * 00368 * @retval -1 The configuration file is not found or cannot 00369 * be opened (errno is set accordingly). 00370 * @retval 0 Success. 00371 * @retval >0 The number of errors encountered while processing 00372 * the service configuration file(s). 00373 */ 00374 static int open (int argc, 00375 ACE_TCHAR *argv[], 00376 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, 00377 bool ignore_static_svcs = true, 00378 bool ignore_default_svc_conf_file = false, 00379 bool ignore_debug_flag = false); 00380 00381 /// Tidy up and perform last rites when ACE_Service_Config is shut 00382 /// down. This method calls <close_svcs>. Returns 0. 00383 static int close (void); 00384 00385 /// Perform user-specified close hooks and possibly delete all of the 00386 /// configured services in the <Service_Repository>. 00387 static int fini_svcs (void); 00388 00389 /** 00390 * Perform user-specified close hooks on all of the configured 00391 * services in the Service_Repository, then delete the 00392 * Service_Repository itself. Returns 0. 00393 */ 00394 static int close_svcs (void); 00395 00396 /// True if reconfiguration occurred. 00397 static int reconfig_occurred (void); 00398 00399 /// Indicate that reconfiguration occurred. 00400 static void reconfig_occurred (int); 00401 00402 /// Perform the reconfiguration process. 00403 static void reconfigure (void); 00404 00405 // = The following methods are static in order to enforce Singleton 00406 // semantics for the Reactor, Service_Repository, Thread_Manager, 00407 // and Acceptor/Connector Strategy factory. Other portions of the 00408 // system may need to access them at some point or another... 00409 00410 // = This is not strictly needed, anymore since the service configurator 00411 // has been refactored to allow multiple service configuration 00412 // instances (called gestalts). The interfaces, however were retained in for 00413 // the sake of maintaining source-code compatibility. 00414 00415 00416 // = Accessors and mutators for process-wide Singletons. 00417 00418 /// Returns a pointer to the list of statically linked services. 00419 /// 00420 /// @deprecated - Same as instance(), but still useful in legacy code, 00421 /// (notably, one that can not be easily modified) which uses the following 00422 /// idiom for registering static services: 00423 /// 00424 /// ACE_Service_Config::static_svcs ()->insert (...); 00425 static ACE_Service_Gestalt *static_svcs (void); 00426 00427 /// Insert a static service descriptor for processing on open_i(). The 00428 /// corresponding ACE_STATIC_SVC_* macros were chaged to use this method 00429 /// instead of obtaining a ptr to a container. See the note on static_svcs(). 00430 /// Added to prevent exposing the internal storage representation of the 00431 /// services repository and provide a better way of debugging service 00432 /// loading and registration problems. 00433 static int insert (ACE_Static_Svc_Descriptor *svc); 00434 00435 // = Utility methods. 00436 /// Dynamically link the shared object file and retrieve a pointer to 00437 /// the designated shared object in this file. 00438 static int initialize (const ACE_Service_Type *, 00439 const ACE_TCHAR *parameters); 00440 00441 /// Initialize and activate a statically @a svc_name service. 00442 static int initialize (const ACE_TCHAR *svc_name, 00443 const ACE_TCHAR *parameters); 00444 00445 /// Resume a @a svc_name that was previously suspended or has not yet 00446 /// been resumed (e.g., a static service). 00447 static int resume (const ACE_TCHAR svc_name[]); 00448 00449 /** 00450 * Suspend @a svc_name. Note that this will not unlink the service 00451 * from the daemon if it was dynamically linked, it will mark it as 00452 * being suspended in the Service Repository and call the <suspend> 00453 * member function on the appropriate ACE_Service_Object. A 00454 * service can be resumed later on by calling the <RESUME> member 00455 * function... 00456 */ 00457 static int suspend (const ACE_TCHAR svc_name[]); 00458 00459 /// Totally remove @a svc_name from the daemon by removing it 00460 /// from the ACE_Reactor, and unlinking it if necessary. 00461 static int remove (const ACE_TCHAR svc_name[]); 00462 00463 #if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) 00464 // We must provide these function to bridge the Svc_Conf parser 00465 // with ACE. 00466 static int initialize (const ACE_Service_Type *, ACE_ANTI_TCHAR []); 00467 static int initialize (const char svc_name[], ACE_ANTI_TCHAR parameters[]); 00468 static int resume (const ACE_ANTI_TCHAR svc_name[]); 00469 static int suspend (const ACE_ANTI_TCHAR svc_name[]); 00470 static int remove (const ACE_ANTI_TCHAR svc_name[]); 00471 #endif /* ACE_HAS_WINCE */ 00472 00473 /// Dump the state of an object. 00474 void dump (void) const; 00475 00476 /// Set the signal_handler;for internal use by ACE_Object_Manager only. 00477 static ACE_INLINE void signal_handler (ACE_Sig_Adapter *); 00478 00479 /// Declare the dynamic allocation hooks. 00480 ACE_ALLOC_HOOK_DECLARE; 00481 00482 /// Process a file containing a list of service configuration 00483 /// directives. 00484 static int process_file (const ACE_TCHAR file[]); 00485 00486 /// Process one service configuration @a directive, which is passed as 00487 /// a string. Returns the number of errors that occurred. 00488 static int process_directive (const ACE_TCHAR directive[]); 00489 00490 /// Process one static service definition. 00491 /** 00492 * Load a new static service into the ACE_Service_Repository. 00493 * 00494 * @param ssd Service descriptor, see the document of 00495 * ACE_Static_Svc_Descriptor for more details. 00496 * 00497 * @param force_replace If set the new service descriptor replaces 00498 * any previous instance in the ACE_Service_Repository. 00499 * 00500 * @return Returns -1 if the service cannot be 'loaded'. 00501 */ 00502 static int process_directive (const ACE_Static_Svc_Descriptor &ssd, 00503 int force_replace = 0); 00504 00505 /** 00506 * Process (or re-process) service configuration requests that are 00507 * provided in the svc.conf file(s). Returns the number of errors 00508 * that occurred. 00509 */ 00510 static int process_directives (void); 00511 00512 /// Handles signals to trigger reconfigurations. 00513 static void handle_signal (int sig, siginfo_t *, ucontext_t *); 00514 00515 /** 00516 * Handle the command-line options intended for the 00517 * ACE_Service_Config. Note that @c argv[0] is assumed to be the 00518 * program name. 00519 * The arguments that are valid in a call to this method are 00520 * - '-b' Option to indicate that we should be a daemon 00521 * - '-d' Turn on debugging mode 00522 * - '-f' Option to read in the list of svc.conf file names 00523 * - '-k' Option to read a wide string where in the logger output can 00524 * be written 00525 * - '-y' Turn on the flag for a repository of statically 00526 * linked services 00527 * - '-n' Need not have a repository of statically linked services 00528 * - '-S' Option to read in the list of services on the command-line 00529 * Please observe the difference between options '-f' that looks 00530 * for a list of files and here a list of services. 00531 */ 00532 static int parse_args (int, ACE_TCHAR *argv[]); 00533 #if (ACE_USES_CLASSIC_SVC_CONF == 0) 00534 static ACE_Service_Type *create_service_type (const ACE_TCHAR *n, 00535 ACE_Service_Type_Impl *o, 00536 ACE_DLL &dll, 00537 int active); 00538 #endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ 00539 00540 static ACE_Service_Type_Impl * 00541 create_service_type_impl (const ACE_TCHAR *name, 00542 int type, 00543 void *symbol, 00544 u_int flags, 00545 ACE_Service_Object_Exterminator gobbler); 00546 00547 protected: 00548 00549 /// Process service configuration requests that were provided on the 00550 /// command-line. Returns the number of errors that occurred. 00551 static int process_commandline_directives (void); 00552 00553 #if (ACE_USES_CLASSIC_SVC_CONF == 1) 00554 /// This is the implementation function that process_directives() 00555 /// and process_directive() both call. Returns the number of errors 00556 /// that occurred. 00557 static int process_directives_i (ACE_Svc_Conf_Param *param); 00558 #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ 00559 00560 /// Become a daemon. 00561 static int start_daemon (void); 00562 00563 /// Add the default statically-linked services to the 00564 /// ACE_Service_Repository. 00565 static int load_static_svcs (void); 00566 00567 00568 private: 00569 00570 /// True if reconfiguration occurred. 00571 static sig_atomic_t reconfig_occurred_; 00572 00573 // = Set by command-line options. 00574 /// Shall we become a daemon process? 00575 static int be_a_daemon_; 00576 00577 /// Pathname of file to write process id. 00578 static ACE_TCHAR *pid_file_name_; 00579 00580 /// Number of the signal used to trigger reconfiguration. 00581 static int signum_; 00582 00583 /// Handles the reconfiguration signals. 00584 static ACE_Sig_Adapter *signal_handler_; 00585 00586 /// Pointer to the Singleton (ACE_Cleanup) Gestalt instance. 00587 /// There is thread-specific global instance pointer, which is used to 00588 /// temporarily change which Gestalt instance is used for static service 00589 /// registrations. 00590 /// 00591 /// A specific use case is a thread, which loads a _dynamic_ service from 00592 /// a DLL. If the said DLL also contains additional _static_ services, 00593 /// those *must* be registered with the same configuration repository as 00594 /// the dynamic service. Otherwise, the DLL's static services would be 00595 /// registered with the global Gestalt and may outlive the DLL that 00596 /// contains their code and perhaps the memory in which they are in. 00597 /// This is a problem because if the DLL gets unloaded (as it will, if 00598 /// it was loaded in an instance of Gestalt), the DLL's memory will be 00599 /// deallocated, but the global service repository will still "think" 00600 /// it must finalize the (DLL's) static services - with disastrous 00601 /// consequences, occurring in the post-main code (at_exit()). 00602 00603 /// This class needs the intimate access to be able to swap the 00604 /// current TSS pointer for the global Gestalt. 00605 friend class ACE_Service_Config_Guard; 00606 }; 00607 00608 /** 00609 * @class ACE_Service_Config_Guard 00610 * 00611 * @brief A guard class, designed to be instantiated on the stack. 00612 * 00613 * Instantiating it with a specific configuration ensures any references to 00614 * ACE_Service_Config::instance(), even when occuring in static constructors, 00615 * will allways access the designated configuration instance. 00616 * This comes very handy when a dynamic service also registers any static 00617 * services of its own and their static factories. 00618 */ 00619 class ACE_Export ACE_Service_Config_Guard 00620 { 00621 public: 00622 ACE_Service_Config_Guard (ACE_Service_Gestalt * psg); 00623 ~ACE_Service_Config_Guard (void); 00624 00625 private: 00626 // Private AND not implemented to disable copying 00627 ACE_Service_Config_Guard(const ACE_Service_Config_Guard&); 00628 ACE_Service_Config_Guard& operator= (const ACE_Service_Config_Guard&); 00629 00630 private: 00631 ACE_Service_Gestalt* saved_; 00632 }; 00633 00634 00635 ACE_END_VERSIONED_NAMESPACE_DECL 00636 00637 #if defined (__ACE_INLINE__) 00638 #include "ace/Service_Config.inl" 00639 #endif /* __ACE_INLINE__ */ 00640 00641 00642 #include /**/ "ace/post.h" 00643 00644 #endif /* ACE_SERVICE_CONFIG_H */