// "$Id$" #include "tao/ORB.h" ACE_RCSID (tao, ORB, "$Id$") #include "tao/ORB_Table.h" #include "tao/Connector_Registry.h" #include "tao/IOR_Parser.h" #include "tao/Stub.h" #include "tao/ORB_Core.h" #include "tao/ORB_Core_TSS_Resources.h" #include "tao/TAO_Internal.h" #include "tao/Dynamic_Adapter.h" #include "tao/Profile.h" #include "tao/default_ports.h" #include "tao/ORBInitializer_Registry_Adapter.h" #include "tao/PolicyFactory_Registry_Adapter.h" #include "tao/NVList_Adapter.h" #include "tao/TAO_Singleton_Manager.h" #include "tao/Policy_Current.h" #include "tao/Policy_Manager.h" #include "tao/Valuetype_Adapter.h" #include "tao/IFR_Client_Adapter.h" #include "tao/TypeCodeFactory_Adapter.h" #include "tao/debug.h" #include "tao/CDR.h" #include "tao/SystemException.h" #include "tao/default_environment.h" #include "tao/ObjectIdListC.h" #if !defined (__ACE_INLINE__) # include "tao/ORB.inl" #endif /* ! __ACE_INLINE__ */ #include "ace/Dynamic_Service.h" #include "ace/Service_Config.h" #include "ace/Arg_Shifter.h" #include "ace/Reactor.h" #include "ace/Argv_Type_Converter.h" #include "ace/ACE.h" #include "ace/Static_Object_Lock.h" #include "ace/OS_NS_strings.h" #include "ace/OS_NS_string.h" #include "ace/OS_NS_ctype.h" #include "ace/CORBA_macros.h" static const char ior_prefix[] = "IOR:"; // **************************************************************** TAO_BEGIN_VERSIONED_NAMESPACE_DECL CORBA::ORB::InvalidName::InvalidName (void) : CORBA::UserException ("IDL:omg.org/CORBA/ORB/InvalidName:1.0", "InvalidName") { } // Destructor - all members are of self managing types. CORBA::ORB::InvalidName::~InvalidName (void) { } // Copy constructor. CORBA::ORB::InvalidName::InvalidName (const CORBA::ORB::InvalidName &exc) : CORBA::UserException (exc._rep_id (), exc._name ()) { } // Assignment operator. CORBA::ORB::InvalidName& CORBA::ORB::InvalidName::operator= (const ::CORBA::ORB::InvalidName &_tao_excp) { this->UserException::operator= (_tao_excp); return *this; } CORBA::ORB::InvalidName * CORBA::ORB::InvalidName::_downcast (CORBA::Exception *exc) { return dynamic_cast (exc); } CORBA::Exception *CORBA::ORB::InvalidName::_alloc (void) { CORBA::Exception *retval = 0; ACE_NEW_RETURN (retval, ::CORBA::ORB::InvalidName, 0); return retval; } CORBA::Exception * CORBA::ORB::InvalidName::_tao_duplicate (void) const { CORBA::Exception *result = 0; ACE_NEW_RETURN ( result, ::CORBA::ORB::InvalidName (*this), 0); return result; } void CORBA::ORB::InvalidName::_raise (void) const { throw *this; } void CORBA::ORB::InvalidName::_tao_encode (TAO_OutputCDR &) const { throw ::CORBA::MARSHAL (); } void CORBA::ORB::InvalidName::_tao_decode (TAO_InputCDR &) { throw ::CORBA::MARSHAL (); } // **************************************************************** CORBA::ORB::ORB (TAO_ORB_Core *orb_core) : refcount_ (1) , orb_core_ (orb_core) , use_omg_ior_format_ (1) , timeout_ (0) { } CORBA::ORB::~ORB (void) { // This destructor is only invoked when the last ORB reference (not // instance) is being destroyed. } void CORBA::ORB::shutdown (CORBA::Boolean wait_for_completion) { // We cannot lock the exceptions here. We need to propogate // BAD_INV_ORDER exceptions if needed to the caller. Locking // exceptions down would render us non-compliant with the spec. this->check_shutdown (); this->orb_core ()->shutdown (wait_for_completion); } void CORBA::ORB::destroy (void) { if (this->orb_core () == 0) { // If the ORB_Core pointer is zero, assume that the ORB_Core has // been destroyed. // As defined by the CORBA 2.3 specification, throw a // CORBA::OBJECT_NOT_EXIST exception if the ORB has been // destroyed by the time an ORB function is called. throw ::CORBA::OBJECT_NOT_EXIST (0, CORBA::COMPLETED_NO); } if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("CORBA::ORB::destroy() called on ORB <%s>.\n"), ACE_TEXT_CHAR_TO_TCHAR (this->orb_core ()->orbid ()))); } this->orb_core ()->destroy (); // Now invalidate the pointer to the ORB_Core that created this // ORB. this->orb_core_ = 0; } void CORBA::ORB::run (void) { this->run (0); } void CORBA::ORB::run (ACE_Time_Value &tv) { this->run (&tv); } void CORBA::ORB::run (ACE_Time_Value *tv) { this->check_shutdown (); this->orb_core ()->run (tv, 0); } void CORBA::ORB::perform_work (void) { this->perform_work (0); } void CORBA::ORB::perform_work (ACE_Time_Value &tv) { this->perform_work (&tv); } void CORBA::ORB::perform_work (ACE_Time_Value *tv) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); this->orb_core ()->run (tv, 1); } CORBA::Boolean CORBA::ORB::work_pending (ACE_Time_Value &tv) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); int const result = this->orb_core_->reactor ()->work_pending (tv); if (result == 0 || (result == -1 && errno == ETIME)) return false; if (result == -1) throw ::CORBA::INTERNAL (); return true; } CORBA::Boolean CORBA::ORB::work_pending (void) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); const int result = this->orb_core_->reactor ()->work_pending (); if (result == 0) return false; if (result == -1) throw ::CORBA::INTERNAL (); return true; } #if (TAO_HAS_MINIMUM_CORBA == 0) && !defined (CORBA_E_COMPACT) && !defined (CORBA_E_MICRO) void CORBA::ORB::create_list (CORBA::Long count, CORBA::NVList_ptr &new_list) { TAO_NVList_Adapter *adapter = ACE_Dynamic_Service::instance ("TAO_NVList_Adapter"); if (adapter == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ORB unable to find the ") ACE_TEXT ("NVList Adapter instance"))); throw ::CORBA::INTERNAL (); } adapter->create_list (count, new_list); } void CORBA::ORB::create_exception_list (CORBA::ExceptionList_ptr &list) { TAO_Dynamic_Adapter *dynamic_adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::dynamic_adapter_name ()); dynamic_adapter->create_exception_list (list); } void CORBA::ORB::create_operation_list (CORBA::OperationDef_ptr opDef, CORBA::NVList_ptr &result) { TAO_IFR_Client_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::ifr_client_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTF_REPOS (); } adapter->create_operation_list (this, opDef, result); } void CORBA::ORB::create_environment (CORBA::Environment_ptr &environment) { ACE_NEW_THROW_EX (environment, CORBA::Environment (), CORBA::NO_MEMORY ( CORBA::SystemException::_tao_minor_code ( 0, ENOMEM), CORBA::COMPLETED_NO)); } void CORBA::ORB::create_named_value (CORBA::NamedValue_ptr &nv) { TAO_NVList_Adapter *adapter = ACE_Dynamic_Service::instance ( "TAO_NVList_Adapter"); if (adapter == 0) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("ORB unable to find the ") ACE_TEXT ("NVList Adapter instance"))); throw ::CORBA::INTERNAL (); } adapter->create_named_value (nv); } // The following functions are not implemented - they just throw // CORBA::NO_IMPLEMENT. CORBA::Boolean CORBA::ORB::get_service_information ( CORBA::ServiceType /* service_type */, CORBA::ServiceInformation_out /* service_information */) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } void CORBA::ORB::create_context_list (CORBA::ContextList_ptr &) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } void CORBA::ORB::get_default_context (CORBA::Context_ptr &) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } void CORBA::ORB::send_multiple_requests_oneway (const CORBA::RequestSeq &) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } void CORBA::ORB::send_multiple_requests_deferred (const CORBA::RequestSeq &) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } void CORBA::ORB::get_next_response (CORBA::Request_ptr &) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } CORBA::Boolean CORBA::ORB::poll_next_response (void) { throw ::CORBA::NO_IMPLEMENT ( CORBA::SystemException::_tao_minor_code ( 0, ENOTSUP), CORBA::COMPLETED_NO); } // **************************************************************** CORBA::TypeCode_ptr CORBA::ORB::create_struct_tc ( const char *id, const char *name, const CORBA::StructMemberSeq & members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_struct_tc (id, name, members); } CORBA::TypeCode_ptr CORBA::ORB::create_union_tc ( const char *id, const char *name, CORBA::TypeCode_ptr discriminator_type, const CORBA::UnionMemberSeq & members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_union_tc (id, name, discriminator_type, members); } CORBA::TypeCode_ptr CORBA::ORB::create_enum_tc ( const char *id, const char *name, const CORBA::EnumMemberSeq & members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_enum_tc (id, name, members); } CORBA::TypeCode_ptr CORBA::ORB::create_alias_tc ( const char *id, const char *name, CORBA::TypeCode_ptr original_type) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_alias_tc (id, name, original_type); } CORBA::TypeCode_ptr CORBA::ORB::create_exception_tc ( const char *id, const char *name, const CORBA::StructMemberSeq & members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_exception_tc (id, name, members); } CORBA::TypeCode_ptr CORBA::ORB::create_interface_tc ( const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_interface_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_string_tc ( CORBA::ULong bound) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_string_tc (bound); } CORBA::TypeCode_ptr CORBA::ORB::create_wstring_tc ( CORBA::ULong bound) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_wstring_tc (bound); } CORBA::TypeCode_ptr CORBA::ORB::create_fixed_tc ( CORBA::UShort digits, CORBA::UShort scale) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_fixed_tc (digits, scale); } CORBA::TypeCode_ptr CORBA::ORB::create_sequence_tc ( CORBA::ULong bound, CORBA::TypeCode_ptr element_type) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_sequence_tc (bound, element_type); } CORBA::TypeCode_ptr CORBA::ORB::create_array_tc ( CORBA::ULong length, CORBA::TypeCode_ptr element_type) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_array_tc (length, element_type); } CORBA::TypeCode_ptr CORBA::ORB::create_value_tc ( const char *id, const char *name, CORBA::ValueModifier type_modifier, CORBA::TypeCode_ptr concrete_base, const CORBA::ValueMemberSeq & members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_value_tc (id, name, type_modifier, concrete_base, members); } CORBA::TypeCode_ptr CORBA::ORB::create_value_box_tc ( const char *id, const char *name, CORBA::TypeCode_ptr boxed_type) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_value_box_tc (id, name, boxed_type); } CORBA::TypeCode_ptr CORBA::ORB::create_native_tc (const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_native_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_recursive_tc (const char *id) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_recursive_tc (id); } CORBA::TypeCode_ptr CORBA::ORB::create_abstract_interface_tc (const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_abstract_interface_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_local_interface_tc (const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_local_interface_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_component_tc (const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_component_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_home_tc (const char *id, const char *name) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_home_tc (id, name); } CORBA::TypeCode_ptr CORBA::ORB::create_event_tc ( const char *id, const char *name, CORBA::ValueModifier type_modifier, CORBA::TypeCode_ptr concrete_base, const CORBA::ValueMemberSeq &members) { TAO_TypeCodeFactory_Adapter *adapter = ACE_Dynamic_Service::instance ( TAO_ORB_Core::typecodefactory_adapter_name ()); if (adapter == 0) { throw ::CORBA::INTERNAL (); } return adapter->create_event_tc (id, name, type_modifier, concrete_base, members); } // **************************************************************** #endif /* TAO_HAS_MINIMUM_CORBA */ CORBA::Object_ptr CORBA::ORB::resolve_policy_manager (void) { #if (TAO_HAS_CORBA_MESSAGING == 1) TAO_Policy_Manager *policy_manager = this->orb_core_->policy_manager (); if (policy_manager == 0) { return CORBA::Object::_nil (); } return CORBA::Object::_duplicate (policy_manager); #else return CORBA::Object::_nil (); #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ } CORBA::Object_ptr CORBA::ORB::resolve_policy_current (void) { #if (TAO_HAS_CORBA_MESSAGING == 1) TAO_Policy_Current &policy_current = this->orb_core_->policy_current (); return CORBA::Object::_duplicate (&policy_current); #else return CORBA::Object::_nil (); #endif /* TAO_HAS_CORBA_MESSAGING == 1 */ } void CORBA::ORB::resolve_service (TAO::MCAST_SERVICEID mcast_service_id) { #if defined ACE_HAS_IP_MULTICAST static char const * const env_service_port[] = { "NameServicePort", "TradingServicePort", "ImplRepoServicePort", "InterfaceRepoServicePort" }; static unsigned short const default_service_port[] = { TAO_DEFAULT_NAME_SERVER_REQUEST_PORT, TAO_DEFAULT_TRADING_SERVER_REQUEST_PORT, TAO_DEFAULT_IMPLREPO_SERVER_REQUEST_PORT, TAO_DEFAULT_INTERFACEREPO_SERVER_REQUEST_PORT }; // By now, the table filled in with -ORBInitRef arguments has been // checked. We only get here if the table didn't contain an initial // reference for the requested Service. CORBA::String_var default_init_ref = this->orb_core_->orb_params ()->default_init_ref (); static char const mcast_prefix[] = "mcast://:::"; if ((ACE_OS::strncmp (default_init_ref.in (), mcast_prefix, sizeof (mcast_prefix) - 1) == 0)) { // First, determine if the port was supplied on the command line unsigned short port = this->orb_core_->orb_params ()->service_port (mcast_service_id); if (port == 0) { // Look for the port among our environment variables. char const * const port_number = ACE_OS::getenv (env_service_port[mcast_service_id]); if (port_number != 0) port = static_cast (ACE_OS::atoi (port_number)); else port = default_service_port[mcast_service_id]; } // Set the port value in ORB_Params: modify the default mcast // value. static char const mcast_fmt[] = "mcast://:%d::"; static size_t const PORT_BUF_SIZE = 256; char def_init_ref[PORT_BUF_SIZE] = { 0 }; ACE_OS::snprintf (def_init_ref, PORT_BUF_SIZE, mcast_fmt, port); this->orb_core_->orb_params ()->default_init_ref (def_init_ref); } #else ACE_UNUSED_ARG (mcast_service_id); #endif /* ACE_HAS_IP_MULTICAST */ } CORBA::Object_ptr CORBA::ORB::resolve_initial_references (const char *name, ACE_Time_Value *timeout) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); CORBA::Object_var result; if (ACE_OS::strcmp (name, TAO_OBJID_ROOTPOA) == 0) { result = this->orb_core ()->root_poa (); } else if (ACE_OS::strcmp (name, TAO_OBJID_POACURRENT) == 0) { result = this->orb_core ()->resolve_poa_current (); } else if (ACE_OS::strcmp (name, TAO_OBJID_POLICYMANAGER) == 0) { result = this->resolve_policy_manager (); } else if (ACE_OS::strcmp (name, TAO_OBJID_POLICYCURRENT) == 0) { result = this->resolve_policy_current (); } else if (ACE_OS::strcmp (name, TAO_OBJID_IORMANIPULATION) == 0) { result = this->orb_core ()->resolve_ior_manipulation (); } else if (ACE_OS::strcmp (name, TAO_OBJID_IORTABLE) == 0) { result = this->orb_core ()->resolve_ior_table (); } else if (ACE_OS::strcmp (name, TAO_OBJID_DYNANYFACTORY) == 0) { result = this->orb_core ()->resolve_dynanyfactory (); } else if (ACE_OS::strcmp (name, TAO_OBJID_TYPECODEFACTORY) == 0) { result = this->orb_core ()->resolve_typecodefactory (); } else if (ACE_OS::strcmp (name, TAO_OBJID_CODECFACTORY) == 0) { result = this->orb_core ()->resolve_codecfactory (); } else if (ACE_OS::strcmp (name, TAO_OBJID_COMPRESSIONMANAGER) == 0) { result = this->orb_core ()->resolve_compression_manager (); } else if (ACE_OS::strcmp (name, TAO_OBJID_MONITOR) == 0) { result = this->orb_core ()->resolve_monitor (); } #if TAO_HAS_INTERCEPTORS == 1 else if (ACE_OS::strcmp (name, TAO_OBJID_PICurrent) == 0) { result = this->orb_core ()->resolve_picurrent (); } #endif // ----------------------------------------------------------------- if (CORBA::is_nil (result.in ())) { // Search the object reference table. This search must occur before // the InitRef table search, since it may contain local objects. result = this->orb_core ()->object_ref_table ().resolve_initial_reference (name); } if (!CORBA::is_nil (result.in ())) return result._retn (); // ----------------------------------------------------------------- // Check ORBInitRef options. // @@ There appears to be long standing (i.e. back when the map was // an ACE_Hash_Map_Manager) race condition here since the map // access is not synchronized. // Is the service name in the IOR Table. TAO_ORB_Core::InitRefMap::iterator ior = this->orb_core_->init_ref_map ()->find (ACE_CString (name)); if (ior != this->orb_core_->init_ref_map ()->end ()) return this->string_to_object ((*ior).second.c_str ()); // Look for an environment variable called "IOR". // CORBA::String_var ior_env_var_name = CORBA::string_alloc (static_cast (ACE_OS::strlen (name) + 3)); ACE_OS::strcpy (ior_env_var_name.inout (), name); ACE_OS::strcat (ior_env_var_name.inout (), "IOR"); ACE_CString service_ior = ACE_OS::getenv (ior_env_var_name.in ()); if (ACE_OS::strcmp (service_ior.c_str (), "") != 0) { result = this->string_to_object (service_ior.c_str()); return result._retn (); } // May be trying the explicitly specified services and the well // known services should be tried first before falling on to default // services. // Set the timeout value. this->set_timeout (timeout); if (ACE_OS::strcmp (name, TAO_OBJID_NAMESERVICE) == 0) { this->resolve_service (TAO::MCAST_NAMESERVICE); } else if (ACE_OS::strcmp (name, TAO_OBJID_TRADINGSERVICE) == 0) { this->resolve_service (TAO::MCAST_TRADINGSERVICE); } else if (ACE_OS::strcmp (name, TAO_OBJID_IMPLREPOSERVICE) == 0) { this->resolve_service (TAO::MCAST_IMPLREPOSERVICE); } else if (ACE_OS::strcmp (name, TAO_OBJID_INTERFACEREP) == 0) { this->resolve_service (TAO::MCAST_INTERFACEREPOSERVICE); } // Is not one of the well known services, try to find it in the // InitRef table....check the defaultinitref values also. result = this->orb_core ()->resolve_rir (name); if (!CORBA::is_nil (result.in ())) return result._retn (); // ----------------------------------------------------------------- throw ::CORBA::ORB::InvalidName (); } #if !defined(CORBA_E_MICRO) void CORBA::ORB::register_initial_reference (const char * id, CORBA::Object_ptr obj) { if (id == 0 || ACE_OS::strlen (id) == 0) throw ::CORBA::ORB::InvalidName (); if (CORBA::is_nil (obj)) throw ::CORBA::BAD_PARAM (CORBA::OMGVMCID | 27, CORBA::COMPLETED_NO); TAO_Object_Ref_Table &table = this->orb_core_->object_ref_table (); if (table.register_initial_reference (id, obj) == -1) throw ::CORBA::ORB::InvalidName (); } #endif CORBA::ORB::ObjectIdList_ptr CORBA::ORB::list_initial_services (void) { this->check_shutdown (); return this->orb_core ()->list_initial_references (); } void CORBA::ORB::check_shutdown (void) { if (this->orb_core () != 0) { this->orb_core ()->check_shutdown (); } else { // If the ORB_Core pointer is zero, assume that the ORB_Core has // been destroyed. // As defined by the CORBA 2.3 specification, throw a // CORBA::OBJECT_NOT_EXIST exception if the ORB has been // destroyed by the time an ORB function is called. throw ::CORBA::OBJECT_NOT_EXIST (0, CORBA::COMPLETED_NO); } } CORBA::ORB_ptr CORBA::ORB::_tao_make_ORB (TAO_ORB_Core * orb_core) { CORBA::ORB_ptr orb = CORBA::ORB_ptr (); ACE_NEW_RETURN (orb, CORBA::ORB (orb_core), CORBA::ORB::_nil ()); return orb; } // **************************************************************** namespace TAO { bool parse_orb_opt (ACE_Argv_Type_Converter& command_line, const ACE_TCHAR* orb_opt, ACE_CString& opt_arg) { if (opt_arg.length () > 0) return false; ACE_Arg_Shifter arg_shifter (command_line.get_argc (), command_line.get_TCHAR_argv ()); size_t opt_len = ACE_OS::strlen (orb_opt); bool found = false; while (arg_shifter.is_anything_left ()) { const ACE_TCHAR *current_arg = arg_shifter.get_current (); if (ACE_OS::strcasecmp (current_arg, orb_opt) == 0) { found = true; arg_shifter.consume_arg (); if (arg_shifter.is_parameter_next ()) { opt_arg = ACE_TEXT_ALWAYS_CHAR (arg_shifter.get_current ()); arg_shifter.consume_arg (); } } else if (ACE_OS::strncasecmp (current_arg, orb_opt, opt_len) == 0) { arg_shifter.consume_arg (); // The rest of the argument is the ORB id... // but we should skip an optional space... if (current_arg[opt_len] == ' ') opt_arg = ACE_TEXT_ALWAYS_CHAR (current_arg + opt_len + 1); else opt_arg = ACE_TEXT_ALWAYS_CHAR (current_arg + opt_len); } else arg_shifter.ignore_arg (); } return found; } ACE_Intrusive_Auto_Ptr find_orb_context (const ACE_CString& orbconfig_string) { const ACE_TCHAR *arg = ACE_TEXT_CHAR_TO_TCHAR(orbconfig_string.c_str ()); // 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* gestalt = 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)); return ACE_Intrusive_Auto_Ptr (gestalt); } // 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 (); } // Someone else's context? const ACE_TCHAR *shared = ACE_TEXT("ORB:"); size_t shared_len = ACE_OS::strlen(shared); if (ACE_OS::strncmp (arg, shared, shared_len) == 0) { ACE_CString orbid (orbconfig_string.substr (shared_len)); // 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. // NOTE we also define wide character versions as a conveniance, IF // we are building wide character applications. // The first two versions are wrappers to the actual third and final // implimentation of ORB_init() which is the "native" char form. #if defined (ACE_USES_WCHAR) // Provide the narrow char version as well as the above wide char version. CORBA::ORB_ptr CORBA::ORB_init (int &argc, ACE_ANTI_TCHAR *argv[], const char *orbid) { ACE_Argv_Type_Converter command_line (argc, argv); return CORBA::ORB_init (command_line.get_argc (), command_line.get_TCHAR_argv (), orbid); } CORBA::ORB_ptr CORBA::ORB_init (int &argc, wchar_t *argv[], const wchar_t *orbid) { return CORBA::ORB_init (argc, argv, ACE_TEXT_ALWAYS_CHAR (orbid)); } #endif CORBA::ORB_ptr CORBA::ORB_init (int &argc, ACE_TCHAR *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 = (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 ( 0, EINVAL), 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 ())); // The ORB was already initialized. Just return that one. if (oc.get () != 0) { return CORBA::ORB::_duplicate (oc->orb ()); } // 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-wide (global) context // Use this string variable to hold the configuration identity key ACE_CString orbconfig_string; TAO::parse_orb_opt (command_line, ACE_TEXT("-ORBGestalt"), orbconfig_string); ACE_Intrusive_Auto_Ptr gestalt = TAO::find_orb_context (orbconfig_string); // An ORB corresponding to the desired ORBid doesn't exist so create // a new one. TAO_ORB_Core * tmp = 0; ACE_NEW_THROW_EX (tmp, TAO_ORB_Core (orbid_string.c_str (), gestalt), CORBA::NO_MEMORY ( CORBA::SystemException::_tao_minor_code (0, ENOMEM), CORBA::COMPLETED_NO)); // The ORB table increases the reference count on the ORB Core // so do not release it here. Allow the TAO_ORB_Core_Auto_Ptr // to decrease the reference count on the ORB Core when it goes // out of scope. oc.reset (tmp); // 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 // application most likely neither cares, nor wishes to know about // them. Furthermore, if the ORB DLL gets unloaded, the static // services it had registered globaly will no longer be accesible, // which will have disastrous consequences at the process // shutdown. Hence, the ACE_Service_Config_Guard ensures that for // the current thread, any references to the global // ACE_Service_Config will be re-routed to this ORB's service gestalt. ACE_Service_Config_Guard scg (oc->configuration ()); // Initialize the Service Configurator. This must occur before the // ORBInitializer::pre_init() method is invoked on each registered // ORB initializer. int result = TAO::ORB::open_services (oc->configuration (), command_line.get_argc (), command_line.get_TCHAR_argv ()); // Check for errors returned from . if (result != 0 && errno != ENOENT) { ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("Unable to initialize the ") ACE_TEXT ("Service Configurator"))); throw ::CORBA::INITIALIZE ( CORBA::SystemException::_tao_minor_code ( TAO_ORB_CORE_INIT_LOCATION_CODE, 0), CORBA::COMPLETED_NO); } TAO::ORBInitializer_Registry_Adapter * orbinitializer_registry = oc.get ()->orbinitializer_registry (); PortableInterceptor::SlotId slotid = 0; size_t pre_init_count = 0; if (orbinitializer_registry != 0) { pre_init_count = orbinitializer_registry->pre_init (oc.get (), command_line.get_argc(), command_line.get_ASCII_argv(), slotid); } // Initialize the ORB Core instance. result = oc->init (command_line.get_argc(), command_line.get_ASCII_argv()); if (orbinitializer_registry != 0) { orbinitializer_registry->post_init (pre_init_count, oc.get (), command_line.get_argc(), command_line.get_ASCII_argv(), slotid); } if (TAO_debug_level > 2) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT("TAO (%P|%t) created new ORB <%s>\n"), ACE_TEXT_CHAR_TO_TCHAR (orbid_string.c_str ()))); } // Before returning remember to store the ORB into the table... if (TAO::ORB_Table::instance ()->bind (orbid_string.c_str (), oc.get ()) != 0) throw ::CORBA::INTERNAL (0, CORBA::COMPLETED_NO); // Return a duplicate since the ORB_Core should release the last // reference to the ORB. return CORBA::ORB::_duplicate (oc->orb ()); } // **************************************************************** // Object reference stringification. char * CORBA::ORB::object_to_string (CORBA::Object_ptr obj) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); if (!CORBA::is_nil (obj)) { if (!obj->can_convert_to_ior ()) throw ::CORBA::MARSHAL (CORBA::OMGVMCID | 4, CORBA::COMPLETED_NO); // Allow a user to provide custom object stringification char* user_string = obj->convert_to_ior (this->use_omg_ior_format_, ior_prefix); if (user_string != 0) return user_string; } // Application writer controls what kind of objref strings they get, // maybe along with other things, by how they initialize the ORB. if (use_omg_ior_format_) { // By default, orbs use IOR strings; these are ugly (and error // prone) but specified by CORBA. // // XXX there should be a simple way to reuse this code in other // ORB implementations ... #if defined (ACE_INITIALIZE_MEMORY_BEFORE_USE) char buf [ACE_CDR::DEFAULT_BUFSIZE] = { 0 }; #else // Avoid the initialization overhead if not compiling with // support for a memory profiler. There is no need to actually perform // initialization otherwise. char buf [ACE_CDR::DEFAULT_BUFSIZE]; #endif /* ACE_INITIALIZE_MEMORY_BEFORE_USE */ TAO_OutputCDR cdr (buf, sizeof buf, TAO_ENCAP_BYTE_ORDER, this->orb_core_->output_cdr_buffer_allocator (), this->orb_core_->output_cdr_dblock_allocator (), this->orb_core_->output_cdr_msgblock_allocator (), this->orb_core_->orb_params ()->cdr_memcpy_tradeoff (), TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR); // There is no translator currently available for stringifying an object // reference, since there is no transport with which to choose an NCS/TCS // pair. // support limited oref ACE_OS::strcmp. (void) ACE_OS::memset (buf, 0, sizeof (buf)); // Marshal the objref into an encapsulation bytestream. (void) cdr.write_octet (TAO_ENCAP_BYTE_ORDER); if (!(cdr << obj)) throw ::CORBA::MARSHAL (); // Now hexify the encapsulated CDR data into a string, and // return that string. size_t const total_len = cdr.total_length (); char *cp = 0; ACE_ALLOCATOR_RETURN (cp, CORBA::string_alloc ( sizeof ior_prefix + 2 * static_cast (total_len)), 0); CORBA::String_var string = cp; ACE_OS::strcpy (cp, ior_prefix); cp += sizeof (ior_prefix) - 1; for (const ACE_Message_Block *i = cdr.begin (); i != 0; i = i->cont ()) { const char *bytes = i->rd_ptr (); size_t len = i->length (); while (len--) { *cp++ = static_cast (ACE::nibble2hex ((*bytes) >> 4)); *cp++ = static_cast (ACE::nibble2hex (*bytes)); ++bytes; } } // Null terminate the string.. *cp = 0; return string._retn (); } else { // It is perfectly valid to marshal a nil object reference. // However, it is not possible to convert a nil object reference // to a URL IOR, so throw an exception. if (CORBA::is_nil (obj) || obj->_stubobj () == 0) { if (TAO_debug_level > 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("Nil object reference or TAO_Stub ") ACE_TEXT ("pointer is zero when converting\n") ACE_TEXT ("object reference to URL IOR.\n"))); throw ::CORBA::MARSHAL ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); } TAO_MProfile &mp = obj->_stubobj ()->base_profiles (); // Try the profiles until one returns a string for (CORBA::ULong index = 0; index < mp.profile_count(); ++index) { char * result = mp.get_profile (index)->to_string(); if (result) return result; } if (TAO_debug_level > 0) ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Cannot stringify given ") ACE_TEXT ("object. No or only unknown profiles.\n"))); throw ::CORBA::MARSHAL ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); } } // Destringify arbitrary objrefs. This method is called from // with an IOR . CORBA::Object_ptr CORBA::ORB::string_to_object (const char *str) { // This method should not be called if the ORB has been shutdown. this->check_shutdown (); // Check for NULL pointer if (str == 0) throw ::CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); TAO_IOR_Parser *ior_parser = this->orb_core_->parser_registry ()->match_parser (str); if (ior_parser != 0) { return ior_parser->parse_string (str, this); } if (ACE_OS::strncmp (str, ior_prefix, sizeof ior_prefix - 1) == 0) return this->ior_string_to_object (str + sizeof ior_prefix - 1); else return this->url_ior_string_to_object (str); } #if defined (ACE_USES_WCHAR) CORBA::Object_ptr CORBA::ORB::string_to_object (const wchar_t *str) { return this->string_to_object (ACE_TEXT_ALWAYS_CHAR (str)); } #endif // **************************************************************** char * CORBA::ORB::id (void) { return CORBA::string_dup (this->orb_core_->orbid ()); } // **************************************************************** #if !defined(CORBA_E_MICRO) CORBA::Policy_ptr CORBA::ORB::create_policy (CORBA::PolicyType type, const CORBA::Any& val) { this->check_shutdown (); TAO::PolicyFactory_Registry_Adapter *adapter = this->orb_core_->policy_factory_registry (); if (adapter == 0) { throw ::CORBA::INTERNAL (); } // Attempt to obtain the policy from the policy factory registry. return adapter->create_policy (type, val); } #endif #if !defined(CORBA_E_MICRO) CORBA::Policy_ptr CORBA::ORB::_create_policy (CORBA::PolicyType type) { this->check_shutdown (); TAO::PolicyFactory_Registry_Adapter *adapter = this->orb_core_->policy_factory_registry (); if (adapter == 0) { throw ::CORBA::INTERNAL (); } // Attempt to obtain the policy from the policy factory registry. return adapter->_create_policy (type); } #endif // Destringify OMG-specified "IOR" string. // // XXX there should be a simple way to reuse this code in other ORB // implementations ... CORBA::Object_ptr CORBA::ORB::ior_string_to_object (const char *str) { // Unhex the bytes, and make a CDR deencapsulation stream from the // resulting data. ACE_Message_Block mb (ACE_OS::strlen (str) / 2 + 1 + ACE_CDR::MAX_ALIGNMENT + 1); ACE_CDR::mb_align (&mb); char *buffer = mb.rd_ptr (); const char *tmp = str; size_t len = 0; while (tmp [0] && tmp [1]) { // Some platforms define 'byte' as a macro, solve the problem // here. #undef byte unsigned char byte; if (!(ACE_OS::ace_isxdigit (tmp [0]) && ACE_OS::ace_isxdigit (tmp [1]))) break; byte = (u_char) (ACE::hex2byte (tmp [0]) << 4); byte |= ACE::hex2byte (tmp [1]); buffer [len++] = byte; tmp += 2; } if (tmp [0] && !ACE_OS::ace_isspace (tmp [0])) { throw ::CORBA::BAD_PARAM (); } // Create deencapsulation stream ... then unmarshal objref from that // stream. int const byte_order = *(mb.rd_ptr ()); mb.rd_ptr (1); mb.wr_ptr (len); TAO_InputCDR stream (&mb, byte_order, TAO_DEF_GIOP_MAJOR, TAO_DEF_GIOP_MINOR, this->orb_core_); CORBA::Object_ptr objref = CORBA::Object::_nil (); stream >> objref; return objref; } // **************************************************************** // Convert an URL style IOR in an object CORBA::Object_ptr CORBA::ORB::url_ior_string_to_object (const char* str) { TAO_MProfile mprofile; // It is safe to declare this on the stack since the contents of // mprofile get copied. No memory is allocated for profile storage // here. The Connector Registry will determine the exact number // of profiles and tell the MProfile object to allocate enough memory // to hold them all. TAO_Connector_Registry *conn_reg = this->orb_core_->connector_registry (); if (conn_reg->make_mprofile (str, mprofile) != 0) { throw ::CORBA::INV_OBJREF ( CORBA::SystemException::_tao_minor_code ( 0, EINVAL), CORBA::COMPLETED_NO); } // Now make the TAO_Stub. TAO_Stub *data = this->orb_core_->create_stub ((char *) 0, mprofile); TAO_Stub_Auto_Ptr safe_objdata (data); // Figure out if the servant is collocated. CORBA::Object_ptr obj = this->orb_core_->create_object (safe_objdata.get ()); if (CORBA::is_nil (obj)) return CORBA::Object::_nil (); // Transfer ownership to the CORBA::Object (void) safe_objdata.release (); return obj; } // ************************************************************* // Valuetype factory operations // ************************************************************* #if !defined(CORBA_E_MICRO) CORBA::ValueFactory CORBA::ORB::register_value_factory (const char *repository_id, CORBA::ValueFactory factory) { TAO_Valuetype_Adapter *vta = this->orb_core ()->valuetype_adapter (); if (vta) { int const result = vta->vf_map_rebind (repository_id, factory); if (result == 0) // No previous factory found { return 0; } if (result == -1) { // Error on bind. throw ::CORBA::MARSHAL (); } } return factory; // previous factory was found } #endif #if !defined(CORBA_E_MICRO) void CORBA::ORB::unregister_value_factory (const char *repository_id) { TAO_Valuetype_Adapter *vta = this->orb_core ()->valuetype_adapter (); if (vta) { // Dont care whther it was successful or not! (void) vta->vf_map_unbind (repository_id); } } #endif #if !defined(CORBA_E_MICRO) CORBA::ValueFactory CORBA::ORB::lookup_value_factory (const char *repository_id) { TAO_Valuetype_Adapter *vta = this->orb_core ()->valuetype_adapter (); if (vta) { return vta->vf_map_find (repository_id); } return 0; } #endif TAO_END_VERSIONED_NAMESPACE_DECL