diff options
author | iliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-04-08 12:16:13 +0000 |
---|---|---|
committer | iliyan <iliyan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2008-04-08 12:16:13 +0000 |
commit | 1243661f99c8dc2e36bbc1c414347481d5b8eb87 (patch) | |
tree | 3fbecd54f322e40a0683c9bad740a26b651ce19e /TAO | |
parent | c13095fddb25b40243bb22f694834c3bd0820d03 (diff) | |
download | ATCD-1243661f99c8dc2e36bbc1c414347481d5b8eb87.tar.gz |
ChangeLogTag: Tue Apr 8 12:04:20 UTC 2008 Iliyan Jeliazkov <iliyan@ociweb.com>
Diffstat (limited to 'TAO')
-rw-r--r-- | TAO/ChangeLog | 38 | ||||
-rw-r--r-- | TAO/tao/ORB.cpp | 237 | ||||
-rw-r--r-- | TAO/tao/ORB.h | 9 | ||||
-rw-r--r-- | TAO/tao/ORB_Core.cpp | 14 | ||||
-rw-r--r-- | TAO/tao/ORB_Core.h | 6 | ||||
-rw-r--r-- | TAO/tao/ORB_Core.inl | 2 | ||||
-rw-r--r-- | TAO/tao/TAO_Internal.cpp | 322 | ||||
-rw-r--r-- | TAO/tao/TAO_Internal.h | 13 | ||||
-rw-r--r-- | TAO/tests/ORB_Local_Config/Shared/Test.cpp | 8 |
9 files changed, 338 insertions, 311 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index 40c4b5d9692..e8de1edec8a 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,41 @@ +Tue Apr 8 12:04:20 UTC 2008 Iliyan Jeliazkov <iliyan@ociweb.com> + + This is the last batch of changes related to the re-factoring of + the service configuration, which aims to eliminate a number of + related memory leaks and bugs. The changes are being ported back + from the "iliyan-gestalt" branch. + + * tao/ORB.h: + * tao/ORB.cpp (ORB_init,init_orb_globals,find_orb_context): + + Modified ORB_init to accept -ORBGestalt command line parameter + which specifies which service configuration context the new ORB + will use. Acceptable values (case-insensitive) include "LOCAL" + forces the ORB to manage its own, local service configuration + context (gestalt). "GLOBAL" forces the new ORB to use (but not + own) the process-global gestalt. The caller can also identify a + particular existing ORB, who will share its ownership of a gestalt + with the new ORB. The existing ORB ID must be prefixed with "ORB:" + and the resulting string as a whole is case-sensitive. Removed + init_orb_globals. + + * tao/ORB_Core.h (TAO_ORB_Core): + * tao/ORB_Core.inl (configuration): + * tao/ORB_Core.cpp (TAO_ORB_Core,orbinitializer_registry_i): + + Modified tor to take a smart pointer for the service + configuration. The core now has a smart pointer member which + allows us to destroy local service configuration contexts + _exactly_ when they are no longer needed and eliminate memory + leaks. + + * tao/TAO_Internal.h: + * tao/TAO_Internal.cpp (close_services,open_services): + + Updated for the use of smart pointer for the gestalt + + * tests/ORB_Local_Config/Shared/Test.cpp (testReusingGlobals): + Sun Apr 6 00:03:27 UTC 2008 Iliyan Jeliazkov <iliyan@ociweb.com> * orbsvcs/tests/Notify/Bug_3252_Regression/server.cpp: diff --git a/TAO/tao/ORB.cpp b/TAO/tao/ORB.cpp index 534b92a238a..664e07a98e4 100644 --- a/TAO/tao/ORB.cpp +++ b/TAO/tao/ORB.cpp @@ -49,14 +49,6 @@ ACE_RCSID (tao, static const char ior_prefix[] = "IOR:"; -// = Static initialization. - -namespace -{ - // Count of the number of ORBs. - int orb_init_count = 0; -} - // **************************************************************** TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -1053,24 +1045,6 @@ CORBA::ORB::check_shutdown (void) } } -// **************************************************************** - -void -TAO::ORB::init_orb_globals (void) -{ - // This method should be invoked atomically. It is the caller's - // responsibility to ensure that this condition is satisfied. - - // Prevent multiple initializations. - if (orb_init_count != 0) - { - return; - } - else - { - ++orb_init_count; - } -} CORBA::ORB_ptr CORBA::ORB::_tao_make_ORB (TAO_ORB_Core * orb_core) @@ -1136,54 +1110,88 @@ namespace TAO } return found; } -} -// ORB initialization, per OMG document 98-12-01. -CORBA::ORB_ptr -CORBA::ORB_init (int &argc, char *argv[], const char *orbid) -{ - // Use this string variable to hold the orbid - ACE_CString orbid_string (orbid); + ACE_Service_Gestalt_Auto_Ptr + find_orb_context (const ACE_CString& orbconfig_string) + { + const ACE_TCHAR *arg = ACE_TEXT_CHAR_TO_TCHAR(orbconfig_string.c_str ()); - // Copy command line parameter not to use original. - ACE_Argv_Type_Converter command_line(argc, argv); + // Need a local repo? Make one which typically should not be as + // big as the default repository + const ACE_TCHAR *local = ACE_TEXT("LOCAL"); + if (ACE_OS::strcasecmp (arg, local) == 0) + { + ACE_Service_Gestalt_Auto_Ptr gestalt; + ACE_NEW_THROW_EX (gestalt, + ACE_Service_Gestalt + (ACE_Service_Gestalt::MAX_SERVICES / 4, true), + CORBA::NO_MEMORY + (CORBA::SystemException::_tao_minor_code (0, + ENOMEM), + CORBA::COMPLETED_NO)); + return gestalt; + } - { - // Using ACE_Static_Object_Lock::instance() precludes ORB_init() - // from being called within a static object CTOR. - ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, - guard, - *ACE_Static_Object_Lock::instance (), - CORBA::ORB::_nil ())); - - // Make sure TAO's singleton manager is initialized. - // We need to initialize before TAO_default_environment() is called - // since that call instantiates a TAO_TSS_Singleton. - if (TAO_Singleton_Manager::instance ()->init () == -1) - { - return CORBA::ORB::_nil (); - } + // Explicit global case? + const ACE_TCHAR *global = ACE_TEXT("GLOBAL"); + if (orbconfig_string.is_empty () || ACE_OS::strcasecmp (arg, global) == 0) + { + return ACE_Service_Config::global (); + } - TAO::ORB::init_orb_globals (); - } + // Someone else's context? + const ACE_TCHAR *shared = ACE_TEXT("ORB:"); + if (ACE_OS::strncmp (arg, shared, sizeof (shared) - 1) == 0) + { + ACE_CString orbid (orbconfig_string.substr (sizeof (shared))); - // Make sure the following is done after the global ORB - // initialization since we need to have exceptions initialized. + // Get ORB Core + TAO_ORB_Core_Auto_Ptr oc (TAO::ORB_Table::instance ()->find (orbid.c_str ())); + if (oc.get () != 0) + return oc->configuration (); + + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ERROR: Unable to find ORB: %s. Invalid shared ") + ACE_TEXT ("configuration argument \"%s\"\n"), + orbid.c_str (), arg)); + throw ::CORBA::BAD_PARAM + (CORBA::SystemException::_tao_minor_code + ( TAO_ORB_CORE_INIT_LOCATION_CODE, + ENOTSUP), + CORBA::COMPLETED_NO); + } + + + // Unknown value + if (TAO_debug_level > 0) + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("ERROR: -ORBGestalt unknown value <%s>\n"), + orbconfig_string.c_str())); + + throw ::CORBA::BAD_PARAM + (CORBA::SystemException::_tao_minor_code + ( TAO_ORB_CORE_INIT_LOCATION_CODE, + EINVAL), + CORBA::COMPLETED_NO); + } +} + +// ORB initialization, per OMG document 98-12-01. +CORBA::ORB_ptr +CORBA::ORB_init (int &argc, char *argv[], const char *orbid) +{ // It doesn't make sense for argc to be zero and argv to be // non-empty/zero, or for argc to be greater than zero and argv be // zero. - size_t const argv0_len = - (command_line.get_TCHAR_argv () - ? (*command_line.get_TCHAR_argv () - ? ACE_OS::strlen (*command_line.get_TCHAR_argv ()) - : 0) - : 0); - - if ((command_line.get_argc () == 0 && argv0_len != 0) - || (command_line.get_argc () != 0 - && (command_line.get_TCHAR_argv () == 0 - || command_line.get_TCHAR_argv ()[0] == 0))) + size_t const argv0_len = (argv ? (*argv + ? ACE_OS::strlen (*argv) + : 0) + : 0); + + if ((argc == 0 && argv0_len != 0) + || (argc != 0 && (argv == 0 || argv[0] == 0))) { throw ::CORBA::BAD_PARAM ( CORBA::SystemException::_tao_minor_code ( @@ -1192,11 +1200,31 @@ CORBA::ORB_init (int &argc, char *argv[], const char *orbid) CORBA::COMPLETED_NO); } + // Scan the parameters to find any we could interpret to + // use for initializing the global context. Note that if + // the global context has been initialized already, the + // parameters may either be ignored, or later used to initialize + // a local configuration context. The chosen action depends on + // weather we want the ORB to share the global context or + // have its own, private (or local) context. + if (TAO::ORB::open_global_services (argc, argv) == -1) + { + return CORBA::ORB::_nil (); + } + + // Copy command line parameter not to corrupt the original. + ACE_Argv_Type_Converter command_line(argc, argv); + + + // Make sure the following is done after the global ORB + // initialization since we need to have exceptions initialized. + + // Use this string variable to hold the orbid + ACE_CString orbid_string (orbid); TAO::parse_orb_opt (command_line, ACE_TEXT("-ORBid"), orbid_string); // Get ORB Core - TAO_ORB_Core_Auto_Ptr oc ( - TAO::ORB_Table::instance ()->find (orbid_string.c_str ())); + TAO_ORB_Core_Auto_Ptr oc (TAO::ORB_Table::instance ()->find (orbid_string.c_str ())); // The ORB was already initialized. Just return that one. if (oc.get () != 0) @@ -1207,74 +1235,11 @@ CORBA::ORB_init (int &argc, char *argv[], const char *orbid) // Determine the service object registry this ORB will use. The choises // are: (a) the legacy (global); (b) its own, local, or (c) share somebody - // else's configuration - - // By default use the process (application?) global configuration context - ACE_Service_Gestalt* gestalt = ACE_Service_Config::current (); - - // Use this string variable to hold the config identity + // else's configuration. By default use the process-wide (global) context + // Use this string variable to hold the configuration identity key ACE_CString orbconfig_string; - ACE_Auto_Ptr<ACE_Service_Gestalt> guard_gestalt(0); - - if (TAO::parse_orb_opt (command_line, - ACE_TEXT("-ORBGestalt"), - orbconfig_string)) - { - const ACE_TCHAR *arg = ACE_TEXT_CHAR_TO_TCHAR(orbconfig_string.c_str ()); - const ACE_TCHAR *local = ACE_TEXT("LOCAL"); - const ACE_TCHAR *shared = ACE_TEXT("ORB:"); - // Need a local repo? Make one which typically should not be as - // big as the default repository - if (ACE_OS::strcasecmp (arg,local) == 0) - { - ACE_NEW_THROW_EX (gestalt, - ACE_Service_Gestalt - (ACE_Service_Gestalt::MAX_SERVICES / 4, true), - CORBA::NO_MEMORY - (CORBA::SystemException::_tao_minor_code (0, - ENOMEM), - CORBA::COMPLETED_NO)); - guard_gestalt.reset(gestalt); - } - else if (ACE_OS::strncmp (arg, shared, sizeof (shared) - 1) == 0) - { - // @TODO: At some point, we need to implement a lookup of an - // existing configuration context based on the orbid - // following the "ORB:" It may be the case that contexts may - // be initialized separate from the ORB of the same ID, in - // which case we would need some sort of table of contexts - // at which point we would either find this one or make a - // new one. And making a new one would require assigning it - // to the guard_gestalt just like the local. - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("ERROR: Sharing ORB configuration ") - ACE_TEXT ("contexts is not yet supported\n"))); - } - - throw ::CORBA::BAD_PARAM - (CORBA::SystemException::_tao_minor_code - ( TAO_ORB_CORE_INIT_LOCATION_CODE, - ENOTSUP), - CORBA::COMPLETED_NO); - } - else - { - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("ERROR: -ORBGestalt unknown value <%s>\n"), - orbconfig_string.c_str())); - } - - throw ::CORBA::BAD_PARAM - (CORBA::SystemException::_tao_minor_code - ( TAO_ORB_CORE_INIT_LOCATION_CODE, - EINVAL), - CORBA::COMPLETED_NO); - } - } + TAO::parse_orb_opt (command_line, ACE_TEXT("-ORBGestalt"), orbconfig_string); + ACE_Service_Gestalt_Auto_Ptr gestalt = TAO::find_orb_context (orbconfig_string); // An ORB corresponding to the desired ORBid doesn't exist so create // a new one. @@ -1292,10 +1257,6 @@ CORBA::ORB_init (int &argc, char *argv[], const char *orbid) // out of scope. oc.reset (tmp); - // The ORB now owns its configuration and the auto pointer is not - // necessary anymore. - guard_gestalt.release (); - // Having the ORB's default static services be shared among all ORBs // is tempting from the point of view of reducing the dynamic // footprint. However, if the ORB in a DLL and the rest of that diff --git a/TAO/tao/ORB.h b/TAO/tao/ORB.h index 5201a3b506c..f1522a556c8 100644 --- a/TAO/tao/ORB.h +++ b/TAO/tao/ORB.h @@ -579,15 +579,6 @@ namespace CORBA }; } // End namespace CORBA -namespace TAO -{ - namespace ORB - { - /// Initialize the ORB globals correctly, i.e., only when they - /// haven't been initialized yet. - void init_orb_globals (void); - } -} TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/ORB_Core.cpp b/TAO/tao/ORB_Core.cpp index 39c93e10099..01bd0590ed4 100644 --- a/TAO/tao/ORB_Core.cpp +++ b/TAO/tao/ORB_Core.cpp @@ -181,7 +181,7 @@ TAO_ORB_Core_Static_Resources::operator=(const TAO_ORB_Core_Static_Resources& ot // **************************************************************** TAO_ORB_Core::TAO_ORB_Core (const char *orbid, - ACE_Service_Gestalt* gestalt) + ACE_Service_Gestalt_Auto_Ptr gestalt) : protocols_hooks_ (0), network_priority_protocols_hooks_ (0), #if TAO_USE_LOCAL_MEMORY_POOL == 1 @@ -329,10 +329,6 @@ TAO_ORB_Core::~TAO_ORB_Core (void) // This will destroy the service repository for this core (void) TAO::ORB::close_services (this->config_); - if (this->config_ != ACE_Service_Config::global()) - delete this->config_; - - this->config_ = 0; } int @@ -1588,12 +1584,10 @@ TAO_ORB_Core::orbinitializer_registry_i (void) { // @todo The ORBInitializer_Registry is supposed to be a singleton. - ACE_Service_Gestalt * const config = this->configuration (); - // If not, lookup it up. this->orbinitializer_registry_ = ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance - (config, + (this->configuration (), ACE_TEXT ("ORBInitializer_Registry")); #if !defined (TAO_AS_STATIC_LIBS) @@ -1602,14 +1596,14 @@ TAO_ORB_Core::orbinitializer_registry_i (void) // output an error then. if (this->orbinitializer_registry_ == 0) { - config->process_directive ( + this->configuration ()->process_directive ( ACE_DYNAMIC_SERVICE_DIRECTIVE ("ORBInitializer_Registry", "TAO_PI", "_make_ORBInitializer_Registry", "")); this->orbinitializer_registry_ = ACE_Dynamic_Service<TAO::ORBInitializer_Registry_Adapter>::instance - (config, + (this->configuration (), ACE_TEXT ("ORBInitializer_Registry")); } #endif /* !TAO_AS_STATIC_LIBS */ diff --git a/TAO/tao/ORB_Core.h b/TAO/tao/ORB_Core.h index fbfce6f651f..076d656069c 100644 --- a/TAO/tao/ORB_Core.h +++ b/TAO/tao/ORB_Core.h @@ -43,7 +43,7 @@ #include "ace/Lock_Adapter_T.h" #include "ace/TSS_T.h" -#include "ace/Service_Object.h" +#include "ace/Service_Config.h" ACE_BEGIN_VERSIONED_NAMESPACE_DECL class ACE_Data_Block; @@ -165,7 +165,7 @@ class TAO_Export TAO_ORB_Core public: /// Constructor. - TAO_ORB_Core (const char* id, ACE_Service_Gestalt* g); + TAO_ORB_Core (const char* id, ACE_Service_Gestalt_Auto_Ptr g); /// Accessor for the ORB parameters. TAO_ORB_Parameters *orb_params (void); @@ -1230,7 +1230,7 @@ protected: TAO_Codeset_Manager *codeset_manager_; /// ORB's service configuration - ACE_Service_Gestalt *config_; + ACE_Service_Gestalt_Auto_Ptr config_; /// The hook to be set for the SyncScopePolicy Sync_Scope_Hook sync_scope_hook_; diff --git a/TAO/tao/ORB_Core.inl b/TAO/tao/ORB_Core.inl index 05ee53dd0bd..5c8bb2ca7e8 100644 --- a/TAO/tao/ORB_Core.inl +++ b/TAO/tao/ORB_Core.inl @@ -10,7 +10,7 @@ TAO_BEGIN_VERSIONED_NAMESPACE_DECL ACE_INLINE ACE_Service_Gestalt* TAO_ORB_Core::configuration (void) const { - return this->config_; + return this->config_.get (); } ACE_INLINE unsigned long diff --git a/TAO/tao/TAO_Internal.cpp b/TAO/tao/TAO_Internal.cpp index be875638eb8..e9d705e3bb7 100644 --- a/TAO/tao/TAO_Internal.cpp +++ b/TAO/tao/TAO_Internal.cpp @@ -26,6 +26,7 @@ #include "ace/Dynamic_Service.h" #include "ace/Arg_Shifter.h" #include "ace/Argv_Type_Converter.h" +#include "ace/ARGV.h" #include "ace/Env_Value_T.h" #include "ace/ACE.h" #include "ace/OS_NS_stdio.h" @@ -123,13 +124,13 @@ namespace * Initialize ORB-local (private) ACE Service Configurator * repository. * - * @return @c 0 if successful, @c -1 with @c errno set if failure. - * - */ - int open_private_services_i (ACE_Service_Gestalt* pcfg, - int & argc, - char ** argv, - bool skip_service_config_open = false, + * @return @c 0 if successful, @c -1 with @c errno set if failure. + * + */ + int open_private_services_i (ACE_Service_Gestalt_Auto_Ptr pcfg, + int & argc, + char ** argv, + bool skip_service_config_open = false, bool ignore_default_svc_conf_file = false); /** @@ -185,16 +186,159 @@ public: { } -private: - /// The mutex, associated with the condition. Do not use the ACE - /// global mutex, because it causes deadlocks with other thrads that - /// may be in DLL_Manager::open() - ACE_Recursive_Thread_Mutex mutex_; -}; -#endif // ACE_HAS_THREADS + + private: + /// The mutex, associated with the condition. Do not use the ACE + /// global mutex, because it causes deadlocks with other threads that + /// may be in DLL_Manager::open() + ACE_Recursive_Thread_Mutex mutex_; + }; + #endif // ACE_HAS_THREADS + + + + + // **************************************************************** + /// Note that the argument vector will be corrupted upon return + int + TAO::ORB::open_global_services (int argc, + char **argv) + { + { + // Count of the number of (times we did this for all) ORBs. + static int orb_init_count = 0; + + // Using ACE_Static_Object_Lock::instance() precludes ORB_init() + // from being called within a static object CTOR. + ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, + guard, + *ACE_Static_Object_Lock::instance (), + -1)); + + // Make sure TAO's singleton manager is initialized. + // We need to initialize before TAO_default_environment() is called + // since that call instantiates a TAO_TSS_Singleton. + if (TAO_Singleton_Manager::instance ()->init () == -1) + return -1; + + // Prevent multiple initializations. + if (++orb_init_count > 1) + return 0; + + } + + // Prevent any other thread from going through ORB initialization before the + // uber-gestalt is initialized. + ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, + guard, + TAO_Ubergestalt_Ready_Condition::instance ()->mutex (), + -1)); + + if (TAO_debug_level > 2) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Initializing the ") + ACE_TEXT ("process-wide service context\n"))); + } + + ACE_Service_Gestalt* theone = ACE_Service_Config::global (); + ACE_Service_Config_Guard auto_config_guard (theone); + + register_global_services_i (theone); + + // Be certain to copy the program name so that service configurator + // has something to skip! + ACE_CString argv0 ((argc <= 0 || argv == 0) ? "" : ACE_TEXT_ALWAYS_CHAR (argv[0])); + + // Construct an argument vector specific to the process-wide + // (global) Service Configurator instance. + CORBA::StringSeq global_svc_config_argv; + global_svc_config_argv.length (1); + global_svc_config_argv[0] = argv0.c_str (); + + // Will expand the environment variables, if any were used. Is this a good thing? + // I guess it provides greater flexibility for deployment, so let's leave it. Will + // also quote arguments. + ACE_ARGV copyargv (argc, argv, true, true); + + // Adjust to proper TCHAR type + int tmpargc = argc; + ACE_Argv_Type_Converter cvtargv (tmpargc, copyargv.argv()); + + tmpargc = cvtargv.get_argc (); + ACE_TCHAR **tmpargv = cvtargv.get_TCHAR_argv (); + + // Collect global SC parameters. True means "immediately + // apply global setting" like debug flag, etc. + if (parse_global_args_i (tmpargc, + tmpargv, + global_svc_config_argv, + true) == -1) + return -1; + + bool skip_service_config_open = false; // by default we shouldn't + + if (parse_svcconf_args_i (tmpargc, + tmpargv, + global_svc_config_argv) == -1) + return -1; + + if (parse_private_args_i (tmpargc, + tmpargv, + global_svc_config_argv, + skip_service_config_open) == -1) + return -1; + + // Perform the open magic (unless SC::open() has been called already) + int global_svc_config_argc = global_svc_config_argv.length (); + int status = open_private_services_i (theone, + global_svc_config_argc, + global_svc_config_argv.get_buffer (), + skip_service_config_open); + + // okay? + if (status == -1) + { + if (TAO_debug_level > 0) + { + ACE_ERROR ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Failed to open process-") + ACE_TEXT ("wide service configuration context\n"))); + } + + return -1; + } + + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Completed initializing the ") + ACE_TEXT ("process-wide service context\n"))); + + if (TAO_debug_level > 4) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Default ORB services initialization begins\n"))); + + // Load more ORB-related services + register_additional_services_i (theone); + + if (TAO_debug_level > 4) + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) Default ORB services initialization completed\n"))); + + // Notify all other threads that may be waiting, that the global + // gestalt has been initialized. + is_ubergestalt_ready = true; + ACE_MT (if (TAO_Ubergestalt_Ready_Condition::instance ()-> + broadcast () == -1) + return -1); + + return 0; +} + + int -TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, +TAO::ORB::open_services (ACE_Intrusive_Auto_Ptr<ACE_Service_Gestalt> pcfg, int &argc, ACE_TCHAR **argv) { @@ -242,13 +386,7 @@ TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, // Be certain to copy the program name so that service configurator // has something to skip! - ACE_CString argv0 (""); - - if (argc > 0 && argv != 0) - { - argv0 = ACE_TEXT_ALWAYS_CHAR (argv[0]); - } - + ACE_CString argv0 ((argc <= 0 || argv == 0) ? "" : ACE_TEXT_ALWAYS_CHAR (argv[0])); svc_config_argv.length (1); svc_config_argv[0] = argv0.c_str (); @@ -273,122 +411,26 @@ TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, // Construct an argument vector specific to the process-wide // (global) Service Configurator instance. CORBA::StringSeq global_svc_config_argv; + // Parse any globally applicable arguments, but do not make them effective. We are effectively purging the command line from them without affecting the global state - after all, it may be a private (local) configuration context. + int status = + parse_global_args_i(argc, argv, global_svc_config_argv, false); - ACE_Service_Gestalt * theone = ACE_Service_Config::global (); - - if (service_open_count == 1) - { - ACE_Service_Config_Guard config_guard (theone); - - if (TAO_debug_level > 2) - { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) Initializing the ") - ACE_TEXT ("process-wide services\n"))); - } - - register_global_services_i (theone); - - // Be certain to copy the program name so that service configurator - // has something to skip! - ACE_CString gargv0 (""); - - if (argc > 0 && argv != 0) - { - gargv0 = ACE_TEXT_ALWAYS_CHAR (argv[0]); - } - - global_svc_config_argv.length (1); - global_svc_config_argv[0] = gargv0.c_str (); - - if (parse_global_args_i (argc, argv, global_svc_config_argv, true) == -1) - { - return -1; - } - - if (parse_svcconf_args_i (argc, argv, global_svc_config_argv) == -1) - { - return -1; - } - - // If the target configuration happens to be the global context, - // add any 'private' arguments here. - if (pcfg == theone && svc_config_argv.length() > 1) - { - CORBA::ULong glen = global_svc_config_argv.length(); - global_svc_config_argv.length(glen + svc_config_argv.length() - 1); - for (CORBA::ULong i = 1; i < svc_config_argv.length(); i++) - global_svc_config_argv[glen++] = svc_config_argv[i]; - svc_config_argv.length(1); - } - - int global_svc_config_argc = global_svc_config_argv.length (); - int status = - open_private_services_i (theone, - global_svc_config_argc, - global_svc_config_argv.get_buffer (), - skip_service_config_open); - - if (status == -1) - { - if (TAO_debug_level > 0) - { - ACE_ERROR ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) Failed to open process-") - ACE_TEXT ("wide service configuration\n"))); - } - - return -1; - } - - register_additional_services_i (theone); - - if (TAO_debug_level > 4) - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) Default ORB - global ") - ACE_TEXT ("initialization completed.\n"))); - - // Notify all other threads that may be waiting, that the global - // gestalt has been initialized. - { - ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, - guard, - TAO_Ubergestalt_Ready_Condition::instance ()->mutex (), - -1)); - - is_ubergestalt_ready = true; - ACE_MT (if (TAO_Ubergestalt_Ready_Condition::instance ()-> - broadcast () == -1) - return -1); - } - - } - else - { - int status = - parse_global_args_i(argc, argv,global_svc_config_argv, false); - if (status == -1 && TAO_debug_level > 0) + if (status == -1 && TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) Skipping the process-wide ") ACE_TEXT ("service configuration, service_open_count ") ACE_TEXT ("= %d, status = %d\n"), service_open_count, status)); - } if (TAO_debug_level > 2) - { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) Initializing the ") ACE_TEXT ("orb-specific services\n"))); - } if (parse_svcconf_args_i (argc, argv, svc_config_argv) == -1) - { return -1; - } - - int status = 0; + // Not a big deal to call open_private_services_i() again (if it was the global one). The SG::open() would not run if it has already been executed. // only open the private context if it is not also the global context if (pcfg != ACE_Service_Config::global()) { @@ -400,12 +442,7 @@ TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, skip_service_config_open); } - if (status >= 0) - { - return 0; - } - - if (TAO_debug_level > 0) + if (status < 0 && TAO_debug_level > 0) { ACE_ERROR_RETURN ((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) Failed to ") @@ -413,11 +450,11 @@ TAO::ORB::open_services (ACE_Service_Gestalt* pcfg, -1); } - return -1; + return status; } int -TAO::ORB::close_services (ACE_Service_Gestalt* pcfg) +TAO::ORB::close_services (ACE_Service_Gestalt_Auto_Ptr pcfg) { ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, @@ -427,6 +464,7 @@ TAO::ORB::close_services (ACE_Service_Gestalt* pcfg) if (pcfg == ACE_Service_Config::global()) return 0; + return pcfg->close (); } @@ -448,7 +486,7 @@ namespace /// Open services, belonging to the gestalt instance. int - open_private_services_i (ACE_Service_Gestalt * pcfg, + open_private_services_i (ACE_Service_Gestalt_Auto_Ptr pcfg, int & argc, char ** argv, bool skip_service_config_open, @@ -691,19 +729,19 @@ namespace ACE_Arg_Shifter arg_shifter (argc, argv); CORBA::ULong len = 0; + while (arg_shifter.is_anything_left ()) { - const ACE_TCHAR *current_arg = - arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConf")); - - if (0 != current_arg) + // Can't interpret this argument. Move on to the next argument. + if (arg_shifter.cur_arg_strncasecmp (ACE_TEXT ("-ORBSvcConf")) == 0) { - // Specify the name of the svc.conf file to be used. + const ACE_TCHAR *current_arg = + arg_shifter.get_the_parameter (ACE_TEXT ("-ORBSvcConf")); + arg_shifter.consume_arg (); // Proceeds only if the configuration file exists. FILE * const conf_file = ACE_OS::fopen (current_arg, ACE_TEXT ("r")); - if (0 == conf_file) { // Assigning EINVAL to errno to make an exception @@ -712,9 +750,8 @@ namespace errno = EINVAL; ACE_ERROR_RETURN ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) Service ") - ACE_TEXT ("Configurator ") - ACE_TEXT ("unable to open file %s\n"), + ACE_TEXT ("TAO (%P|%t) Unable to open file %s") + ACE_TEXT (", referenced by -ORBSvcConf option\n"), current_arg), -1); } @@ -729,10 +766,7 @@ namespace svc_config_argv[len] = CORBA::string_dup ("-f"); svc_config_argv[len + 1] = CORBA::string_dup (ACE_TEXT_ALWAYS_CHAR (current_arg)); - - arg_shifter.consume_arg (); } - // Can't interpret this argument. Move on to the next argument. else { // Any arguments that don't match are ignored so that the diff --git a/TAO/tao/TAO_Internal.h b/TAO/tao/TAO_Internal.h index 8178f40c349..ee173949e02 100644 --- a/TAO/tao/TAO_Internal.h +++ b/TAO/tao/TAO_Internal.h @@ -27,6 +27,7 @@ ACE_BEGIN_VERSIONED_NAMESPACE_DECL /// Forward declaration class ACE_Service_Gestalt; +template <class X> class ACE_Intrusive_Auto_Ptr; ACE_END_VERSIONED_NAMESPACE_DECL TAO_BEGIN_VERSIONED_NAMESPACE_DECL @@ -43,6 +44,14 @@ namespace TAO */ namespace ORB { + + /** + * If never done it before, extract ACE Service Configurator arguments from the given + * argument vector, and initialize the _global_ configuration gestalt. Return value 0 means OK, + * -1 spells major trouble ... + */ + int open_global_services (int argc, char** argv); + /** * Extract ACE Service Configurator arguments from the given * argument vector, and initialize the ACE Service Configurator. @@ -50,7 +59,7 @@ namespace TAO * @note This method should be called before the ORB Core is * initialized, and before any ORBInitializers are invoked. */ - int open_services (ACE_Service_Gestalt* cfg, int& argc, ACE_TCHAR** argv); + int open_services (ACE_Intrusive_Auto_Ptr<ACE_Service_Gestalt> cfg, int& argc, ACE_TCHAR** argv); /** * The complement to @c open_services(), this will perform @@ -62,7 +71,7 @@ namespace TAO * @return @c 0 if successful, @c -1 with @c errno set if * failure. */ - int close_services (ACE_Service_Gestalt* pcfg); + int close_services (ACE_Intrusive_Auto_Ptr<ACE_Service_Gestalt> pcfg); /** * Set default @c `svc.conf' content. diff --git a/TAO/tests/ORB_Local_Config/Shared/Test.cpp b/TAO/tests/ORB_Local_Config/Shared/Test.cpp index 950121f9f2c..9141a1fa422 100644 --- a/TAO/tests/ORB_Local_Config/Shared/Test.cpp +++ b/TAO/tests/ORB_Local_Config/Shared/Test.cpp @@ -67,10 +67,10 @@ testReusingGlobals (int , ACE_TCHAR *[]) svcname = ACE_TEXT ("CORBANAME_Parser"); ACE_Service_Object* p2 = ACE_Dynamic_Service<ACE_Service_Object>::instance (two.get (), svcname); - if (p2 == 0) // You should be able to find the same stuff here, too`` - { - ACE_ERROR ((LM_ERROR, ACE_TEXT ("Not expected to find %s in the global repo\n"), svcname)); - return -1; + if (p2 == 0) // You should be able to find the same stuff here, too + { + ACE_ERROR ((LM_ERROR, ACE_TEXT ("Not expected to find %s in the global repo\n"), svcname)); + return -1; } return 0; |