// $Id$ #include "ORB_Core.h" #include "ORB_Table.h" #include "TAO_Internal.h" #include "default_client.h" #include "default_server.h" #include "default_resource.h" #include "debug.h" #include "MProfile.h" #include "Profile.h" #include "Stub.h" #include "Leader_Follower.h" #include "Connector_Registry.h" #include "Sync_Strategies.h" #include "Object_Loader.h" #include "ObjectIDList.h" #include "Services_Activate.h" #include "Invocation.h" #include "BiDir_Adapter.h" #include "Collocation_Resolver.h" #include "Endpoint_Selector_Factory.h" #include "Flushing_Strategy.h" #include "Request_Dispatcher.h" #include "Stub_Factory.h" #include "Thread_Lane_Resources.h" #include "Thread_Lane_Resources_Manager.h" #include "Protocols_Hooks.h" #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) # include "Buffering_Constraint_Policy.h" #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ #include "tao/LF_Event_Loop_Thread_Helper.h" #if (TAO_HAS_INTERCEPTORS == 1) #include "tao/ClientRequestInfo.h" #endif /* TAO_HAS_INTERCEPTORS == 1 */ #include "ace/Object_Manager.h" #include "ace/Dynamic_Service.h" #include "ace/Arg_Shifter.h" #include "ace/Argv_Type_Converter.h" #if defined(ACE_MVS) #include "ace/Codeset_IBM1047.h" #endif /* ACE_MVS */ #if !defined (__ACE_INLINE__) # include "ORB_Core.i" #endif /* ! __ACE_INLINE__ */ ACE_RCSID (tao, ORB_Core, "$Id$") // **************************************************************** CORBA::Environment& TAO_default_environment () { return *TAO_TSS_RESOURCES::instance ()->default_environment_; } // **************************************************************** TAO_ORB_Core::Timeout_Hook TAO_ORB_Core::timeout_hook_ = 0; TAO_ORB_Core::Timeout_Hook TAO_ORB_Core::connection_timeout_hook_ = 0; TAO_ORB_Core::Sync_Scope_Hook TAO_ORB_Core::sync_scope_hook_ = 0; ACE_CString TAO_ORB_Core::endpoint_selector_factory_name_ = "Default_Endpoint_Selector_Factory"; ACE_CString TAO_ORB_Core::thread_lane_resources_manager_factory_name_ = "Default_Thread_Lane_Resources_Manager_Factory"; ACE_CString TAO_ORB_Core::collocation_resolver_name_ = "Default_Collocation_Resolver"; ACE_CString TAO_ORB_Core::stub_factory_name_ = "Default_Stub_Factory"; ACE_CString TAO_ORB_Core::resource_factory_name_ = "Resource_Factory"; ACE_CString TAO_ORB_Core::protocols_hooks_name_ = "Protocols_Hooks"; ACE_CString TAO_ORB_Core::dynamic_adapter_name_ = "Dynamic_Adapter"; ACE_CString TAO_ORB_Core::ifr_client_adapter_name_ = "IFR_Client_Adapter"; ACE_CString TAO_ORB_Core::typecodefactory_adapter_name_ = "TypeCodeFactory_Adapter"; ACE_CString TAO_ORB_Core::poa_factory_name_ = "TAO_POA"; ACE_CString TAO_ORB_Core::poa_factory_directive_ = "dynamic TAO_POA Service_Object * TAO_PortableServer:_make_TAO_Object_Adapter_Factory()"; TAO_ORB_Core::TAO_ORB_Core (const char *orbid) : protocols_hooks_ (0), lock_ (), thread_lane_resources_manager_ (0), collocation_resolver_ (0), stub_factory_ (0), protocol_factories_ (0), implrepo_service_ (CORBA::Object::_nil ()), use_implrepo_ (0), typecode_factory_ (CORBA::Object::_nil ()), dynany_factory_ (CORBA::Object::_nil ()), ior_manip_factory_ (CORBA::Object::_nil ()), ior_table_ (CORBA::Object::_nil ()), orb_ (), root_poa_ (), portable_group_poa_hooks_ (0), orb_params_ (), init_ref_map_ (TAO_DEFAULT_OBJECT_REF_TABLE_SIZE), object_ref_table_ (), orbid_ (ACE_OS::strdup (orbid ? orbid : "")), resource_factory_ (0), #if 0 /// @@todo:Need to go one day message_block_dblock_allocator_ (0), message_block_buffer_allocator_ (0), message_block_msgblock_allocator_ (0), #endif /*if 0*/ // server_id_ (0), client_factory_ (0), server_factory_ (0), opt_for_collocation_ (1), use_global_collocation_ (1), collocation_strategy_ (THRU_POA), #if (TAO_HAS_CORBA_MESSAGING == 1) policy_manager_ (0), default_policies_ (0), policy_current_ (0), #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ poa_current_ (), adapter_registry_ (this), poa_adapter_ (0), tm_ (), from_iso8859_ (0), to_iso8859_ (0), from_unicode_ (0), to_unicode_ (0), tss_cleanup_funcs_ (), tss_resources_ (), orb_resources_ (), has_shutdown_ (1), // Start the ORB in a "shutdown" state. Only // after CORBA::ORB_init() is called will the // ORB no longer be shutdown. This does not // mean that the ORB can be reinitialized. It // can only be initialized once. thread_per_connection_use_timeout_ (1), endpoint_selector_factory_ (0), #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) eager_buffering_sync_strategy_ (0), delayed_buffering_sync_strategy_ (0), #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ transport_sync_strategy_ (0), refcount_ (1), policy_factory_registry_ (), #if (TAO_HAS_INTERCEPTORS == 1) pi_current_ (0), client_request_interceptors_ (), server_request_interceptors_ (), #endif /* TAO_HAS_INTERCEPTORS == 1 */ ior_interceptors_ (), parser_registry_ (), bidir_adapter_ (0), bidir_giop_policy_ (0), flushing_strategy_ (0) { #if defined(ACE_MVS) ACE_NEW (this->from_iso8859_, ACE_IBM1047_ISO8859); ACE_NEW (this->to_iso8859_, ACE_IBM1047_ISO8859); #endif /* ACE_MVS */ #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) ACE_NEW (this->eager_buffering_sync_strategy_, TAO_Eager_Buffering_Sync_Strategy); ACE_NEW (this->delayed_buffering_sync_strategy_, TAO_Delayed_Buffering_Sync_Strategy); #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ #if (TAO_HAS_CORBA_MESSAGING == 1) ACE_NEW (this->policy_manager_, TAO_Policy_Manager); ACE_NEW (this->default_policies_, TAO_Policy_Set (TAO_POLICY_ORB_SCOPE)); ACE_NEW (this->policy_current_, TAO_Policy_Current); #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ ACE_NEW (this->transport_sync_strategy_, TAO_Transport_Sync_Strategy); // Initialize the default request dispatcher. ACE_NEW (this->request_dispatcher_, TAO_Request_Dispatcher); } TAO_ORB_Core::~TAO_ORB_Core (void) { delete this->thread_lane_resources_manager_; delete this->flushing_strategy_; ACE_OS::free (this->orbid_); delete this->from_iso8859_; delete this->to_iso8859_; #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) delete this->eager_buffering_sync_strategy_; delete this->delayed_buffering_sync_strategy_; #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ #if (TAO_HAS_CORBA_MESSAGING == 1) CORBA::release (this->policy_manager_); delete this->default_policies_; CORBA::release (this->policy_current_); #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ delete this->transport_sync_strategy_; delete this->request_dispatcher_; } #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) CORBA::Policy_ptr TAO_ORB_Core::default_buffering_constraint (void) const { return this->default_policies_-> get_cached_policy (TAO_CACHED_POLICY_BUFFERING_CONSTRAINT); } #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ int TAO_ORB_Core::init (int &argc, char *argv[] ACE_ENV_ARG_DECL) { // Right now, this code expects to begin parsing in argv[1] rather // than argv[0]. I don't think that's wise. I think we need to // change that convention to argv[0] and let the initializing code // make any necessary shifts. // // Parse arguments to the ORB. Typically the ORB is passed // arguments straight from the command line, so we will simply pass // through them and respond to the ones we understand and ignore // those we don't. // // In some instances, we may actually build another vector of // arguments and stash it for use initializing other components such // as the RootPOA. // @@ GIOPLite should be an alternative ORB Messaging protocols, fredk // int giop_lite = 0; CORBA::Boolean use_ior = 1; int cdr_tradeoff = ACE_DEFAULT_CDR_MEMCPY_TRADEOFF; // The following things should be changed to use the ACE_Env_Value<> // template sometime. // Name Service port use for Multicast u_short ns_port = 0; // Trading Service port used for Multicast u_short ts_port = 0; // Implementation Repository Service port #. u_short ir_port = 0; // Buffer sizes for kernel socket buffers // @@ should be a default defined for each protocol implementation? // since we may have protocols loaded which use shared memory of // some form, fredk long rcv_sock_size = -1; long snd_sock_size = -1; // Use TCP_NODELAY. size_t nodelay = 1; // Use dotted decimal addresses // @@ This option will be treated as a suggestion to each loaded // protocol to use a character representation for the numeric // address, otherwise use a logical name. fredk #if (TAO_USE_DOTTED_DECIMAL_ADDRESSES == 1) int dotted_decimal_addresses = 1; #else int dotted_decimal_addresses = 0; #endif /* TAO_USE_DOTTED_DECIMAL_ADDRESSES */ #if defined (TAO_STD_PROFILE_COMPONENTS) int std_profile_components = 1; #else int std_profile_components = 0; #endif /* TAO_STD_PROFILE_COMPONENTS */ // Copy command line parameter not to use original. ACE_Argv_Type_Converter command_line(argc, argv); ACE_Arg_Shifter arg_shifter (command_line.get_argc(), command_line.get_TCHAR_argv()); while (arg_shifter.is_anything_left ()) { const ACE_TCHAR *current_arg = 0; //////////////////////////////////////////////////////////////// // begin with the 'parameterless' flags // //////////////////////////////////////////////////////////////// if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBDottedDecimalAddresses")))) { // Use dotted decimal addresses // @@ this should be renamed. See above comment. fredk dotted_decimal_addresses = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBEndpoint")))) { // Each "endpoint" is of the form: // // protocol://V.v@addr1,addr2,...,addrN // // or: // // protocol://addr1,addr2,...,addrN // // where "V.v" is an optional protocol version for each // addr. All endpoint strings should be of the above // form(s). // // Multiple sets of endpoint may be seperated by a semi-colon `;'. // For example: // // corbaloc:space:2001,1.2@odyssey:2010;uiop://foo,bar // // All endpoint strings should be of the above form(s). this->set_endpoint_helper (ACE_TEXT_ALWAYS_CHAR(current_arg) ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (-1); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBNameServicePort")))) { // Specify the port number for the NameService. // Unrelated to ORB Protocols, this is used for multicast. ns_port = (CORBA::UShort) ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBMulticastDiscoveryEndpoint")))) { // Specify mcast address:port@network_interface for the // Naming Service Multicast Discovery Protocol. // If there is no colon, its only the port no. // If there is a '@' also, it means that the network // interface name is specified. this->orb_params ()->mcast_discovery_endpoint (ACE_TEXT_ALWAYS_CHAR(current_arg)); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBNodelay")))) { // Use TCP_NODELAY or not. nodelay = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBTradingServicePort")))) { // Specify the port number for the NameService. ts_port = (CORBA::UShort) ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBImplRepoServicePort")))) { // Specify the multicast port number for the Implementation // Repository. ir_port = (CORBA::UShort) ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBRcvSock")))) { // @@ All protocol implementation may not use sockets, so // this can either be a generic I/O Buffer size or // Buffer info can be a per protocol specification, fredk // Specify the size of the socket's receive buffer rcv_sock_size = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBSndSock")))) { // @@ All protocol implementation may not use sockets, so // this can either be a generic I/O Buffer size or // Buffer info can be a per protocol specification, fredk // Specify the size of the socket's send buffer snd_sock_size = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBObjRefStyle")))) { // Specifies the style of printed objrefs: URL or IOR // // BEGIN COMMENTS FROM IIOP-1.4 On Win32, we should be // collecting information from the Registry such as what // ORBs are configured, specific configuration details like // whether they generate IOR or URL style stringified // objrefs and which addresses they listen to (e.g. allowing // multihomed hosts to implement firewalls), user-meaningful // orb names (they will normally indicate domains), and // more. // // On UNIX, we should collect that from some private config // file. // // Instead, this just treats the "internet" ORB name // specially and makes it always use URL-style stringified // objrefs, where the hostname and TCP port number are // explicit (and the whole objref is readable by mortals). // BEGIN COMMENTS FROM IIOP-1.4 const ACE_TCHAR *opt = current_arg; if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("URL")) == 0) use_ior = 0; arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBCollocationStrategy")))) { // Specify which collocation policy we want to use. const ACE_TCHAR *opt = current_arg; if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("thru_poa")) == 0) this->collocation_strategy_ = THRU_POA; else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("direct")) == 0) this->collocation_strategy_ = DIRECT; arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBCollocation")))) { // Specify whether we want to optimize against collocation // objects. Valid arguments are: "yes" and "no". // Default is yes. int yes_implies_global = 0; const ACE_TCHAR *opt = current_arg; if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("YES")) == 0) { yes_implies_global = 1; ACE_DEBUG ((LM_WARNING, ACE_LIB_TEXT ("WARNING: using '-ORBCollocation YES' is obsolete ") ACE_LIB_TEXT ("and implies '-ORBCollocation global'") ACE_LIB_TEXT (" Please use '-ORBCollocation global' instead.\n"))); } if (yes_implies_global || ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("global")) == 0) { this->opt_for_collocation_ = 1; this->use_global_collocation_ = 1; } else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("NO")) == 0) this->opt_for_collocation_ = 0; else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("per-orb")) == 0) { this->opt_for_collocation_ = 1; this->use_global_collocation_ = 0; } arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBGlobalCollocation")))) // Specify whether we want to use collocation across ORBs; // i.e. all the ORBs in the same address space use collocated // calls. { ACE_DEBUG ((LM_WARNING, ACE_LIB_TEXT ("WARNING: -ORBGlobalCollocation option is obsolete.") ACE_LIB_TEXT (" Please use '-ORBCollocation global/per-orb/no'") ACE_LIB_TEXT ("instead.\n"))); const ACE_TCHAR *opt = current_arg; if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("YES")) == 0) this->use_global_collocation_ = 1; else if (ACE_OS::strcasecmp (opt, ACE_LIB_TEXT("NO")) == 0) this->use_global_collocation_ = 0; arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBPreconnect")))) { #if 0 /* * * TODO: Needs to go. Leaving it around for things to * settle down. */ // Get a string which describes the connections we want to // cache up-front, thus reducing the latency of the first call. // // For example, specify -ORBpreconnect once for each // protocol: // // -ORBpreconnect iiop://tango:10015,watusi:10016 // -ORBpreconnect busX_iop://board1:0x07450000,board2,0x08450000 // // Or chain all possible endpoint designations together: // // -ORBpreconnect iiop://tango:10015,watusi:10016/; // busX_iop://board1:0x07450000,board2,0x08450000/ // // The old style command line only works for IIOP: // -ORBpreconnect tango:10015,tango:10015,watusi:10016 ACE_CString preconnections (ACE_TEXT_ALWAYS_CHAR(current_arg)); if (this->orb_params ()->preconnects (preconnections) != 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t)\n") ACE_LIB_TEXT ("Invalid preconnect(s)") ACE_LIB_TEXT ("specified:\n%s\n"), preconnections.c_str ())); ACE_THROW_RETURN (CORBA::BAD_PARAM ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, EINVAL), CORBA::COMPLETED_NO), -1); } #endif /*if 0*/ // validate_connection() supports the same functionality as // the -ORBPreconnect option, and more. Multiple // preconnections are also provided by validate_connection() // via "banded connections." ACE_ERROR ((LM_WARNING, ACE_LIB_TEXT ("(%P|%t) -ORBPreconnect is ") ACE_LIB_TEXT ("deprecated.\n") ACE_LIB_TEXT ("(%P|%t) Use validate_connection()") ACE_LIB_TEXT ("at run-time, instead.\n"))); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBCDRTradeoff")))) { cdr_tradeoff = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } // A new : mapping has been specified. This will be // used by the resolve_initial_references (). else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBInitRef")))) { const ACE_TCHAR *pos = ACE_OS::strchr (current_arg, '='); if (pos == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("Invalid ORBInitRef argument '%s'") ACE_LIB_TEXT ("format is ObjectID=IOR\n"), current_arg)); ACE_THROW_RETURN (CORBA::INTERNAL ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); } ACE_CString object_id (ACE_TEXT_ALWAYS_CHAR(current_arg), pos - current_arg); ACE_CString IOR (ACE_TEXT_ALWAYS_CHAR(pos + 1)); if (this->init_ref_map_.bind (object_id, IOR) != 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("Cannot store ORBInitRef ") ACE_LIB_TEXT ("argument '%s'\n"), current_arg)); ACE_THROW_RETURN (CORBA::INTERNAL ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); } arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBDefaultInitRef")))) { // Set the list of prefixes from -ORBDefaultInitRef. this->orb_params ()->default_init_ref (ACE_TEXT_ALWAYS_CHAR(current_arg)); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBStdProfileComponents")))) { std_profile_components = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBResources")))) { ACE_DEBUG ((LM_WARNING, ACE_LIB_TEXT ("This option has been deprecated\n"))); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBLogFile")))) { // redirect all ACE_DEBUG and ACE_ERROR output to a file // USAGE: -ORBLogFile // default: if is present = append // if is not present = create const ACE_TCHAR *file_name = current_arg; arg_shifter.consume_arg (); // would rather use ACE_OSTREAM_TYPE out here.. // but need ACE_FSTREAM_TYPE to call ->open(...) // and haven't found such a macro to rep FILE* and/or fstream* #if defined (ACE_LACKS_IOSTREAM_TOTALLY) FILE* output_stream = ACE_OS::fopen (file_name, ACE_LIB_TEXT("a")); ACE_LOG_MSG->msg_ostream (output_stream, 1); #else /* ! ACE_LACKS_IOSTREAM_TOTALLY */ ofstream* output_stream = 0; // // note: we are allocating dynamic memory here....but // I assume it will persist for the life of the program // ACE_NEW_THROW_EX (output_stream, ofstream (), CORBA::NO_MEMORY ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, ENOMEM), CORBA::COMPLETED_NO)); ACE_CHECK_RETURN (-1); output_stream->open (file_name, ios::out | ios::app); if (!output_stream->bad ()) { ACE_LOG_MSG->msg_ostream (output_stream, 1); } #endif /* ACE_LACKS_IOSTREAM_TOTALLY */ ACE_LOG_MSG->clr_flags (ACE_Log_Msg::STDERR | ACE_Log_Msg::LOGGER); ACE_LOG_MSG->set_flags (ACE_Log_Msg::OSTREAM); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBUseIMR")))) { // Use IR or not. this->use_implrepo_ = ACE_OS::atoi (current_arg); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBid")))) { // The ORBid is actually set in ORB_init(), and then passed // to the TAO_ORB_Core() constructor. However, in the case // where the ORBid third argument to ORB_init() is not zero, // any "-ORBid" arguments in the argv argument list are // supposed to be ignored, according to the CORBA spec. As // such, "-ORBid" must be removed from the argument list // since ORB_init() must remove all "-ORB" option // arguments. // We obtain a lock on the ORB table when setting the // ORBid. For this reason we should *not* set the ORBid // here. CORBA::ORB_init() does all of the proper locking // and setting. arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBServerId")))) { // The this->server_id_ is to uniquely identify a server to // an IMR. // Fill in later. this->server_id_.set(ACE_TEXT_ALWAYS_CHAR(current_arg)); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBListenEndpoints")))) { // This option is similar to the -ORBEndPoint option. May be // ORBEndpoint option will be deprecated in future. But, for // now, I (Priyanka) am leaving so that both options can be // used. this->set_endpoint_helper (ACE_TEXT_ALWAYS_CHAR(current_arg) ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (-1); arg_shifter.consume_arg (); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBNoProprietaryActivation")))) { // This option can be used to set to not use any proprietary // activation framework. The only TAO proprietary activation // framework is IMR. So, by setting this option in TAO, the // IMR shouldnt be used .. even if the ORBUseIMR option is // set. // Fill in later // @@ To do later: Priyanka. ACE_THROW_RETURN (CORBA::NO_IMPLEMENT (), -1); } else if ((current_arg = arg_shifter.get_the_parameter (ACE_LIB_TEXT("-ORBSingleReadOptimization")))) { this->orb_params ()->single_read_optimization (ACE_OS::atoi (current_arg)); arg_shifter.consume_arg (); } //////////////////////////////////////////////////////////////// // catch any unknown -ORB args // //////////////////////////////////////////////////////////////// else if (arg_shifter.cur_arg_strncasecmp (ACE_LIB_TEXT("-ORB")) != -1) { if (TAO_debug_level > 0) { current_arg = arg_shifter.get_current (); ACE_DEBUG ((LM_ERROR, ACE_LIB_TEXT ("ERROR: Unknown \"-ORB\" option ") ACE_LIB_TEXT ("<%s>.\n"), ((current_arg == 0) ? ACE_LIB_TEXT("") : current_arg))); } ACE_THROW_RETURN (CORBA::BAD_PARAM ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, EINVAL), CORBA::COMPLETED_NO), -1); } //////////////////////////////////////////////////////////////// // ok, we can't interpret this argument, move to next argument// //////////////////////////////////////////////////////////////// else // Any arguments that don't match are ignored so that the // caller can still use them. arg_shifter.ignore_arg (); } #if defined (SIGPIPE) && !defined (ACE_LACKS_UNIX_SIGNALS) // There's really no way to deal with this in a portable manner, so // we just have to suck it up and get preprocessor conditional and // ugly. // // Impractical to have each call to the ORB protect against the // implementation artifact of potential writes to dead connections, // as it'd be way expensive. Do it here; who cares about SIGPIPE in // these kinds of applications, anyway? (void) ACE_OS::signal (SIGPIPE, (ACE_SignalHandler) SIG_IGN); #endif /* SIGPIPE */ // Calling the open method here so that the svc.conf file is // opened and TAO_default_resource_factory::init () is called by the // time this method is called. this->parser_registry_.open (this); // Initialize the pointers to resources in the ORB Core instance, // e.g., reactor, connector, etc. Must do this after we open // services because we'll load the factory from there. TAO_Resource_Factory *trf = this->resource_factory (); if (trf == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("ORB Core unable to find a ") ACE_LIB_TEXT ("Resource Factory instance"))); ACE_THROW_RETURN (CORBA::INTERNAL ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); } // @@ ???? // Make sure the reactor is initialized... ACE_Reactor *reactor = this->reactor (); if (reactor == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("ORB Core unable to initialize reactor"))); ACE_THROW_RETURN (CORBA::INITIALIZE ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); } TAO_Server_Strategy_Factory *ssf = this->server_factory (); if (ssf == 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("ORB Core unable to find a ") ACE_LIB_TEXT ("Server Strategy Factory instance"))); ACE_THROW_RETURN (CORBA::INTERNAL ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); } ssf->open (this); // Obtain the timeout value for the thread-per-connection model this->thread_per_connection_use_timeout_ = ssf->thread_per_connection_timeout (this->thread_per_connection_timeout_); if (thread_per_connection_use_timeout_ == -1) { if (ACE_OS::strcasecmp (TAO_DEFAULT_THREAD_PER_CONNECTION_TIMEOUT, "INFINITE") == 0) { this->thread_per_connection_use_timeout_ = 0; } else { this->thread_per_connection_use_timeout_ = 1; int milliseconds = ACE_OS::atoi (TAO_DEFAULT_THREAD_PER_CONNECTION_TIMEOUT); // Use a temporary to obtain automatic normalization. this->thread_per_connection_timeout_ = ACE_Time_Value (0, 1000 * milliseconds); } } if (this->thread_per_connection_use_timeout_ == 0) { // Do not wait for the server threads because they may block // forever. this->tm_.wait_on_exit (0); } // Initialize the "ORB" pseudo-object now. CORBA::ORB_ptr temp_orb = CORBA::ORB::_nil (); ACE_NEW_THROW_EX (temp_orb, CORBA::ORB (this), CORBA::NO_MEMORY ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, ENOMEM), CORBA::COMPLETED_NO)); ACE_CHECK_RETURN (-1); this->orb_ = temp_orb; // This should probably move into the ORB Core someday rather then // being done at this level. this->orb_->_use_omg_ior_format (use_ior); // Set all kinds of orb parameters whose setting needed to be // deferred until after the service config entries had been // determined. this->orb_params ()->service_port (NAMESERVICE, ns_port); if (ns_port != 0) { char ns_port_char[256]; ACE_OS_String::itoa (ns_port, ns_port_char, 10); CORBA::String_var ns_port_ptr = CORBA::string_alloc (ACE_OS::strlen ((const char *) ns_port_char)); ns_port_ptr = (const char *) ns_port_char; const char prefix[] = "mcast://:"; CORBA::String_var def_init_ref = CORBA::string_alloc (sizeof (prefix) + ACE_OS::strlen (ns_port_ptr.in ()) + 2); ACE_OS::strcpy (def_init_ref, prefix); ACE_OS::strcat (def_init_ref, ns_port_ptr.in ()); ACE_OS::strcat (def_init_ref, "::"); this->orb_params ()->default_init_ref (def_init_ref.in ()); } this->orb_params ()->service_port (TRADINGSERVICE, ts_port); this->orb_params ()->service_port (IMPLREPOSERVICE, ir_port); this->orb_params ()->use_dotted_decimal_addresses (dotted_decimal_addresses); this->orb_params ()->nodelay (nodelay); if (rcv_sock_size >= 0) this->orb_params ()->sock_rcvbuf_size (rcv_sock_size); if (snd_sock_size >= 0) this->orb_params ()->sock_sndbuf_size (snd_sock_size); if (cdr_tradeoff >= 0) this->orb_params ()->cdr_memcpy_tradeoff (cdr_tradeoff); this->orb_params ()->std_profile_components (std_profile_components); // Set up the pluggable protocol infrastructure. First get a // pointer to the protocol factories set, then obtain pointers to // all factories loaded by the service configurator. // Load all protocol factories! if (trf->init_protocol_factories () == -1) ACE_THROW_RETURN (CORBA::INITIALIZE ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); // init the ORB core's pointer this->protocol_factories_ = trf->get_protocol_factories (); // Initialize the flushing strategy this->flushing_strategy_ = trf->create_flushing_strategy (); // Now that we have a complete list of available protocols and their // related factory objects, set default policies and initialize the // registries! // Set ORB-level policy defaults. TAO_Protocols_Hooks *tph = this->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (-1); int status = tph->set_default_policies (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (-1); if (status != 0) ACE_THROW_RETURN (CORBA::INITIALIZE ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO), -1); // Look for BiDirectional library here. If the user has svc.conf // file, load the library at this point. int ret = this->bidirectional_giop_init (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (-1); if (ret == -1) return -1; // As a last step perform initializations of the service callbacks this->services_callbacks_init (); // The ORB has been initialized, meaning that the ORB is no longer // in the shutdown state. this->has_shutdown_ = 0; return 0; } int TAO_ORB_Core::fini (void) { ACE_TRY_NEW_ENV { // Shutdown the ORB and block until the shutdown is complete. this->shutdown (1 ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY { ACE_CString message = "Exception caught in trying to shutdown "; message += this->orbid_; message += "\n"; ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, message.c_str ()); } ACE_ENDTRY; // Wait for any server threads, ignoring any failures. (void) this->thr_mgr ()->wait (); CORBA::release (this->implrepo_service_); CORBA::release (this->typecode_factory_); CORBA::release (this->dynany_factory_); CORBA::release (this->ior_manip_factory_); CORBA::release (this->ior_table_); if (TAO_debug_level >= 3) { ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("Destroying ORB <%s>\n"), this->orbid_)); } // Finalize lane resources. // // @@ Do not call this->thread_lane_resources_manager().finalize(). // this->thread_lane_manager_resources() can seg fault if the // factory method it invokes returns a zero pointer, which can // easily occur if the ORB is partially initialized due to a Service // Configurator initialization failure. Instead check if the // cached pointer is non-zero and then finalize. // // @todo Fix potential seg fault in // TAO_ORB_Core::thread_lane_resources_manager(). if (this->thread_lane_resources_manager_ != 0) this->thread_lane_resources_manager_->finalize (); (void) TAO_Internal::close_services (); #if 0 // @@todo: Need to go someday! if (this->message_block_dblock_allocator_) this->message_block_dblock_allocator_->remove (); delete this->message_block_dblock_allocator_; if (this-> message_block_buffer_allocator_) this->message_block_buffer_allocator_->remove (); delete this->message_block_buffer_allocator_; if (this->message_block_msgblock_allocator_) this->message_block_msgblock_allocator_->remove (); delete this->message_block_msgblock_allocator_; #endif /*if 0*/ delete this; return 0; } void TAO_ORB_Core::set_thread_lane_resources_manager_factory (const char *thread_lane_resources_manager_factory_name) { TAO_ORB_Core::thread_lane_resources_manager_factory_name_ = thread_lane_resources_manager_factory_name; } void TAO_ORB_Core::set_collocation_resolver (const char *collocation_resolver_name) { TAO_ORB_Core::collocation_resolver_name_ = collocation_resolver_name; } void TAO_ORB_Core::set_stub_factory (const char *stub_factory_name) { TAO_ORB_Core::stub_factory_name_ = stub_factory_name; } void TAO_ORB_Core::set_resource_factory (const char *resource_factory_name) { TAO_ORB_Core::resource_factory_name_ = resource_factory_name; } void TAO_ORB_Core::dynamic_adapter_name (const char *name) { TAO_ORB_Core::dynamic_adapter_name_ = name; } const char * TAO_ORB_Core::dynamic_adapter_name (void) { return TAO_ORB_Core::dynamic_adapter_name_.c_str(); } void TAO_ORB_Core::ifr_client_adapter_name (const char *name) { TAO_ORB_Core::ifr_client_adapter_name_ = name; } const char * TAO_ORB_Core::ifr_client_adapter_name (void) { return TAO_ORB_Core::ifr_client_adapter_name_.c_str(); } void TAO_ORB_Core::typecodefactory_adapter_name (const char *name) { TAO_ORB_Core::typecodefactory_adapter_name_ = name; } const char * TAO_ORB_Core::typecodefactory_adapter_name (void) { return TAO_ORB_Core::typecodefactory_adapter_name_.c_str(); } TAO_Resource_Factory * TAO_ORB_Core::resource_factory (void) { // Check if there is a cached reference. if (this->resource_factory_ != 0) return this->resource_factory_; // Look in the service repository for an instance. this->resource_factory_ = ACE_Dynamic_Service::instance (TAO_ORB_Core::resource_factory_name_.c_str()); return this->resource_factory_; } TAO_Thread_Lane_Resources_Manager & TAO_ORB_Core::thread_lane_resources_manager (void) { // Check if there is a cached reference. if (this->thread_lane_resources_manager_ != 0) return *this->thread_lane_resources_manager_; // If not, lookup the corresponding factory and ask it to make one. TAO_Thread_Lane_Resources_Manager_Factory *factory = ACE_Dynamic_Service::instance (TAO_ORB_Core::thread_lane_resources_manager_factory_name_.c_str()); this->thread_lane_resources_manager_ = factory->create_thread_lane_resources_manager (*this); return *this->thread_lane_resources_manager_; } TAO_Collocation_Resolver & TAO_ORB_Core::collocation_resolver (void) { // Check if there is a cached reference. if (this->collocation_resolver_ != 0) return *this->collocation_resolver_; // If not, lookup it up. this->collocation_resolver_ = ACE_Dynamic_Service::instance (TAO_ORB_Core::collocation_resolver_name_.c_str()); return *this->collocation_resolver_; } TAO_Stub_Factory * TAO_ORB_Core::stub_factory (void) { // Check if there is a cached reference. if (this->stub_factory_ != 0) return this->stub_factory_; // If not, look in the service repository for an instance. this->stub_factory_ = ACE_Dynamic_Service::instance (TAO_ORB_Core::stub_factory_name_.c_str()); return this->stub_factory_; } void TAO_ORB_Core::set_poa_factory (const char *poa_factory_name, const char *poa_factory_directive) { TAO_ORB_Core::poa_factory_name_ = poa_factory_name; TAO_ORB_Core::poa_factory_directive_ = poa_factory_directive; } void TAO_ORB_Core::set_endpoint_selector_factory (const char *endpoint_selector_factory_name) { TAO_ORB_Core::endpoint_selector_factory_name_ = endpoint_selector_factory_name; } TAO_Endpoint_Selector_Factory * TAO_ORB_Core::endpoint_selector_factory (void) { // Check if there is a cached reference. if (this->endpoint_selector_factory_ != 0) return this->endpoint_selector_factory_; // If not, look in the service repository for an instance. this->endpoint_selector_factory_ = ACE_Dynamic_Service::instance (TAO_ORB_Core::endpoint_selector_factory_name_.c_str()); return this->endpoint_selector_factory_; } void TAO_ORB_Core::set_protocols_hooks (const char *protocols_hooks) { TAO_ORB_Core::protocols_hooks_name_ = protocols_hooks; } TAO_Protocols_Hooks * TAO_ORB_Core::get_protocols_hooks (ACE_ENV_SINGLE_ARG_DECL) { // Check if there is a cached reference. if (this->protocols_hooks_ != 0) return this->protocols_hooks_; // If not, look in the service repository for an instance. this->protocols_hooks_ = ACE_Dynamic_Service::instance (TAO_ORB_Core::protocols_hooks_name_.c_str()); // Initialize the protocols hooks instance. this->protocols_hooks_->init_hooks (this ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); return this->protocols_hooks_; } int TAO_ORB_Core::bidirectional_giop_init (ACE_ENV_SINGLE_ARG_DECL) { if (this->bidir_adapter_ == 0) { this->bidir_adapter_ = ACE_Dynamic_Service::instance ("BiDirGIOP_Loader"); } if (this->bidir_adapter_) return this->bidir_adapter_->activate (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER); else return 0; } void TAO_ORB_Core::services_callbacks_init (void) { // We (should) know what are the services that would need // callbacks. So, what we do is go through the Service Configurator // list for looking at the services that we want to load. this->ft_service_.init (this); // @@ Other service callbacks can be added here } int TAO_ORB_Core::service_raise_comm_failure (TAO_GIOP_Invocation *invoke, TAO_Profile *profile ACE_ENV_ARG_DECL) { if (this->ft_service_.service_callback ()) { return this->ft_service_.service_callback ()-> raise_comm_failure (invoke, profile ACE_ENV_ARG_PARAMETER); } invoke->close_connection (); ACE_THROW_RETURN (CORBA::COMM_FAILURE ( CORBA_SystemException::_tao_minor_code ( TAO_INVOCATION_RECV_REQUEST_MINOR_CODE, errno), CORBA::COMPLETED_MAYBE), TAO_INVOKE_EXCEPTION); } int TAO_ORB_Core::service_raise_transient_failure (TAO_GIOP_Invocation *invoke, TAO_Profile *profile ACE_ENV_ARG_DECL) { if (this->ft_service_.service_callback ()) { return this->ft_service_.service_callback ()-> raise_transient_failure (invoke, profile ACE_ENV_ARG_PARAMETER); } ACE_THROW_RETURN (CORBA::TRANSIENT ( CORBA_SystemException::_tao_minor_code ( TAO_INVOCATION_SEND_REQUEST_MINOR_CODE, errno), CORBA::COMPLETED_MAYBE), TAO_INVOKE_EXCEPTION); } void TAO_ORB_Core::service_context_list ( TAO_Stub *stub, TAO_Service_Context &service_context, CORBA::Boolean restart ACE_ENV_ARG_DECL) { // @@ We look at the services if they are loaded. But if more // services offer this feature we may want to keep expanding the // 'if' conditions with a check for whether a service returned a // valid Policy object. if (this->ft_service_.service_callback ()) { this->ft_service_.service_callback ()->service_context_list (stub, service_context.service_info (), restart ACE_ENV_ARG_PARAMETER); ACE_CHECK; } this->protocols_hooks_->rt_service_context (stub, service_context, restart ACE_ENV_ARG_PARAMETER); ACE_CHECK; } TAO_Client_Strategy_Factory * TAO_ORB_Core::client_factory (void) { if (this->client_factory_ == 0) { // Look in the service repository for an instance. this->client_factory_ = ACE_Dynamic_Service::instance ("Client_Strategy_Factory"); } return this->client_factory_; } TAO_Server_Strategy_Factory * TAO_ORB_Core::server_factory (void) { if (this->server_factory_ == 0) { // Look in the service repository for an instance. this->server_factory_ = ACE_Dynamic_Service::instance ("Server_Strategy_Factory"); } return this->server_factory_; } int TAO_ORB_Core::inherit_from_parent_thread ( TAO_ORB_Core_TSS_Resources *tss_resources) { // Inherit properties/objects used in ORB_Core from the // parent thread. Stuff inherited here must already exist // in the "parent" orbcore. // This is used in the thread-per-connection concurrency model where // each ORB spawned thread must use the resources of the spawning // thread... if (tss_resources == 0) return -1; return 0; } CORBA::Object_ptr TAO_ORB_Core::root_poa (ACE_ENV_SINGLE_ARG_DECL) { if (!CORBA::is_nil (this->root_poa_.in ())) return CORBA::Object::_duplicate (this->root_poa_.in ()); TAO_Adapter_Factory *factory = ACE_Dynamic_Service::instance (TAO_ORB_Core::poa_factory_name_.c_str()); if (factory == 0) { ACE_Service_Config::process_directive (ACE_TEXT_CHAR_TO_TCHAR(TAO_ORB_Core::poa_factory_directive_.c_str())); factory = ACE_Dynamic_Service::instance (TAO_ORB_Core::poa_factory_name_.c_str()); } if (factory == 0) { // It really failed, raise an exception! ACE_THROW_RETURN (CORBA::ORB::InvalidName (), CORBA::Object::_nil ()); } // @@ Not exception safe TAO_Adapter *poa_adapter = factory->create (this); poa_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); this->root_poa_ = poa_adapter->root (); this->adapter_registry_.insert (poa_adapter ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (CORBA::Object::_nil ()); return CORBA::Object::_duplicate (this->root_poa_.in ()); } TAO_Adapter * TAO_ORB_Core::poa_adapter (void) { if (this->poa_adapter_ == 0) { ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->poa_adapter_ == 0) { this->poa_adapter_ = this->adapter_registry_.find_adapter ("RootPOA"); } } return this->poa_adapter_; } TAO_Stub * TAO_ORB_Core::create_stub (const char *repository_id, const TAO_MProfile &profiles ACE_ENV_ARG_DECL) { TAO_Stub *retval = this->stub_factory ()->create_stub (repository_id, profiles, this ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN(0); return retval; } void TAO_ORB_Core::request_dispatcher (TAO_Request_Dispatcher *request_dispatcher) { // Assume ownership of the request dispatcher. TAO_Request_Dispatcher *tmp = this->request_dispatcher_; this->request_dispatcher_ = request_dispatcher; delete tmp; } TAO_Stub * TAO_ORB_Core::create_stub_object (TAO_MProfile &mprofile, const char *type_id, CORBA::PolicyList *policy_list ACE_ENV_ARG_DECL) { // Add the Polices contained in "policy_list" to each profile so // that those policies will be exposed to the client in the IOR. In // particular each CORBA::Policy has to be converted in to // Messaging::PolicyValue, and then all the Messaging::PolicyValue // should be embedded inside a Messaging::PolicyValueSeq which // became in turns the "body" of the IOP::TaggedComponent. This // conversion is a responsability of the CORBA::Profile class. (See // orbos\98-05-05.pdf Section 5.4) if (policy_list->length () != 0) { TAO_Profile * profile; for (CORBA::ULong i = 0; i < mprofile.profile_count (); ++i) { // Get the ith profile profile = mprofile.get_profile (i); profile->policies (policy_list TAO_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (0); } } /// Initialize a TAO_Stub object with the mprofile thats passed. TAO_Stub *stub = this->create_stub (type_id, mprofile ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (stub); stub->base_profiles ().policy_list (policy_list); return stub; } void TAO_ORB_Core::load_policy_validators (TAO_Policy_Validator &validator) { // Call the BiDir library if it has been loaded if (this->bidir_adapter_) this->bidir_adapter_->load_policy_validators (validator); } CORBA::Object_ptr TAO_ORB_Core::create_object (TAO_Stub *stub) { // @@ What about forwarding. With this approach we are never forwarded // when we use collocation! const TAO_MProfile &mprofile = stub->base_profiles (); { // @@ Ossama: maybe we need another lock for the table, to // reduce contention on the Static_Object_Lock below, if so // then we need to use that lock in the ORB_init() function. ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance (), 0)); TAO_ORB_Table *table = TAO_ORB_Table::instance (); TAO_ORB_Table::Iterator end = table->end (); for (TAO_ORB_Table::Iterator i = table->begin (); i != end; ++i) { TAO_ORB_Core *other_core = (*i).int_id_; CORBA::Object_ptr x = this->create_collocated_object (stub, other_core, mprofile); if (x != 0) return x; } } // @@ We should thow CORBA::NO_MEMORY in platforms with exceptions, // but we are stuck in platforms without exceptions! CORBA::Object_ptr x; // The constructor sets the proxy broker as the // Remote one. ACE_NEW_RETURN (x, CORBA_Object (stub, 0), 0); return x; } CORBA::Object_ptr TAO_ORB_Core::create_collocated_object (TAO_Stub *stub, TAO_ORB_Core *orb_core, const TAO_MProfile &mprofile) { if (!orb_core->optimize_collocation_objects ()) return 0; if (!orb_core->use_global_collocation () && orb_core != this) return 0; if (!orb_core->is_collocated (mprofile)) return 0; // OK, the target ORB and the mprofile match, use the Adapter // Registry of each ORB to find the right one. return orb_core->adapter_registry ()->create_collocated_object (stub, mprofile); } int TAO_ORB_Core::is_collocated (const TAO_MProfile& mprofile) { // @@ Lots of issues arise when dealing with collocation. What about // forwarding or what if this is a multi-profile IOR where the order is // significant and only one of the profiles is collocated. For example // when using a multiple servers for fault tolerance. For now, we just // look through all profiles and if any are colocated then we assume // the object is collocated. // @@ Note, if collocated we can not be forwarded! // Also, acceptor_registry_->is_collocated (...) will check the // address (ORB Host) but not the object_key. This should be checked // also. return this->thread_lane_resources_manager ().is_collocated (mprofile); } // **************************************************************** TAO_Leader_Follower & TAO_ORB_Core::leader_follower (void) { return this->lane_resources ().leader_follower (); } TAO_LF_Strategy & TAO_ORB_Core::lf_strategy (void) { return this->thread_lane_resources_manager ().lf_strategy (); } int TAO_ORB_Core::run (ACE_Time_Value *tv, int perform_work ACE_ENV_ARG_DECL_NOT_USED) { if (TAO_debug_level >= 3) ACE_DEBUG ((LM_DEBUG, "TAO (%P|%t) - ORB_Core::run, " "start [%s]\n", perform_work?"perform_work":"run")); // Fetch the Reactor ACE_Reactor *r = this->reactor (); int result = 1; // 1 to detect that nothing went wrong // Loop handling client requests until the ORB is shutdown. // We could use the leader-follower lock to check for the state // if this variable or use the lock in // the server strategy factory. // We don't need to do this because we use the Reactor // mechanisms to shutdown in a thread-safe way. while (this->has_shutdown () == 0) { // Every time we perform an interation we have to become the // leader again, because it is possible that a client has // acquired the leader role... TAO_Leader_Follower &leader_follower = this->leader_follower (); TAO_LF_Strategy &lf_strategy = this->lf_strategy (); TAO_LF_Event_Loop_Thread_Helper helper (leader_follower, lf_strategy, tv); int result = helper.event_loop_return (); if (result != 0) { if (errno == ETIME) return 0; else return result; } // Set the owning thread of the Reactor to the one which we're // currently in. This is necessary b/c it's possible that the // application is calling us from a thread other than that in which // the Reactor's CTOR (which sets the owner) was called. // // We need to do this on every iteration because the reactor may be // acquired by one of the client threads in the LF waiting // strategy r->owner (ACE_Thread::self ()); if (TAO_debug_level >= 3) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, " "calling handle_events()\n"))); result = r->handle_events (tv); if (TAO_debug_level >= 3) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, " "handle_events() returns %d\n"), result)); if (result == -1) { // An error, terminate the loop break; } if (result == 0 && tv != 0 && *tv == ACE_Time_Value::zero) { // A timeout, terminate the loop... break; } if (perform_work) { // This is running on behalf of a perform_work() call, // The loop should run only once. break; } // Otherwise just continue.. } if (TAO_debug_level >= 3) ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("TAO (%P|%t) - ORB_Core::run, ") ACE_LIB_TEXT ("ends with result = %d\n"), result)); return result; } void TAO_ORB_Core::shutdown (CORBA::Boolean wait_for_completion ACE_ENV_ARG_DECL) { ACE_GUARD (TAO_SYNCH_MUTEX, monitor, this->lock_); if (this->has_shutdown () == 0) { this->adapter_registry_.check_close (wait_for_completion ACE_ENV_ARG_PARAMETER); ACE_CHECK; this->adapter_registry_.close (wait_for_completion ACE_ENV_ARG_PARAMETER); ACE_CHECK; // Set the shutdown flag this->has_shutdown_ = 1; // Shutdown reactor. this->thread_lane_resources_manager ().shutdown_reactor (); // Grab the thread manager ACE_Thread_Manager *tm = this->thr_mgr (); // Try to cancel all the threads in the ORB. tm->cancel_all (); // If is set, wait for all threads to exit. if (wait_for_completion != 0) tm->wait (); // Invoke Interceptor::destroy() on all registered interceptors. this->destroy_interceptors (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; // Explicitly destroy the object reference table since it // contains references to objects, which themselves may contain // reference to this ORB. this->object_ref_table_.destroy (); #if (TAO_HAS_INTERCEPTORS == 1) this->pi_current_ = 0; // For the sake of consistency. #endif /* TAO_HAS_INTERCEPTORS == 1 */ } } void TAO_ORB_Core::destroy (ACE_ENV_SINGLE_ARG_DECL) { // // All destroy() should do is (a) call shutdown() and (b) unbind() // from the ORB table. Nothing else should really be added to this // method. Everything else should go to the shutdown() method. // Remember when the ORB Core is finally removed from the ORB table, // the reference count goes to zero and fini() is called. fini() // calls shutdown() and does not call destroy() since destroy() will // try to unbind from the ORB table again. Additional code should // not be added to destroy() since there is no guarantee that // orb->destroy() will ever be called by the user. Since TAO // guarantees that shutdown() will be called, all cleanup code // should go there. // // Shutdown the ORB and block until the shutdown is complete. this->shutdown (1 ACE_ENV_ARG_PARAMETER); ACE_CHECK; // Now remove it from the ORB table so that it's ORBid may be // reused. { ACE_MT (ACE_GUARD (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance ())); TAO_ORB_Table::instance ()->unbind (this->orbid_); } } void TAO_ORB_Core::destroy_interceptors (ACE_ENV_SINGLE_ARG_DECL) { size_t len = 0; // The length of the interceptor array. size_t ilen = 0; // The incremental length of the interceptor array. #if TAO_HAS_INTERCEPTORS == 1 TAO_ClientRequestInterceptor_List::TYPE &client_interceptors = this->client_request_interceptors_.interceptors (); len = client_interceptors.size (); ilen = len; for (size_t i = 0; i < len; ++i) { // Destroy the interceptors in reverse order in case the array // list is only partially destroyed and another invocation // occurs afterwards. --ilen; client_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; // Since Interceptor::destroy() can throw an exception, decrease // the size of the interceptor array incrementally since some // interceptors may not have been destroyed yet. Note that this // size reduction is fast since no memory is actually // deallocated. client_interceptors.size (ilen); } TAO_ServerRequestInterceptor_List::TYPE &server_interceptors = this->server_request_interceptors_.interceptors (); len = server_interceptors.size (); ilen = len; for (size_t j = 0; j < len; ++j) { // Destroy the interceptors in reverse order in case the array // list is only partially destroyed and another invocation // occurs afterwards. --ilen; server_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; // Since Interceptor::destroy() can throw an exception, decrease // the size of the interceptor array incrementally since some // interceptors may not have been destroyed yet. Note that this // size reduction is fast since no memory is actually // deallocated. server_interceptors.size (ilen); } #endif /* TAO_HAS_INTERCEPTORS == 1 */ TAO_IORInterceptor_List::TYPE &ior_interceptors = this->ior_interceptors_.interceptors (); len = ior_interceptors.size (); ilen = len; for (size_t k = 0; k < len; ++k) { // Destroy the interceptors in reverse order in case the array // list is only partially destroyed and another invocation // occurs afterwards. --ilen; ior_interceptors[ilen]->destroy (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; // Since Interceptor::destroy() can throw an exception, decrease // the size of the interceptor array incrementally since some // interceptors may not have been destroyed yet. Note that this // size reduction is fast since no memory is actually // deallocated. ior_interceptors.size (ilen); } } TAO_Thread_Lane_Resources & TAO_ORB_Core::lane_resources (void) { return this->thread_lane_resources_manager ().lane_resources (); } void TAO_ORB_Core::resolve_typecodefactory_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = ACE_Dynamic_Service::instance ("TypeCodeFactory_Loader"); if (loader == 0) { ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic TypeCodeFactory Service_Object *") ACE_LIB_TEXT("TAO_TypeCodeFactory:_make_TAO_TypeCodeFactory_Loader()")); loader = ACE_Dynamic_Service::instance ("TypeCodeFactory_Loader"); if (loader == 0) ACE_THROW (CORBA::ORB::InvalidName ()); } this->typecode_factory_ = loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER); } void TAO_ORB_Core::resolve_dynanyfactory_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = ACE_Dynamic_Service::instance ("DynamicAny_Loader"); if (loader == 0) { ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic DynamicAny_Loader Service_Object *") ACE_LIB_TEXT("TAO_DynamicAny:_make_TAO_DynamicAny_Loader()")); loader = ACE_Dynamic_Service::instance ("DynamicAny_Loader"); if (loader == 0) ACE_THROW (CORBA::ORB::InvalidName ()); } this->dynany_factory_ = loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER); } void TAO_ORB_Core::resolve_iormanipulation_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Object_Loader *loader = ACE_Dynamic_Service::instance ("IORManip_Loader"); if (loader == 0) { ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic IORManip_Loader Service_Object *") ACE_LIB_TEXT("TAO_IORManip:_make_TAO_IORManip_Loader()")); loader = ACE_Dynamic_Service::instance ("IORManip_Loader"); if (loader == 0) ACE_THROW (CORBA::ORB::InvalidName ()); } this->ior_manip_factory_ = loader->create_object (this->orb_.in (), 0, 0 ACE_ENV_ARG_PARAMETER); } void TAO_ORB_Core::resolve_ior_table_i (ACE_ENV_SINGLE_ARG_DECL) { TAO_Adapter_Factory *factory = ACE_Dynamic_Service::instance ("TAO_IORTable"); if (factory == 0) { ACE_Service_Config::process_directive (ACE_LIB_TEXT("dynamic TAO_IORTable Service_Object *") ACE_LIB_TEXT("TAO_IORTable:_make_TAO_Table_Adapter_Factory()")); factory = ACE_Dynamic_Service::instance ("TAO_IORTable"); } if (factory == 0) ACE_THROW (CORBA::ORB::InvalidName ()); // @@ Not exception safe TAO_Adapter *iortable_adapter = factory->create (this); this->adapter_registry_.insert (iortable_adapter ACE_ENV_ARG_PARAMETER); ACE_CHECK; iortable_adapter->open (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK; this->ior_table_ = iortable_adapter->root (); } int TAO_ORB_Core::set_endpoint_helper (const char *current_arg ACE_ENV_ARG_DECL) { ACE_CString endpts (current_arg); if (this->orb_params ()->endpoints (endpts) != 0) { ACE_ERROR ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t)\n") ACE_LIB_TEXT ("Invalid endpoint(s) specified:\n%s\n"), ACE_TEXT_CHAR_TO_TCHAR(endpts.c_str ()))); ACE_THROW_RETURN (CORBA::BAD_PARAM ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, EINVAL), CORBA::COMPLETED_NO), -1); } return 0; } CORBA::Object_ptr TAO_ORB_Core::resolve_rir (const char *name ACE_ENV_ARG_DECL) { // Get the table of initial references specified through // -ORBInitRef. ACE_CString ior; ACE_CString object_id ((const char *) name); // Get the list of initial reference prefixes specified through // -ORBDefaultInitRef. CORBA::String_var default_init_ref = this->orb_params ()->default_init_ref (); // Check if a DefaultInitRef was specified. if (ACE_OS::strlen (default_init_ref.in ()) != 0) { static const char corbaloc_prefix[] = "corbaloc:"; static const char mcast_prefix[] = "mcast:"; char object_key_delimiter = 0; ACE_CString list_of_profiles (default_init_ref.in ()); // Check if the protocol is corbaloc: or mcast:. // If it is, set the object_key_delimiter. if ((ACE_OS::strncmp (default_init_ref.in (), corbaloc_prefix, sizeof corbaloc_prefix -1) == 0) || (ACE_OS::strncmp (default_init_ref.in (), mcast_prefix, sizeof mcast_prefix -1) == 0)) { object_key_delimiter = '/'; } else { TAO_Connector_Registry *conn_reg = this->connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); // Obtain the appropriate object key delimiter for the // specified protocol. object_key_delimiter = conn_reg->object_key_delimiter (list_of_profiles.c_str ()); } // Make sure that the default initial reference doesn't end // with the object key delimiter character. if (list_of_profiles[list_of_profiles.length() - 1] != object_key_delimiter) list_of_profiles += ACE_CString (object_key_delimiter); list_of_profiles += object_id; return this->orb ()->string_to_object (list_of_profiles.c_str () ACE_ENV_ARG_PARAMETER); } return CORBA::Object::_nil (); } CORBA::ORB::ObjectIdList_ptr TAO_ORB_Core::list_initial_references (ACE_ENV_SINGLE_ARG_DECL) { // Unsupported initial services should NOT be included in the below list! const char *initial_services[] = { TAO_LIST_OF_INITIAL_SERVICES }; // Make sure the "terminating" zero is the last array element so // that there is a stop condition when iterating through the list. const size_t initial_services_size = sizeof (initial_services) / sizeof (initial_services[0]); const size_t total_size = initial_services_size + this->init_ref_map_.current_size () + this->object_ref_table_.current_size (); CORBA::ORB::ObjectIdList_ptr tmp = 0; ACE_NEW_THROW_EX (tmp, CORBA_ORB_ObjectIdList (total_size), CORBA::NO_MEMORY ()); ACE_CHECK_RETURN (0); CORBA::ORB::ObjectIdList_var list = tmp; list->length (total_size); CORBA::ULong index = 0; // Index for ObjectIdList members. // Iterate over the registered initial references. for (index = 0; index < initial_services_size; ++index) list[index] = initial_services[index]; // Now iterate over the initial references created by the user and // add them to the sequence. // References registered via // ORBInitInfo::register_initial_reference(). TAO_Object_Ref_Table::Iterator obj_ref_end = this->object_ref_table_.end (); for (TAO_Object_Ref_Table::Iterator i = this->object_ref_table_.begin (); i != obj_ref_end; ++i, ++index) list[index] = CORBA::string_dup ((*i).ext_id_); // References registered via INS. InitRefMap::iterator end = this->init_ref_map_.end (); for (InitRefMap::iterator j = this-> init_ref_map_.begin (); j != end; ++j, ++index) list[index] = (*j).ext_id_.c_str (); return list._retn (); } // **************************************************************** ACE_Allocator* TAO_ORB_Core::input_cdr_dblock_allocator (void) { if (this->orb_resources_.input_cdr_dblock_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->orb_resources_.input_cdr_dblock_allocator_ == 0) this->orb_resources_.input_cdr_dblock_allocator_ = this->resource_factory ()->input_cdr_dblock_allocator (); } return this->orb_resources_.input_cdr_dblock_allocator_; } ACE_Allocator* TAO_ORB_Core::input_cdr_buffer_allocator (void) { if (this->orb_resources_.input_cdr_buffer_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->orb_resources_.input_cdr_buffer_allocator_ == 0) this->orb_resources_.input_cdr_buffer_allocator_ = this->resource_factory ()->input_cdr_buffer_allocator (); } return this->orb_resources_.input_cdr_buffer_allocator_; } ACE_Allocator* TAO_ORB_Core::input_cdr_msgblock_allocator (void) { if (this->orb_resources_.input_cdr_msgblock_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->orb_resources_.input_cdr_msgblock_allocator_ == 0) this->orb_resources_.input_cdr_msgblock_allocator_ = this->resource_factory ()->input_cdr_msgblock_allocator (); } return this->orb_resources_.input_cdr_msgblock_allocator_; } ACE_Allocator* TAO_ORB_Core::output_cdr_dblock_allocator (void) { // Allocating memory here confuses purify a bit. We do delete this // memory when TSS delete TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss == 0) ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("TAO_ORB_Core::output_cdr_dblock_allocator (); ") ACE_LIB_TEXT ("no more TSS keys")), 0); if (tss->output_cdr_dblock_allocator_ == 0) tss->output_cdr_dblock_allocator_ = this->resource_factory ()->output_cdr_dblock_allocator (); return tss->output_cdr_dblock_allocator_; } ACE_Allocator* TAO_ORB_Core::output_cdr_buffer_allocator (void) { TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss == 0) ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("TAO_ORB_Core::input_cdr_buffer_allocator (); ") ACE_LIB_TEXT ("no more TSS keys")), 0); if (tss->output_cdr_buffer_allocator_ == 0) tss->output_cdr_buffer_allocator_ = this->resource_factory ()->output_cdr_buffer_allocator (); return tss->output_cdr_buffer_allocator_; } ACE_Allocator* TAO_ORB_Core::output_cdr_msgblock_allocator (void) { TAO_ORB_Core_TSS_Resources *tss = this->get_tss_resources (); if (tss == 0) ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("(%P|%t) %p\n"), ACE_LIB_TEXT ("TAO_ORB_Core::output_cdr_msgblock_allocator (); ") ACE_LIB_TEXT ("no more TSS keys")), 0); if (tss->output_cdr_msgblock_allocator_ == 0) tss->output_cdr_msgblock_allocator_ = this->resource_factory ()->output_cdr_msgblock_allocator (); return tss->output_cdr_msgblock_allocator_; } ACE_Allocator* TAO_ORB_Core::transport_message_buffer_allocator (void) { if (this->orb_resources_.transport_message_buffer_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->orb_resources_.transport_message_buffer_allocator_ == 0) this->orb_resources_.transport_message_buffer_allocator_ = this->resource_factory ()->input_cdr_dblock_allocator (); } return this->orb_resources_.transport_message_buffer_allocator_; } ACE_Data_Block* TAO_ORB_Core::create_input_cdr_data_block (size_t size) { ACE_Allocator *dblock_allocator; ACE_Allocator *buffer_allocator; dblock_allocator = this->input_cdr_dblock_allocator (); buffer_allocator = this->input_cdr_buffer_allocator (); ACE_Lock* lock_strategy = 0; if (this->resource_factory ()->use_locked_data_blocks ()) { lock_strategy = &this->data_block_lock_; } return this->create_data_block_i (size, buffer_allocator, dblock_allocator, lock_strategy); } #if 0 // @@todo: This will go off after sometime. We may no longer need // this, since we could as well use the input_cdr* for use. ACE_Data_Block * TAO_ORB_Core::data_block_for_message_block (size_t size) { ACE_Allocator *dblock_allocator; ACE_Allocator *buffer_allocator; dblock_allocator = this->message_block_dblock_allocator (); buffer_allocator = this->message_block_buffer_allocator (); ACE_Lock* lock_strategy = 0; if (this->resource_factory ()->use_locked_data_blocks ()) { lock_strategy = &this->data_block_lock_; } return this->create_data_block_i (size, buffer_allocator, dblock_allocator, lock_strategy); } ACE_Allocator* TAO_ORB_Core::message_block_dblock_allocator (void) { if (this->message_block_dblock_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->message_block_dblock_allocator_ == 0) this->message_block_dblock_allocator_ = this->resource_factory ()->input_cdr_dblock_allocator (); } return this->message_block_dblock_allocator_; } ACE_Allocator* TAO_ORB_Core::message_block_buffer_allocator (void) { if (this->message_block_buffer_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->message_block_buffer_allocator_ == 0) this->message_block_buffer_allocator_ = this->resource_factory ()->input_cdr_buffer_allocator (); } return this->message_block_buffer_allocator_; } ACE_Allocator* TAO_ORB_Core::message_block_msgblock_allocator (void) { if (this->message_block_msgblock_allocator_ == 0) { // Double checked locking ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, 0); if (this->message_block_msgblock_allocator_ == 0) this->message_block_msgblock_allocator_ = this->resource_factory ()->input_cdr_buffer_allocator (); } return this->message_block_msgblock_allocator_; } #endif /*if 0*/ ACE_Data_Block * TAO_ORB_Core::create_data_block_i (size_t size, ACE_Allocator *buffer_allocator, ACE_Allocator *dblock_allocator, ACE_Lock *lock_strategy) { ACE_Data_Block *nb = 0; ACE_NEW_MALLOC_RETURN ( nb, ACE_static_cast(ACE_Data_Block*, dblock_allocator->malloc (sizeof (ACE_Data_Block))), ACE_Data_Block (size, ACE_Message_Block::MB_DATA, 0, buffer_allocator, lock_strategy, 0, dblock_allocator), 0); return nb; } TAO_Connector_Registry * TAO_ORB_Core::connector_registry (ACE_ENV_SINGLE_ARG_DECL) { TAO_Connector_Registry *conn = this->lane_resources ().connector_registry (ACE_ENV_SINGLE_ARG_PARAMETER); ACE_CHECK_RETURN (0); return conn; } ACE_Reactor * TAO_ORB_Core::reactor (void) { return this->leader_follower ().reactor (); } CORBA::Object_ptr TAO_ORB_Core::implrepo_service (void) { if (!this->use_implrepo_) return CORBA::Object::_nil (); if (CORBA::is_nil (this->implrepo_service_)) { ACE_TRY_NEW_ENV { CORBA::Object_var temp = this->orb_->resolve_initial_references ("ImplRepoService" ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, ace_mon, this->lock_, CORBA::Object::_nil ()); // @@ Worry about assigning a different IOR? (brunsch) this->implrepo_service_ = temp._retn (); } ACE_CATCHANY { // Just make sure that we have a null pointer. Ignore the exception anyway. this->implrepo_service_ = CORBA::Object::_nil (); } ACE_ENDTRY; } return CORBA::Object::_duplicate (this->implrepo_service_); } void TAO_ORB_Core::call_sync_scope_hook (TAO_Stub *stub, int &has_synchronization, Messaging::SyncScope &scope) { if (TAO_ORB_Core::sync_scope_hook_ == 0) { has_synchronization = 0; return; } (*TAO_ORB_Core::sync_scope_hook_) (this, stub, has_synchronization, scope); } TAO_Sync_Strategy & TAO_ORB_Core::get_sync_strategy (TAO_Stub *, Messaging::SyncScope &scope) { if (scope == Messaging::SYNC_WITH_TRANSPORT || scope == Messaging::SYNC_WITH_SERVER || scope == Messaging::SYNC_WITH_TARGET) return this->transport_sync_strategy (); #if (TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1) if (scope == Messaging::SYNC_NONE || scope == TAO::SYNC_EAGER_BUFFERING) return this->eager_buffering_sync_strategy (); if (scope == TAO::SYNC_DELAYED_BUFFERING) return this->delayed_buffering_sync_strategy (); #endif /* TAO_HAS_BUFFERING_CONSTRAINT_POLICY == 1 */ return this->transport_sync_strategy (); } void TAO_ORB_Core::set_sync_scope_hook (Sync_Scope_Hook hook) { TAO_ORB_Core::sync_scope_hook_ = hook; return; } #if (TAO_HAS_SYNC_SCOPE_POLICY == 1) CORBA::Policy_ptr TAO_ORB_Core::stubless_sync_scope (void) { CORBA::Policy_var result; // No need to lock, the object is in TSS storage.... TAO_Policy_Current &policy_current = this->policy_current (); result = policy_current.get_cached_policy (TAO_CACHED_POLICY_SYNC_SCOPE); // @@ Must lock, but is is harder to implement than just modifying // this call: the ORB does take a lock to modify the policy // manager if (CORBA::is_nil (result.in ())) { TAO_Policy_Manager *policy_manager = this->policy_manager (); if (policy_manager != 0) result = policy_manager->get_cached_policy ( TAO_CACHED_POLICY_SYNC_SCOPE); } if (CORBA::is_nil (result.in ())) result = this->default_policies_->get_cached_policy ( TAO_CACHED_POLICY_SYNC_SCOPE); return result._retn (); } #endif /* TAO_HAS_SYNC_SCOPE_POLICY == 1 */ void TAO_ORB_Core::call_timeout_hook (TAO_Stub *stub, int &has_timeout, ACE_Time_Value &time_value) { if (TAO_ORB_Core::timeout_hook_ == 0) { has_timeout = 0; return; } (*TAO_ORB_Core::timeout_hook_) (this, stub, has_timeout, time_value); } void TAO_ORB_Core::set_timeout_hook (Timeout_Hook hook) { TAO_ORB_Core::timeout_hook_ = hook; // Saving the hook pointer so that we can use it later when needed. return; } CORBA::Policy_ptr TAO_ORB_Core::stubless_relative_roundtrip_timeout (void) { CORBA::Policy_var result; #if (TAO_HAS_CORBA_MESSAGING == 1 \ && TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1) // No need to lock, the object is in TSS storage.... TAO_Policy_Current &policy_current = this->policy_current (); result = policy_current.get_cached_policy ( TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT); // @@ Must lock, but is is harder to implement than just modifying // this call: the ORB does take a lock to modify the policy // manager if (CORBA::is_nil (result.in ())) { TAO_Policy_Manager *policy_manager = this->policy_manager (); if (policy_manager != 0) result = policy_manager->get_cached_policy ( TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT); } if (CORBA::is_nil (result.in ())) result = this->default_policies_->get_cached_policy ( TAO_CACHED_POLICY_RELATIVE_ROUNDTRIP_TIMEOUT); #endif /* TAO_HAS_CORBA_MESSAGING == 1 && TAO_HAS_RELATIVE_ROUNDTRIP_TIMEOUT_POLICY == 1 */ return result._retn (); } void TAO_ORB_Core::connection_timeout (TAO_Stub *stub, int &has_timeout, ACE_Time_Value &time_value) { if (TAO_ORB_Core::connection_timeout_hook_ == 0) { has_timeout = 0; return; } (*TAO_ORB_Core::connection_timeout_hook_) (this, stub, has_timeout, time_value); } void TAO_ORB_Core::connection_timeout_hook (Timeout_Hook hook) { // Saving the hook pointer so that we can use it later when needed. TAO_ORB_Core::connection_timeout_hook_ = hook; return; } CORBA::Policy_ptr TAO_ORB_Core::stubless_connection_timeout (void) { CORBA::Policy_var result; #if (TAO_HAS_CORBA_MESSAGING == 1 \ && TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1) // No need to lock, the object is in TSS storage.... TAO_Policy_Current &policy_current = this->policy_current (); result = policy_current.get_cached_policy ( TAO_CACHED_POLICY_CONNECTION_TIMEOUT); // @@ Must lock, but is is harder to implement than just modifying // this call: the ORB does take a lock to modify the policy // manager if (CORBA::is_nil (result.in ())) { TAO_Policy_Manager *policy_manager = this->policy_manager (); if (policy_manager != 0) result = policy_manager->get_cached_policy ( TAO_CACHED_POLICY_CONNECTION_TIMEOUT); } if (CORBA::is_nil (result.in ())) result = this->default_policies_->get_cached_policy ( TAO_CACHED_POLICY_CONNECTION_TIMEOUT); #endif /* TAO_HAS_CORBA_MESSAGING == 1 && TAO_HAS_CONNECTION_TIMEOUT_POLICY == 1 */ return result._retn (); } #if (TAO_HAS_CORBA_MESSAGING == 1) CORBA::Policy_ptr TAO_ORB_Core::get_cached_policy (TAO_Cached_Policy_Type type) { CORBA::Policy_var result; // @@ Must lock, but is is harder to implement than just modifying // this call: the ORB does take a lock to modify the policy // manager TAO_Policy_Manager *policy_manager = this->policy_manager (); if (policy_manager != 0) result = policy_manager->get_cached_policy (type); if (CORBA::is_nil (result.in ())) result = this->get_default_policies ()->get_cached_policy (type); return result._retn (); } #endif /* (TAO_HAS_CORBA_MESSAGING == 1) */ // **************************************************************** TAO_ORB_Core_TSS_Resources::TAO_ORB_Core_TSS_Resources (void) : output_cdr_dblock_allocator_ (0), output_cdr_buffer_allocator_ (0), output_cdr_msgblock_allocator_ (0), input_cdr_dblock_allocator_ (0), input_cdr_buffer_allocator_ (0), input_cdr_msgblock_allocator_ (0), transport_message_buffer_allocator_ (0), event_loop_thread_ (0), client_leader_thread_ (0), lane_ (0), ts_objects_ (), orb_core_ (0) #if TAO_HAS_INTERCEPTORS == 1 , pi_current_ () , client_request_info_ (0) #endif /* TAO_HAS_INTERCEPTORS == 1 */ { #if TAO_HAS_INTERCEPTORS == 1 ACE_NEW (this->client_request_info_, TAO_ClientRequestInfo); #endif /* TAO_HAS_INTERCEPTORS == 1 */ } TAO_ORB_Core_TSS_Resources::~TAO_ORB_Core_TSS_Resources (void) { if (this->output_cdr_dblock_allocator_ != 0) this->output_cdr_dblock_allocator_->remove (); delete this->output_cdr_dblock_allocator_; if (this->output_cdr_buffer_allocator_ != 0) this->output_cdr_buffer_allocator_->remove (); delete this->output_cdr_buffer_allocator_; if (this->output_cdr_msgblock_allocator_ != 0) this->output_cdr_msgblock_allocator_->remove (); delete this->output_cdr_msgblock_allocator_; if (this->input_cdr_dblock_allocator_ != 0) this->input_cdr_dblock_allocator_->remove (); delete this->input_cdr_dblock_allocator_; if (this->input_cdr_buffer_allocator_ != 0) this->input_cdr_buffer_allocator_->remove (); delete this->input_cdr_buffer_allocator_; if (this->input_cdr_msgblock_allocator_ != 0) this->input_cdr_msgblock_allocator_->remove (); delete this->input_cdr_msgblock_allocator_; if (this->transport_message_buffer_allocator_ != 0) this->transport_message_buffer_allocator_->remove (); delete this->transport_message_buffer_allocator_; #if TAO_HAS_INTERCEPTORS == 1 CORBA::release (this->client_request_info_); #endif /* TAO_HAS_INTERCEPTORS == 1 */ //@@ This is broken on platforms that use TSS emulation since this // destructor is invoked after the ORB. Since we're under // pressure to release a beta, we'll have to leak the TSS objects // stores in the array. However, the only service // known to currently use this array is the SSLIOP pluggable // protocol. Fortunately, it registeres a null cleanup function // so we're not leaking anything yet. We *do* need to fix this // before other services start to use this array. // -Ossama // if (this->orb_core_ != 0) // this->orb_core_->tss_cleanup_funcs ()->cleanup (this->ts_objects_); } // **************************************************************** TAO_TSS_Resources::TAO_TSS_Resources (void) : poa_current_impl_ (0), default_environment_ (&this->tss_environment_) #if (TAO_HAS_CORBA_MESSAGING == 1) , policy_current_ (&this->initial_policy_current_) #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ { } TAO_TSS_Resources::~TAO_TSS_Resources (void) { } // **************************************************************** TAO_Export TAO_ORB_Core * TAO_ORB_Core_instance (void) { // @@ This is a slight violation of layering, we should use // TAO_ORB_Core_instance(), but that breaks during startup. TAO_ORB_Table *orb_table = TAO_ORB_Table::instance (); if (orb_table->first_orb () == 0) { ACE_MT (ACE_GUARD_RETURN (TAO_SYNCH_RECURSIVE_MUTEX, guard, *ACE_Static_Object_Lock::instance (), 0)); if (orb_table->first_orb () == 0) { // Calling CORBA::ORB_init() returns a duplicated ORB // reference, so make sure that reference is stored in an // ORB_var so that no leak occurs. The duplicate ORB // reference isn't needed outside the scope of this function // since the corresponding ORB Core instance will still // exist in the ORB table after the ORB reference is // destroyed. CORBA::ORB_var orb; int argc = 0; ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { orb = CORBA::ORB_init (argc, 0, 0 ACE_ENV_ARG_PARAMETER); ACE_TRY_CHECK; } ACE_CATCHANY { // @@ What should we do here? } ACE_ENDTRY; } } return orb_table->first_orb (); } int TAO_ORB_Core::collocation_strategy (CORBA::Object_ptr object ACE_ENV_ARG_DECL) { TAO_Stub *stub = object->_stubobj (); if (!CORBA::is_nil (stub->servant_orb_var ().in ()) && stub->servant_orb_var ()->orb_core () != 0) { TAO_ORB_Core *orb_core = stub->servant_orb_var ()->orb_core (); int collocated = orb_core->collocation_resolver ().is_collocated (object ACE_ENV_ARG_PARAMETER); ACE_CHECK_RETURN (-1); if (collocated) { switch (stub->servant_orb_var ()->orb_core ()->get_collocation_strategy ()) { case THRU_POA: return TAO_Collocation_Strategies::CS_THRU_POA_STRATEGY; case DIRECT: { ///////////////////////////////////////////////////////////// // If the servant is null and you are collocated this means // that the POA policy NON-RETAIN is set, and with that policy // using the DIRECT collocation strategy is just insane. ///////////////////////////////////////////////////////////// ACE_ASSERT (object->_servant () != 0); return TAO_Collocation_Strategies::CS_DIRECT_STRATEGY; } } } } // In this case the Object is a client. return TAO_Collocation_Strategies::CS_REMOTE_STRATEGY; } TAO_ORB_Core::InitRefMap * TAO_ORB_Core::init_ref_map () { return &this->init_ref_map_; } // **************************************************************** #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Lock_Adapter; #if defined (ACE_HAS_THREADS) template class ACE_Lock_Adapter; template class ACE_Lock_Adapter; #endif /* ACE_HAS_THREADS */ template class ACE_Reverse_Lock; template class ACE_Guard >; template class TAO_TSS_Singleton; template class ACE_TSS; template class ACE_TSS; template class ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Entry; template class ACE_Hash_Map_Reverse_Iterator_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex>; template class ACE_Array_Base; template class ACE_Dynamic_Service; template class ACE_Dynamic_Service; #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Lock_Adapter #if defined (ACE_HAS_THREADS) #pragma instantiate ACE_Lock_Adapter #pragma instantiate ACE_Lock_Adapter #endif /* ACE_HAS_THREADS */ #pragma instantiate ACE_Reverse_Lock #pragma instantiate ACE_Guard > #pragma instantiate TAO_TSS_Singleton #pragma instantiate ACE_TSS #pragma instantiate ACE_TSS #pragma instantiate ACE_Hash_Map_Manager_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Entry #pragma instantiate ACE_Hash_Map_Reverse_Iterator_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Hash_Map_Iterator_Base_Ex, ACE_Equal_To, ACE_Null_Mutex> #pragma instantiate ACE_Array_Base #pragma instantiate ACE_Dynamic_Service #pragma instantiate ACE_Dynamic_Service #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */