Service_Config.h

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

Generated on Thu Nov 9 09:42:02 2006 for ACE by doxygen 1.3.6