diff options
author | john_c <john_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-04-28 03:50:28 +0000 |
---|---|---|
committer | john_c <john_c@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2006-04-28 03:50:28 +0000 |
commit | 88556d568eb0a06bf8af2ddefacbc1ad5f00401e (patch) | |
tree | 72f4a0e33b9dd26d1783ff005d67494bfb79a9de /ace/Service_Config.h | |
parent | 317d8c1ce78436f0107f056418c0c5f5b4231069 (diff) | |
download | ATCD-oci_dave_wchar_refactor_branch.tar.gz |
4_27_06 branch merge in and compile error fixedoci_dave_wchar_refactor_branch
Diffstat (limited to 'ace/Service_Config.h')
-rw-r--r-- | ace/Service_Config.h | 237 |
1 files changed, 166 insertions, 71 deletions
diff --git a/ace/Service_Config.h b/ace/Service_Config.h index 6fafb50408b..82b988d69d6 100644 --- a/ace/Service_Config.h +++ b/ace/Service_Config.h @@ -17,13 +17,12 @@ #include "ace/config-all.h" #include "ace/Default_Constants.h" +#include "ace/Service_Gestalt.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ -#include "ace/Unbounded_Queue.h" -#include "ace/Unbounded_Set.h" #include "ace/SString.h" #include "ace/OS_NS_signal.h" @@ -134,20 +133,8 @@ public: bool operator!= (ACE_Static_Svc_Descriptor &) const; }; -// Maintain a set of the statically linked service descriptors. -typedef ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *> - ACE_STATIC_SVCS; -typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *> - ACE_STATIC_SVCS_ITERATOR; - -// Maintain a queue of services to be configured from the -// command-line. -typedef ACE_Unbounded_Queue<ACE_TString> - ACE_SVC_QUEUE; -typedef ACE_Unbounded_Queue_Iterator<ACE_TString> - ACE_SVC_QUEUE_ITERATOR; - #define ACE_Component_Config ACE_Service_Config + /** * @class ACE_Service_Config * @@ -155,7 +142,22 @@ typedef ACE_Unbounded_Queue_Iterator<ACE_TString> * configuration of services. * * The ACE_Service_Config uses the Monostate pattern. Therefore, - * you can only have one of these instantiated per-process. + * you can only have one of these instantiated per-process. It + * represents the process-wide collection of services, which is + * typicaly shared among all other configurable entities. The only + * ACE_Service_Config instance is registered with and owned by the + * ACE_Object_Manager. + * + * By contrast, the ACE_Service_Gestalt represents the collection + * of services, pertaining to a configurable entity. Typicaly, a + * "configurable entity" is an instance, which owns an instance of + * ACE_Service_Gestalt in order to ensure full controll over the + * services it needs. + * + * Another facet of ACE_Service_Config is that for a given thread, + * it provides access to its current, process-global + * ACE_Service_Gestalt instance through its curent() method. + * * @note The signal_handler_ static member is allocated by the * ACE_Object_Manager. The ACE_Service_Config constructor * uses signal_handler_. Therefore, if the program has any @@ -164,13 +166,9 @@ typedef ACE_Unbounded_Queue_Iterator<ACE_TString> * not eliminated, by _not_ #defining * ACE_HAS_NONSTATIC_OBJECT_MANAGER. */ -class ACE_Export ACE_Service_Config +class ACE_Export ACE_Service_Config: public ACE_Service_Gestalt { public: - enum - { - MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE - }; // = Initialization and termination methods. @@ -180,7 +178,7 @@ public: * registered when the repository is opened. */ ACE_Service_Config (int ignore_static_svcs = 1, - size_t size = ACE_Service_Config::MAX_SERVICES, + size_t size = ACE_Service_Gestalt::MAX_SERVICES, int signum = SIGHUP); /** @@ -191,9 +189,19 @@ public: ACE_Service_Config (const ACE_TCHAR program_name[], const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY); + /// Perform user-specified close activities and remove dynamic + /// memory. + virtual ~ACE_Service_Config (void); + + +protected: + /** - * Performs an open without parsing command-line arguments. The - * @a logger_key indicates where to write the logging output, which + * Performs an open without parsing command-line arguments. + * Implements whats different in the opening sequence + * for this class, as opposed to the base class. + * + * The @a logger_key indicates where to write the logging output, which * is typically either a STREAM pipe or a socket address. If * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file * will be ignored. If @a ignore_debug_flag is non-0 then the @@ -201,12 +209,56 @@ public: * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of * errors that occurred on failure and 0 otherwise. */ - static int open_i (const ACE_TCHAR program_name[], - const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, - int ignore_default_svc_conf_file = 0, - int ignore_debug_flag = 0); + virtual int open_i (const ACE_TCHAR program_name[], + const ACE_TCHAR *logger_key, + bool ignore_static_svcs, + bool ignore_default_svc_conf_file, + bool ignore_debug_flag); /** + * Implements whats different in the command line parameter processing + * for this class, as opposed to the base class. + */ + virtual int parse_args_i (int argc, ACE_TCHAR *argv[]); + + + + /// = Static interfaces + + + +protected: + + /// Mutator to set the (TSS) global instance. Intended for use by helper + /// classes, like ACE_Service_Config_Guard which when instantiated on the + /// stack, can temporarily change which gestalt instance is viewed as + /// global from the point of view of the static initializers in DLLs. + static int current (ACE_Service_Gestalt*); + + +public: + + /// If not yet initialized, creates a process-wide instance + /// global instance, which is registered with the ACE_Object_Manager, + /// via ACE_Singleton. Note that this is allways the same instance, + /// in contrast with current (), which may be different instance at + /// different times, dependent on the context. + static ACE_Service_Gestalt* global (void); + + + /// Accessor for the "current" service repository through a pointer + /// held in TSS. + static ACE_Service_Gestalt* current (void); + + /// This is what the static service initializators are hard-wired + /// to use, so in order to keep interface changes to a minimum this + /// method merely forwards to current(). Thus it is possible to + /// temporarily replace what those initializers think is the global + /// service repository, for instance when dynamically loading a + /// service from a DLL, which in turn, contains its own static services. + static ACE_Service_Gestalt* instance (void); + + /** * Performs an open without parsing command-line arguments. The * @a logger_key indicates where to write the logging output, which * is typically either a STREAM pipe or a socket address. If @@ -283,10 +335,6 @@ public: int ignore_default_svc_conf_file = 0, int ignore_debug_flag = 0); - /// Perform user-specified close activities and remove dynamic - /// memory. - virtual ~ACE_Service_Config (void); - /// Tidy up and perform last rites when ACE_Service_Config is shut /// down. This method calls <close_svcs>. Returns 0. static int close (void); @@ -315,11 +363,31 @@ public: // semantics for the Reactor, Service_Repository, Thread_Manager, // and Acceptor/Connector Strategy factory. Other portions of the // system may need to access them at some point or another... + + // = This is not strictly needed, anymore since the service configurator + // has been refactored to allow multiple service configuration + // instances (called gestalts). The interfaces, however were retained in for + // the sake of maintaining source-code compatibility. + // = Accessors and mutators for process-wide Singletons. /// Returns a pointer to the list of statically linked services. - static ACE_STATIC_SVCS *static_svcs (void); + /// + /// @deprecated - Same as instance(), but still useful in legacy code, + /// (notably, one that can not be easily modified) which uses the following + /// idiom for registering static services: + /// + /// ACE_Service_Config::static_svcs ()->insert (...); + static ACE_Service_Gestalt *static_svcs (void); + + /// Insert a static service descriptor for processing on open_i(). The + /// corresponding ACE_STATIC_SVC_* macros were chaged to use this method + /// instead of obtaining a ptr to a container. See the note on static_svcs(). + /// Added to prevent exposing the internal storage representation of the + /// services repository and provide a better way of debugging service + /// loading and registration problems. + static int insert (ACE_Static_Svc_Descriptor *svc); // = Utility methods. /// Dynamically link the shared object file and retrieve a pointer to @@ -352,11 +420,11 @@ public: #if defined (ACE_HAS_WINCE) && defined (ACE_USES_WCHAR) // We must provide these function to bridge the Svc_Conf parser // with ACE. - static int initialize (const ACE_Service_Type *, char parameters[]); - static int initialize (const char svc_name[], char parameters[]); - static int resume (const char svc_name[]); - static int suspend (const char svc_name[]); - static int remove (const char svc_name[]); + static int initialize (const ACE_Service_Type *, ACE_ANTI_TCHAR []); + static int initialize (const char svc_name[], ACE_ANTI_TCHAR parameters[]); + static int resume (const ACE_ANTI_TCHAR svc_name[]); + static int suspend (const ACE_ANTI_TCHAR svc_name[]); + static int remove (const ACE_ANTI_TCHAR svc_name[]); #endif /* ACE_HAS_WINCE */ /// Dump the state of an object. @@ -426,12 +494,15 @@ public: int active); #endif /* ACE_USES_CLASSIC_SVC_CONF == 0 */ - static ACE_Service_Type_Impl *create_service_type_impl (const ACE_TCHAR *name, - int type, - void *symbol, - u_int flags, - ACE_Service_Object_Exterminator gobbler); + static ACE_Service_Type_Impl * + create_service_type_impl (const ACE_TCHAR *name, + int type, + void *symbol, + u_int flags, + ACE_Service_Object_Exterminator gobbler); + protected: + /// Process service configuration requests that were provided on the /// command-line. Returns the number of errors that occurred. static int process_commandline_directives (void); @@ -442,7 +513,8 @@ protected: /// that occurred. static int process_directives_i (ACE_Svc_Conf_Param *param); #else - /// Helper function to dynamically link in the XML Service Configurator parser. + /// Helper function to dynamically link in the XML Service Configurator + /// parser. static ACE_XML_Svc_Conf *get_xml_svc_conf (ACE_DLL &d); #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ @@ -453,23 +525,8 @@ protected: /// ACE_Service_Repository. static int load_static_svcs (void); + private: - /// Indicates where to write the logging output. This is typically - /// either a STREAM pipe or a socket address. - static const ACE_TCHAR *logger_key_; - - /// Singleton repository of statically linked services. - static ACE_STATIC_SVCS *static_svcs_; - - /// Queue of services specified on the command-line. - static ACE_SVC_QUEUE *svc_queue_; - - /// Queue of svc.conf files specified on the command-line. - /// @@ This should probably be made to handle unicode filenames... - static ACE_SVC_QUEUE *svc_conf_file_queue_; - - /// Initialize the <svc_conf_file_queue_> if necessary. - static int init_svc_conf_file_queue (void); /// True if reconfiguration occurred. static sig_atomic_t reconfig_occurred_; @@ -481,25 +538,63 @@ private: /// Pathname of file to write process id. static ACE_TCHAR *pid_file_name_; - /// Should we avoid loading the static services? - static int no_static_svcs_; - /// Number of the signal used to trigger reconfiguration. static int signum_; /// Handles the reconfiguration signals. static ACE_Sig_Adapter *signal_handler_; - /** - * Keep track of whether the ACE_Service_Config is already - * initialized. If so, we can't allow <yyparse> to be called since - * it's not reentrant. This variable is incremented by the - * <ACE_Service_Config::open> method and decremented by the - * <ACE_Service_Config::close> method. - */ - static int is_initialized_; + /// Pointer to the Singleton (ACE_Cleanup) Gestalt instance. + /// There is thread-specific global instance pointer, which is used to + /// temporarily change which Gestalt instance is used for static service + /// registrations. + /// + /// A specific use case is a thread, which loads a _dynamic_ service from + /// a DLL. If the said DLL also contains additional _static_ services, + /// those *must* be registered with the same configuration repository as + /// the dynamic service. Otherwise, the DLL's static services would be + /// registered with the global Gestalt and may outlive the DLL that + /// contains their code and perhaps the memory in which they are in. + /// This is a problem because if the DLL gets unloaded (as it will, if + /// it was loaded in an instance of Gestalt), the DLL's memory will be + /// deallocated, but the global service repository will still "think" + /// it must finalize the (DLL's) static services - with disastrous + /// consequences, occurring in the post-main code (at_exit()). + static ACE_TSS< ACE_TSS_Type_Adapter <ACE_Service_Gestalt*> > current_; + + /// This class needs the intimate access to be able to swap the + /// current TSS pointer for the global Gestalt. + friend class ACE_Service_Config_Guard; + +}; + +/** + * @class ACE_Service_Config_Guard + * + * @brief A guard class, designed to be instantiated on the stack. + * + * Instantiating it with a specific configuration ensures any references to + * ACE_Service_Config::instance(), even when occuring in static constructors, + * will allways access the designated configuration instance. + * This comes very handy when a dynamic service also registers any static + * services of its own and their static factories. + */ +class ACE_Export ACE_Service_Config_Guard +{ +public: + ACE_Service_Config_Guard (ACE_Service_Gestalt * psg); + ~ACE_Service_Config_Guard (void); + +private: + // Private AND not implemented to disable copying + ACE_Service_Config_Guard(const ACE_Service_Config_Guard&); + ACE_Service_Config_Guard& operator= (const ACE_Service_Config_Guard&); + +private: + ACE_Service_Gestalt* saved_; }; + ACE_END_VERSIONED_NAMESPACE_DECL #if defined (__ACE_INLINE__) |