summaryrefslogtreecommitdiff
path: root/TAO/tao/IIOP_Connector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/tao/IIOP_Connector.cpp')
-rw-r--r--TAO/tao/IIOP_Connector.cpp227
1 files changed, 123 insertions, 104 deletions
diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp
index 8deb1c31355..618ff481ad7 100644
--- a/TAO/tao/IIOP_Connector.cpp
+++ b/TAO/tao/IIOP_Connector.cpp
@@ -6,10 +6,8 @@
#include "Protocols_Hooks.h"
#include "Connect_Strategy.h"
#include "Thread_Lane_Resources.h"
-#include "Profile_Transport_Resolver.h"
#include "Transport.h"
#include "Wait_Strategy.h"
-#include "SystemException.h"
#include "ace/OS_NS_strings.h"
#include "ace/OS_NS_string.h"
@@ -56,7 +54,7 @@ int
TAO_IIOP_Connector::open (TAO_ORB_Core *orb_core)
{
// @@todo: The functionality of the following two statements could
- // be done in the constructor, but that involves changing the
+ // be done in the constructor, but that involves changing the
// interface of the pluggable transport factory.
// Set the ORB Core
@@ -134,42 +132,32 @@ TAO_IIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint)
}
TAO_Transport *
-TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
+TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *,
TAO_Transport_Descriptor_Interface &desc,
- ACE_Time_Value *timeout)
+ ACE_Time_Value *max_wait_time)
{
- TAO_IIOP_Endpoint *iiop_endpoint =
- this->remote_endpoint (desc.endpoint ());
+ TAO_IIOP_Endpoint *iiop_endpoint = this->remote_endpoint (desc.endpoint ());
if (iiop_endpoint == 0)
return 0;
- const ACE_INET_Addr &remote_address =
- iiop_endpoint->object_addr ();
+ const ACE_INET_Addr &remote_address = iiop_endpoint->object_addr ();
if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection, "
- "to <%s:%d> which should %s\n",
- ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()),
- iiop_endpoint->port(),
- r->blocked () ? ACE_TEXT("block") : ACE_TEXT("nonblock")));
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "to <%s:%d>\n",
+ ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host()),
+ iiop_endpoint->port()));
+ }
// Get the right synch options
ACE_Synch_Options synch_options;
- this->active_connect_strategy_->synch_options (timeout,
+ this->active_connect_strategy_->synch_options (max_wait_time,
synch_options);
- // If we don't need to block for a transport just set the timeout to
- // be zero.
- ACE_Time_Value tmp_zero (ACE_Time_Value::zero);
- if (!r->blocked ())
- {
- synch_options.timeout (ACE_Time_Value::zero);
- timeout = &tmp_zero;
- }
-
TAO_IIOP_Connection_Handler *svc_handler = 0;
// Connect.
@@ -179,14 +167,13 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
synch_options);
// The connect() method creates the service handler and bumps the
- // #REFCOUNT# up one extra. There are four possibilities from
+ // #REFCOUNT# up one extra. There are three possibilities from
// calling connect(): (a) connection succeeds immediately - in this
// case, the #REFCOUNT# on the handler is two; (b) connection
// completion is pending - in this case, the #REFCOUNT# on the
// handler is also two; (c) connection fails immediately - in this
// case, the #REFCOUNT# on the handler is one since close() gets
- // called on the handler; (d) the connect immediately returns when we
- // have specified that it shouldn't block.
+ // called on the handler.
//
// The extra reference count in
// TAO_Connect_Creation_Strategy::make_svc_handler() is needed in
@@ -197,67 +184,118 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
// another thread pick up the completion and potentially deletes the
// handler before we get a chance to increment the reference count.
- // Make sure that we always do a remove_reference
- ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler);
+ // No immediate result. Wait for completion.
+ if (result == -1 && errno == EWOULDBLOCK)
+ {
+ if (TAO_debug_level > 2)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "going to wait for connection completion on local"
+ "handle [%d]\n",
+ svc_handler->get_handle ()));
+ }
- TAO_Transport *transport =
- svc_handler->transport ();
+ // Wait for connection completion.
+ result =
+ this->active_connect_strategy_->wait (svc_handler,
+ max_wait_time);
- if (result == -1)
- {
- // No immediate result, wait for completion
- if (errno == EWOULDBLOCK)
+ if (TAO_debug_level > 2)
{
- // Try to wait until connection completion. Incase we block, then we
- // get a connected transport or not. In case of non block we get
- // a connected or not connected transport
- if (!this->wait_for_connection_completion (r,
- transport,
- timeout))
- {
- if (TAO_debug_level > 2)
- ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - IIOP_Connector::"
- "make_connection, "
- "wait for completion failed\n"));
- }
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_Connector::make_connection"
+ "wait done for handle[%d], result = %d\n",
+ svc_handler->get_handle (), result));
}
- else
+
+ // There are three possibilities when wait() returns: (a)
+ // connection succeeded; (b) connection failed; (c) wait()
+ // failed because of some other error. It is easy to deal with
+ // (a) and (b). (c) is tricky since the connection is still
+ // pending and may get completed by some other thread. The
+ // following code deals with (c).
+
+ // Check if the handler has been closed.
+ int closed =
+ svc_handler->is_closed ();
+
+ // In case of failures and close() has not be called.
+ if (result == -1 && !closed)
{
- // Transport is not usable
- transport = 0;
+ // First, cancel from connector.
+ this->base_connector_.cancel (svc_handler);
+
+ // Double check to make sure the handler has not been closed
+ // yet. This double check is required to ensure that the
+ // connection handler was not closed yet by some other
+ // thread since it was still registered with the connector.
+ // Once connector.cancel() has been processed, we are
+ // assured that the connector will no longer open/close this
+ // handler.
+ closed = svc_handler->is_closed ();
+
+ // If closed, there is nothing to do here. If not closed,
+ // it was either opened or is still pending.
+ if (!closed)
+ {
+ // Check if the handler has been opened.
+ const int open = svc_handler->is_open ();
+
+ // Some other thread was able to open the handler even
+ // though wait failed for this thread.
+ if (open)
+ // Overwrite <result>.
+ result = 0;
+ else
+ {
+ // Assert that it is still connecting.
+ ACE_ASSERT (svc_handler->is_connecting ());
+
+ // Force close the handler now.
+ svc_handler->close ();
+ }
+ }
}
}
- // In case of errors transport is zero
- if (transport == 0)
+ // Irrespective of success or failure, remove the extra #REFCOUNT#.
+ svc_handler->remove_reference ();
+
+ // In case of errors.
+ if (result == -1)
{
// Give users a clue to the problem.
- if (TAO_debug_level > 3)
+ if (TAO_debug_level)
+ {
ACE_DEBUG ((LM_ERROR,
"TAO (%P|%t) - IIOP_Connector::make_connection, "
"connection to <%s:%d> failed (%p)\n",
- iiop_endpoint->host (), iiop_endpoint->port (),
+ ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host ()), iiop_endpoint->port (),
ACE_TEXT("errno")));
+ }
return 0;
}
- // At this point, the connection has be successfully created
- // connected or not connected, but we have a connection.
+ // At this point, the connection has be successfully connected.
+ // #REFCOUNT# is one.
if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection, "
- "new %s connection to <%s:%d> on Transport[%d]\n",
- transport->is_connected() ? "connected" : "not connected",
- iiop_endpoint->host (),
- iiop_endpoint->port (),
- svc_handler->peer ().get_handle ()));
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "new connection to <%s:%d> on Transport[%d]\n",
+ ACE_TEXT_CHAR_TO_TCHAR(iiop_endpoint->host ()),
+ iiop_endpoint->port (),
+ svc_handler->peer ().get_handle ()));
+ }
+
+ TAO_Transport *transport = svc_handler->transport ();
// Add the handler to Cache
int retval =
- this->orb_core ()->lane_resources ().transport_cache ().cache_transport (
- &desc,
- transport);
+ this->orb_core ()->lane_resources ().transport_cache ().cache_transport (&desc,
+ transport);
// Failure in adding to cache.
if (retval != 0)
@@ -275,24 +313,26 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
return 0;
}
- if (transport->is_connected () &&
- transport->wait_strategy ()->register_handler () != 0)
- {
- // Registration failures.
+ // If the wait strategy wants us to be registered with the reactor
+ // then we do so. If registeration is required and it succeeds,
+ // #REFCOUNT# becomes two.
+ retval = transport->wait_strategy ()->register_handler ();
- // Purge from the connection cache, if we are not in the cache, this
- // just does nothing.
- (void) transport->purge_entry ();
+ // Registration failures.
+ if (retval != 0)
+ {
+ // Purge from the connection cache.
+ transport->purge_entry ();
// Close the handler.
- (void) transport->close_connection ();
+ svc_handler->close ();
if (TAO_debug_level > 0)
- ACE_ERROR ((LM_ERROR,
- "TAO (%P|%t) - IIOP_Connector [%d]::make_connection, "
- "could not register the transport "
- "in the reactor.\n",
- transport->id ()));
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "could not register the new connection in the reactor\n"));
+ }
return 0;
}
@@ -303,7 +343,7 @@ TAO_IIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r,
TAO_Profile *
TAO_IIOP_Connector::create_profile (TAO_InputCDR& cdr)
{
- TAO_Profile *pfile = 0;
+ TAO_Profile *pfile;
ACE_NEW_RETURN (pfile,
TAO_IIOP_Profile (this->orb_core ()),
0);
@@ -331,7 +371,7 @@ TAO_IIOP_Connector::make_profile (ACE_ENV_SINGLE_ARG_DECL)
TAO_IIOP_Profile (this->orb_core ()),
CORBA::NO_MEMORY (
CORBA::SystemException::_tao_minor_code (
- 0,
+ TAO_DEFAULT_MINOR_CODE,
ENOMEM),
CORBA::COMPLETED_NO));
ACE_CHECK_RETURN (0);
@@ -395,8 +435,7 @@ TAO_IIOP_Connector::init_tcp_properties (void)
int no_delay = this->orb_core ()->orb_params ()->nodelay ();
int enable_network_priority = 0;
- TAO_Protocols_Hooks *tph =
- this->orb_core ()->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER);
+ TAO_Protocols_Hooks *tph = this->orb_core ()->get_protocols_hooks (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_CHECK_RETURN (-1);
if (tph != 0)
@@ -443,23 +482,3 @@ TAO_IIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint)
return iiop_endpoint;
}
-
-int
-TAO_IIOP_Connector::cancel_svc_handler (
- TAO_Connection_Handler * svc_handler)
-{
- TAO_IIOP_Connection_Handler* handler=
- dynamic_cast<TAO_IIOP_Connection_Handler*>(svc_handler);
-
- if (handler)
- {
- // Cancel from the connector
- this->base_connector_.cancel (handler);
-
- return 0;
- }
- else
- {
- return -1;
- }
-}