diff options
Diffstat (limited to 'trunk/TAO/tao/Profile_Transport_Resolver.cpp')
-rw-r--r-- | trunk/TAO/tao/Profile_Transport_Resolver.cpp | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/trunk/TAO/tao/Profile_Transport_Resolver.cpp b/trunk/TAO/tao/Profile_Transport_Resolver.cpp new file mode 100644 index 00000000000..0a6026f543c --- /dev/null +++ b/trunk/TAO/tao/Profile_Transport_Resolver.cpp @@ -0,0 +1,285 @@ +// $Id$ + +#include "tao/Profile_Transport_Resolver.h" +#include "tao/Profile.h" +#include "tao/Stub.h" +#include "tao/Transport.h" +#include "tao/Invocation_Endpoint_Selectors.h" +#include "tao/ORB_Core.h" +#include "tao/Thread_Lane_Resources.h" +#include "tao/Transport_Cache_Manager.h" +#include "tao/Endpoint_Selector_Factory.h" +#include "tao/Codeset_Manager.h" +#include "tao/Connector_Registry.h" +#include "tao/Transport_Connector.h" +#include "tao/Endpoint.h" +#include "tao/SystemException.h" +#include "tao/Client_Strategy_Factory.h" + +#include "ace/Countdown_Time.h" + +#if !defined (__ACE_INLINE__) +# include "tao/Profile_Transport_Resolver.inl" +#endif /* __ACE_INLINE__ */ + +ACE_RCSID (tao, + Profile_Transport_Resolver, + "$Id$") + + +TAO_BEGIN_VERSIONED_NAMESPACE_DECL + +namespace TAO +{ + + Profile_Transport_Resolver::~Profile_Transport_Resolver (void) + { + if (this->profile_) + { + this->profile_->_decr_refcnt (); + } + + if (this->transport_.get ()) + { + if (this->is_released_ == false) + { + this->transport_->make_idle (); + } + + this->transport_->remove_reference (); + } + + delete this->inconsistent_policies_; + } + + void + Profile_Transport_Resolver::profile (TAO_Profile *p) + { + // Dont do anything if the incoming profile is null + if (p) + { + // @note This is just a workaround for a more serious problem + // with profile management. This would cover some potential + // issues that Ossama is working on. Ossama, please remove + // them when you are done. + TAO_Profile *tmp = this->profile_; + + (void) p->_incr_refcnt (); + this->profile_ = p; + + if (tmp) + { + (void) tmp->_decr_refcnt (); + } + } + } + + + void + Profile_Transport_Resolver::resolve (ACE_Time_Value *max_time_val + ACE_ENV_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + ACE_Countdown_Time countdown (max_time_val); + + TAO_Invocation_Endpoint_Selector *es = + this->stub_->orb_core ()->endpoint_selector_factory ()->get_selector ( + ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK; + + // Select the endpoint + es->select_endpoint (this, + max_time_val + ACE_ENV_ARG_PARAMETER); + ACE_CHECK; + + if (this->transport_.get () == 0) + { + ACE_THROW (CORBA::INTERNAL ()); + } + + const TAO_GIOP_Message_Version& version = + this->profile_->version (); + + // Initialize the messaging object + if (this->transport_->messaging_init (version.major, version.minor) == -1) + { + ACE_THROW (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + 0, + EINVAL), + CORBA::COMPLETED_NO)); + } + + if (!this->transport_->is_tcs_set ()) + { + TAO_Codeset_Manager * const tcm = + this->stub_->orb_core ()->codeset_manager (); + if (tcm) + tcm->set_tcs (*this->profile_, *this->transport_); + } + } + + bool + Profile_Transport_Resolver::try_connect ( + TAO_Transport_Descriptor_Interface *desc, + ACE_Time_Value *timeout + ACE_ENV_ARG_DECL + ) + { + return this->try_connect_i (desc, timeout, 0 ACE_ENV_ARG_PARAMETER); + } + + bool + Profile_Transport_Resolver::try_parallel_connect ( + TAO_Transport_Descriptor_Interface *desc, + ACE_Time_Value *timeout + ACE_ENV_ARG_DECL + ) + { + return this->try_connect_i (desc, timeout, 1 ACE_ENV_ARG_PARAMETER); + } + + + bool + Profile_Transport_Resolver::try_connect_i ( + TAO_Transport_Descriptor_Interface *desc, + ACE_Time_Value *timeout, + bool parallel + ACE_ENV_ARG_DECL + ) + { + TAO_Connector_Registry *conn_reg = + this->stub_->orb_core ()->connector_registry ( + ACE_ENV_SINGLE_ARG_PARAMETER); + ACE_CHECK_RETURN (false); + + if (conn_reg == 0) + { + ACE_THROW_RETURN (CORBA::INTERNAL ( + CORBA::SystemException::_tao_minor_code ( + 0, + EINVAL), + CORBA::COMPLETED_NO), + false); + } + + ACE_Time_Value connection_timeout; + bool has_con_timeout = this->get_connection_timeout (connection_timeout); + + if (has_con_timeout && !this->blocked_) + { + timeout = &connection_timeout; + } + else if (has_con_timeout) + { + if (timeout == 0 || connection_timeout < *timeout) + timeout = &connection_timeout; + else + has_con_timeout = false; + } + else if (!this->blocked_) + { + timeout = 0; + } + + TAO_Connector *con = conn_reg->get_connector (desc->endpoint ()->tag ()); + ACE_ASSERT(con != 0); + if (parallel) + { + this->transport_.set (con->parallel_connect (this, desc, timeout + ACE_ENV_ARG_PARAMETER)); + } + else + { + this->transport_.set (con->connect (this, desc, timeout + ACE_ENV_ARG_PARAMETER)); + } + ACE_CHECK_RETURN (false); + // A timeout error occurred. + // If the user has set a roundtrip timeout policy, throw a timeout + // exception. Otherwise, just fall through and return false to + // look at the next endpoint. + if (this->transport_.get () == 0 && + has_con_timeout == false && + errno == ETIME) + { + ACE_THROW_RETURN (CORBA::TIMEOUT ( + CORBA::SystemException::_tao_minor_code ( + TAO_TIMEOUT_CONNECT_MINOR_CODE, + errno), + CORBA::COMPLETED_NO), + false); + } + else if (this->transport_.get () == 0) + { + return false; + } + + return true; + } + + bool + Profile_Transport_Resolver::use_parallel_connect (void) const + { + TAO_ORB_Core *oc = this->stub_->orb_core(); + return (oc->orb_params()->use_parallel_connects() +#if 0 // it was decided that even with blocked connects + // parallel connects could be useful, at least for cache + // processing. + oc->client_factory()->connect_strategy() != + TAO_Client_Strategy_Factory::TAO_BLOCKED_CONNECT +#endif /* 0 */ + ); + } + + bool + Profile_Transport_Resolver::get_connection_timeout ( + ACE_Time_Value &max_wait_time) + { + bool is_conn_timeout = false; + + // Check for the connection timout policy in the ORB + this->stub_->orb_core ()->connection_timeout (this->stub_, + is_conn_timeout, + max_wait_time); + + return is_conn_timeout; + } + + + void + Profile_Transport_Resolver::init_inconsistent_policies ( + ACE_ENV_SINGLE_ARG_DECL) + ACE_THROW_SPEC ((CORBA::SystemException)) + { + ACE_NEW_THROW_EX (this->inconsistent_policies_, + CORBA::PolicyList (0), + CORBA::NO_MEMORY ( + CORBA::SystemException::_tao_minor_code ( + 0, + ENOMEM), + CORBA::COMPLETED_NO)); + } + + + int + Profile_Transport_Resolver::find_transport (TAO_Transport_Descriptor_Interface *desc) + { + TAO::Transport_Cache_Manager & cache = + this->profile_->orb_core()->lane_resources ().transport_cache(); + + // the cache increments the reference count on the transport if + // the find is successful. Cache.find_transport returns 0 on success. + // but we want to return a "boolean" of 0 for failure, 1 for success. + TAO_Transport* tmp = this->transport_.get (); + if (cache.find_transport(desc, tmp) != 0) + return 0; + + this->transport_.set (tmp); + return 1; + } + +} + +TAO_END_VERSIONED_NAMESPACE_DECL |