diff options
Diffstat (limited to 'TAO/tao/Strategies')
-rw-r--r-- | TAO/tao/Strategies/DIOP_Connection_Handler.cpp | 22 | ||||
-rw-r--r-- | TAO/tao/Strategies/DIOP_Connector.cpp | 10 | ||||
-rw-r--r-- | TAO/tao/Strategies/DIOP_Connector.h | 3 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Connection_Handler.cpp | 25 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Connector.cpp | 192 | ||||
-rw-r--r-- | TAO/tao/Strategies/SCIOP_Connector.h | 6 | ||||
-rw-r--r-- | TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp | 22 | ||||
-rw-r--r-- | TAO/tao/Strategies/SHMIOP_Connector.cpp | 61 | ||||
-rw-r--r-- | TAO/tao/Strategies/SHMIOP_Connector.h | 3 | ||||
-rw-r--r-- | TAO/tao/Strategies/UIOP_Connection_Handler.cpp | 22 | ||||
-rw-r--r-- | TAO/tao/Strategies/UIOP_Connector.cpp | 190 | ||||
-rw-r--r-- | TAO/tao/Strategies/UIOP_Connector.h | 3 |
12 files changed, 289 insertions, 270 deletions
diff --git a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp index 8854b94696e..bba8297505f 100644 --- a/TAO/tao/Strategies/DIOP_Connection_Handler.cpp +++ b/TAO/tao/Strategies/DIOP_Connection_Handler.cpp @@ -124,11 +124,8 @@ TAO_DIOP_Connection_Handler::open (void*) this->local_addr_.get_port_number ())); } - // Set that the transport is now connected, if fails we return -1 - // Use C-style cast b/c otherwise we get warnings on lots of - // compilers - if (!this->transport ()->post_open ((size_t) this->get_handle ())) - return -1; + // Set the id in the transport now that we're active. + this->transport ()->id ((size_t) this->get_handle ()); this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -169,7 +166,16 @@ TAO_DIOP_Connection_Handler::close_connection (void) int TAO_DIOP_Connection_Handler::handle_input (ACE_HANDLE h) { - return this->handle_input_eh (h, this); + int result = + this->handle_input_eh (h, this); + + if (result == -1) + { + this->close_connection (); + return 0; + } + + return result; } int @@ -212,7 +218,9 @@ TAO_DIOP_Connection_Handler::handle_close (ACE_HANDLE, int TAO_DIOP_Connection_Handler::close (u_long) { - return this->close_handler (); + this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + this->transport ()->remove_reference (); + return 0; } int diff --git a/TAO/tao/Strategies/DIOP_Connector.cpp b/TAO/tao/Strategies/DIOP_Connector.cpp index a082ce439ed..918e70d6d7f 100644 --- a/TAO/tao/Strategies/DIOP_Connector.cpp +++ b/TAO/tao/Strategies/DIOP_Connector.cpp @@ -258,16 +258,6 @@ TAO_DIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint) return diop_endpoint; } -int -TAO_DIOP_Connector::cancel_svc_handler ( - TAO_Connection_Handler * svc_handler) -{ - ACE_UNUSED_ARG(svc_handler); - - // Noop - return 0; -} - // **************************************************************** diff --git a/TAO/tao/Strategies/DIOP_Connector.h b/TAO/tao/Strategies/DIOP_Connector.h index 389875fa03a..4fe4ba07c0d 100644 --- a/TAO/tao/Strategies/DIOP_Connector.h +++ b/TAO/tao/Strategies/DIOP_Connector.h @@ -89,9 +89,6 @@ protected: /// initialize <tcp_properties_>. int init_tcp_properties (void); - /// Cancel the passed cvs handler from the connector - int cancel_svc_handler (TAO_Connection_Handler * svc_handler); - protected: /// TCP configuration properties to be used for all diff --git a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp index 60d586cef75..39d4a1125a6 100644 --- a/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp +++ b/TAO/tao/Strategies/SCIOP_Connection_Handler.cpp @@ -154,16 +154,14 @@ TAO_SCIOP_Connection_Handler::open (void*) return -1; ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) - SCIOP_Connection_Handler::open, SCIOP ") + ACE_TEXT ("TAO (%P|%t) - Connection_Handler::open, SCIOP ") ACE_TEXT ("connection to peer <%s> on %d\n"), client, this->peer ().get_handle ())); } - // Set that the transport is now connected, if fails we return -1 - // Use C-style cast b/c otherwise we get warnings on lots of - // compilers - if (!this->transport ()->post_open ((size_t) this->get_handle ())) - return -1; + // Set the id in the transport now that we're active. + // Use C-style cast b/c otherwise we get warnings on lots of compilers + this->transport ()->id ((size_t) this->get_handle ()); this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -185,7 +183,16 @@ TAO_SCIOP_Connection_Handler::close_connection (void) int TAO_SCIOP_Connection_Handler::handle_input (ACE_HANDLE h) { - return this->handle_input_eh (h, this); + int result = + this->handle_input_eh (h, this); + + if (result == -1) + { + this->close_connection (); + return 0; + } + + return result; } int @@ -224,7 +231,9 @@ TAO_SCIOP_Connection_Handler::handle_close (ACE_HANDLE, int TAO_SCIOP_Connection_Handler::close (u_long) { - return this->close_handler (); + this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + this->transport ()->remove_reference (); + return 0; } int diff --git a/TAO/tao/Strategies/SCIOP_Connector.cpp b/TAO/tao/Strategies/SCIOP_Connector.cpp index 2911873f0cd..e387d532ca2 100644 --- a/TAO/tao/Strategies/SCIOP_Connector.cpp +++ b/TAO/tao/Strategies/SCIOP_Connector.cpp @@ -14,7 +14,6 @@ #include "tao/Thread_Lane_Resources.h" #include "tao/Transport.h" #include "tao/Wait_Strategy.h" -#include "tao/Profile_Transport_Resolver.h" #include "ace/OS_NS_strings.h" #include "ace/Strategies_T.h" @@ -153,9 +152,9 @@ TAO_SCIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint) } TAO_Transport * -TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, +TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, TAO_Transport_Descriptor_Interface &desc, - ACE_Time_Value *timeout) + ACE_Time_Value *max_wait_time) { TAO_Endpoint *tao_endpoint = desc.endpoint (); @@ -164,7 +163,7 @@ TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, while (tao_endpoint != 0) { TAO_SCIOP_Endpoint *sciop_endpoint = this->remote_endpoint (tao_endpoint); if (sciop_endpoint != 0) { - transport = make_connection_i (r, desc, timeout, sciop_endpoint); + transport = make_connection_i (desc, max_wait_time, sciop_endpoint); if (transport) { break; } @@ -177,37 +176,26 @@ TAO_SCIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, TAO_Transport * -TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, - TAO_Transport_Descriptor_Interface &desc, - ACE_Time_Value *timeout, +TAO_SCIOP_Connector::make_connection_i (TAO_Transport_Descriptor_Interface &desc, + ACE_Time_Value *max_wait_time, TAO_SCIOP_Endpoint *sciop_endpoint) { const ACE_INET_Addr &remote_address = sciop_endpoint->object_addr (); - if (TAO_debug_level > 2) - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - SCIOP_Connector::make_connection_i, " - "to <%s:%d> which should %s\n", - ACE_TEXT_CHAR_TO_TCHAR(sciop_endpoint->host()), - sciop_endpoint->port(), - r->blocked () ? ACE_TEXT("block") : ACE_TEXT("nonblock"))); + if (TAO_debug_level > 2) { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - SCIOP_Connector::make_connection_i, " + "to <%s:%d>\n", + sciop_endpoint->host(), sciop_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_SCIOP_Connection_Handler *svc_handler = 0; // Connect. @@ -237,45 +225,93 @@ TAO_SCIOP_Connector::make_connection_i (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) - SCIOP_Connector::make_connection, " + "going to wait for connection completion on local" + "handle [%d]\n", + svc_handler->get_handle ())); + + // Wait for connection completion. + result = + this->active_connect_strategy_->wait (svc_handler, + max_wait_time); + + if (TAO_debug_level > 2) + { + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - SCIOP_Connector::make_connection" + "wait done for handle[%d], result = %d\n", + svc_handler->get_handle (), result)); + } - TAO_Transport *transport = - svc_handler->transport (); + // 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). - if (result == -1) - { - // No immediate result, wait for completion - if (errno == EWOULDBLOCK) + // 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) { - // 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)) + // 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) { - if (TAO_debug_level > 2) - ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - SCIOP_Connector::" - "make_connection_i, " - "wait for completion failed\n")); + // Check if the handler has been opened. + 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 (); + } } - } - else - { - // Transport is not usable - transport = 0; - } + } } - // 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) { ACE_DEBUG ((LM_ERROR, - "TAO (%P|%t) - SCIOP_Connector::make_connection_i, " + "TAO (%P|%t) - SCIOP_Connector::make_connection, " "connection to <%s:%d> failed (%p)\n", sciop_endpoint->host (), sciop_endpoint->port (), "errno")); @@ -288,12 +324,14 @@ TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, // #REFCOUNT# is one. if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - SCIOP_Connector::make_connection_i, " - "new %s connection to <%s:%d> on Transport[%d]\n", - transport->is_connected() ? "connected" : "not connected", + "TAO (%P|%t) - SCIOP_Connector::make_connection, " + "new connection to <%s:%d> on Transport[%d]\n", sciop_endpoint->host (), sciop_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, @@ -308,31 +346,28 @@ TAO_SCIOP_Connector::make_connection_i (TAO::Profile_Transport_Resolver *r, if (TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - SCIOP_Connector::make_connection_i, " + "TAO (%P|%t) - SCIOP_Connector::make_connection, " "could not add the new connection to cache\n")); } return 0; } - if (transport->is_connected () && - transport->wait_strategy ()->register_handler () != 0) + // Registration failures. + if (retval != 0) { - // Registration failures. - - // Purge from the connection cache, if we are not in the cache, this - // just does nothing. - (void) transport->purge_entry (); + // 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) - SCIOP_Connector [%d]::make_connection_i, " - "could not register the transport " - "in the reactor.\n", - transport->id ())); + { + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - SCIOP_Connector::make_connection, " + "could not register the new connection in the reactor\n")); + } return 0; } @@ -483,25 +518,4 @@ TAO_SCIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint) return sciop_endpoint; } -int -TAO_SCIOP_Connector::cancel_svc_handler ( - TAO_Connection_Handler * svc_handler) -{ - TAO_SCIOP_Connection_Handler* handler= - dynamic_cast<TAO_SCIOP_Connection_Handler*>(svc_handler); - - if (handler) - { - // Cancel from the connector - this->base_connector_.cancel (handler); - - return 0; - } - else - { - return -1; - } -} - - #endif /* TAO_HAS_SCIOP == 1 */ diff --git a/TAO/tao/Strategies/SCIOP_Connector.h b/TAO/tao/Strategies/SCIOP_Connector.h index f307f27bc00..40f304f6085 100644 --- a/TAO/tao/Strategies/SCIOP_Connector.h +++ b/TAO/tao/Strategies/SCIOP_Connector.h @@ -100,9 +100,6 @@ protected: /// initialize <tcp_properties_>. int init_tcp_properties (void); - /// Cancel the passed cvs handler from the connector - int cancel_svc_handler (TAO_Connection_Handler * svc_handler); - protected: /// TCP configuration properties to be used for all @@ -119,8 +116,7 @@ private: TAO_SCIOP_Endpoint *remote_endpoint (TAO_Endpoint *ep); /// Try to make a connection to the next endpoint in the list. - TAO_Transport *make_connection_i (TAO::Profile_Transport_Resolver *r, - TAO_Transport_Descriptor_Interface &desc, + TAO_Transport *make_connection_i (TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *timeout, TAO_SCIOP_Endpoint *sciop_endpoint); diff --git a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp index cc3a4ae8b9d..298adc9ade2 100644 --- a/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp +++ b/TAO/tao/Strategies/SHMIOP_Connection_Handler.cpp @@ -115,11 +115,8 @@ TAO_SHMIOP_Connection_Handler::open (void*) client, this->peer ().get_handle ())); } - // Set that the transport is now connected, if fails we return -1 - // Use C-style cast b/c otherwise we get warnings on lots of - // compilers - if (!this->transport ()->post_open ((size_t) this->get_handle ())) - return -1; + // Set the id in the transport now that we're active. + this->transport ()->id ((size_t) this->get_handle ()); // Not needed, anyway this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -142,7 +139,16 @@ TAO_SHMIOP_Connection_Handler::close_connection (void) int TAO_SHMIOP_Connection_Handler::handle_input (ACE_HANDLE h) { - return this->handle_input_eh (h, this); + int result = + this->handle_input_eh (h, this); + + if (result == -1) + { + this->close_connection (); + return 0; + } + + return result; } int @@ -181,7 +187,9 @@ TAO_SHMIOP_Connection_Handler::handle_close (ACE_HANDLE, int TAO_SHMIOP_Connection_Handler::close (u_long) { - return this->close_handler (); + this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + this->transport ()->remove_reference (); + return 0; } int diff --git a/TAO/tao/Strategies/SHMIOP_Connector.cpp b/TAO/tao/Strategies/SHMIOP_Connector.cpp index eb1c042934b..1a674e31b71 100644 --- a/TAO/tao/Strategies/SHMIOP_Connector.cpp +++ b/TAO/tao/Strategies/SHMIOP_Connector.cpp @@ -155,7 +155,7 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, { if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) SHMIOP_Connector::make_connection - ") + ACE_TEXT ("TAO (%P|%t) Connector::connect - ") ACE_TEXT ("looking for SHMIOP connection.\n"))); TAO_SHMIOP_Endpoint *shmiop_endpoint = @@ -169,7 +169,7 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) SHMIOP_Connector::connect ") + ACE_TEXT ("(%P|%t) SHMIOP_Connector::connect ") ACE_TEXT ("making a new connection \n"))); // Get the right synch options @@ -193,8 +193,8 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, // We always use a blocking connection so the connection is never // pending. - // Make sure that we always do a remove_reference - ACE_Event_Handler_var svc_handler_auto_ptr (svc_handler); + // Irrespective of success or failure, remove the extra #REFCOUNT#. + svc_handler->remove_reference (); // In case of errors. if (result == -1) @@ -203,8 +203,8 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, if (TAO_debug_level > 0) { ACE_DEBUG ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) SHMIOP_Connector::make_connection, ") - ACE_TEXT ("connection to <%s:%u> failed (%p)\n"), + ACE_TEXT ("(%P|%t) %N:%l, connection to ") + ACE_TEXT ("<%s:%u> failed (%p)\n"), ACE_TEXT_CHAR_TO_TCHAR (shmiop_endpoint->host ()), shmiop_endpoint->port (), ACE_TEXT ("errno"))); @@ -247,24 +247,26 @@ TAO_SHMIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, 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) - SHMIOP_Connector [%d]::make_connection, " - "could not register the transport " - "in the reactor.\n", - transport->id ())); + { + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - SHMIOP_Connector::make_connection, " + "could not register the new connection in the reactor\n")); + } return 0; } @@ -360,25 +362,4 @@ TAO_SHMIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint) return shmiop_endpoint; } -int -TAO_SHMIOP_Connector::cancel_svc_handler ( - TAO_Connection_Handler * svc_handler) -{ - TAO_SHMIOP_Connection_Handler* handler= - dynamic_cast<TAO_SHMIOP_Connection_Handler*>(svc_handler); - - if (handler) - { - // Cancel from the connector - this->base_connector_.cancel (handler); - - return 0; - } - else - { - return -1; - } -} - - #endif /* TAO_HAS_SHMIOP && TAO_HAS_SHMIOP != 0 */ diff --git a/TAO/tao/Strategies/SHMIOP_Connector.h b/TAO/tao/Strategies/SHMIOP_Connector.h index d4b41468c55..fd29eca271d 100644 --- a/TAO/tao/Strategies/SHMIOP_Connector.h +++ b/TAO/tao/Strategies/SHMIOP_Connector.h @@ -102,9 +102,6 @@ protected: ACE_Time_Value *timeout = 0); virtual TAO_Profile *make_profile (ACE_ENV_SINGLE_ARG_DECL); - - /// Cancel the passed cvs handler from the connector - int cancel_svc_handler (TAO_Connection_Handler * svc_handler); //@} private: diff --git a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp index f3ad70d0fcd..7aa645abde1 100644 --- a/TAO/tao/Strategies/UIOP_Connection_Handler.cpp +++ b/TAO/tao/Strategies/UIOP_Connection_Handler.cpp @@ -97,11 +97,8 @@ TAO_UIOP_Connection_Handler::open (void*) ACE_TEXT ("<%s> on %d\n"), addr.get_path_name (), this->peer ().get_handle ())); - // Set that the transport is now connected, if fails we return -1 - // Use C-style cast b/c otherwise we get warnings on lots of - // compilers - if (!this->transport ()->post_open ((size_t) this->get_handle ())) - return -1; + // Set the id in the transport now that we're active. + this->transport ()->id ((size_t) this->get_handle ()); this->state_changed (TAO_LF_Event::LFS_SUCCESS); @@ -123,7 +120,16 @@ TAO_UIOP_Connection_Handler::close_connection (void) int TAO_UIOP_Connection_Handler::handle_input (ACE_HANDLE h) { - return this->handle_input_eh (h, this); + const int result = + this->handle_input_eh (h, this); + + if (result == -1) + { + this->close_connection (); + return 0; + } + + return result; } int @@ -162,7 +168,9 @@ TAO_UIOP_Connection_Handler::handle_close (ACE_HANDLE, int TAO_UIOP_Connection_Handler::close (u_long) { - return this->close_handler (); + this->state_changed (TAO_LF_Event::LFS_CONNECTION_CLOSED); + this->transport ()->remove_reference (); + return 0; } int diff --git a/TAO/tao/Strategies/UIOP_Connector.cpp b/TAO/tao/Strategies/UIOP_Connector.cpp index 9d1b9692ad9..d87dd885654 100644 --- a/TAO/tao/Strategies/UIOP_Connector.cpp +++ b/TAO/tao/Strategies/UIOP_Connector.cpp @@ -11,7 +11,6 @@ #include "tao/Transport_Cache_Manager.h" #include "tao/Thread_Lane_Resources.h" #include "tao/Connect_Strategy.h" -#include "tao/Profile_Transport_Resolver.h" #include "ace/OS_NS_strings.h" #include "ace/OS_NS_string.h" @@ -138,13 +137,13 @@ TAO_UIOP_Connector::set_validate_endpoint (TAO_Endpoint *endpoint) } TAO_Transport * -TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, +TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *, TAO_Transport_Descriptor_Interface &desc, ACE_Time_Value *max_wait_time) { if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) UIUP_Connector::make_connection, ") + ACE_TEXT ("TAO (%P|%t) Connector::connect - ") ACE_TEXT ("looking for UIOP connection.\n"))); TAO_UIOP_Endpoint *uiop_endpoint = @@ -158,7 +157,7 @@ TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, if (TAO_debug_level > 2) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) UIUP_Connector::make_connection, ") + ACE_TEXT ("(%P|%t) UIOP_Connector::connect ") ACE_TEXT ("making a new connection \n"))); // Get the right synch options @@ -167,15 +166,6 @@ TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, 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); - max_wait_time = &tmp_zero; - } - TAO_UIOP_Connection_Handler *svc_handler = 0; // Connect. @@ -201,61 +191,103 @@ TAO_UIOP_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); - - TAO_Transport *transport = - svc_handler->transport (); - - if (result == -1) + // No immediate result. Wait for completion. + if (result == -1 && errno == EWOULDBLOCK) { - // No immediate result, wait for completion - if (errno == EWOULDBLOCK) + if (TAO_debug_level > 2) + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - UIOP_Connector::make_connection, " + "going to wait for connection completion on local" + "handle [%d]\n", + svc_handler->get_handle ())); + + result = + this->active_connect_strategy_->wait (svc_handler, + max_wait_time); + + 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, - max_wait_time)) - { - if (TAO_debug_level > 2) - ACE_ERROR ((LM_ERROR, "TAO (%P|%t) - UIOP_Connector::" - "make_connection, " - "wait for completion failed\n")); - } - } - else - { - // Transport is not usable - transport = 0; + ACE_DEBUG ((LM_DEBUG, + "TAO (%P|%t) - UIOP_Connector::make_connection" + "wait done for handle[%d], result = %d\n", + svc_handler->get_handle (), + result)); } + + // 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) + { + // 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) - UIOP_Connector::make_connection, " - "connection to <%s> failed (%p)\n", + ACE_TEXT ("(%P|%t) %N:%l, connection to ") + ACE_TEXT ("%s failed (%p)\n"), uiop_endpoint->rendezvous_point (), - ACE_TEXT("errno"))); + ACE_TEXT ("errno"))); + } return 0; } + // At this point, the connection has be successfully connected. + // #REFCOUNT# is one. - // At this point, the connection has be successfully created - // connected or not connected, but we have a connection. - if (TAO_debug_level > 2) - ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - UIOP_Connector::make_connection, " - "new %s connection to <%s> on Transport[%d]\n", - transport->is_connected() ? "connected" : "not connected", - uiop_endpoint->rendezvous_point (), - svc_handler->peer ().get_handle ())); + TAO_Transport *transport = + svc_handler->transport (); // Add the handler to Cache int retval = @@ -270,31 +302,33 @@ TAO_UIOP_Connector::make_connection (TAO::Profile_Transport_Resolver *r, if (TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - ACE_TEXT ("TAO (%P|%t) UIOP_Connector::make_connection, ") + ACE_TEXT ("(%P|%t) UIOP_Connector::connect ") ACE_TEXT ("could not add the new connection to Cache \n"))); } 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) - UIOP_Connector [%d]::make_connection, " - "could not register the transport " - "in the reactor.\n", - transport->id ())); + { + ACE_ERROR ((LM_ERROR, + "TAO (%P|%t) - UIOP_Connector::make_connection, " + "could not register the new connection in the reactor\n")); + } return 0; } @@ -435,24 +469,4 @@ TAO_UIOP_Connector::remote_endpoint (TAO_Endpoint *endpoint) return uiop_endpoint; } -int -TAO_UIOP_Connector::cancel_svc_handler ( - TAO_Connection_Handler * svc_handler) -{ - TAO_UIOP_Connection_Handler* handler= - dynamic_cast<TAO_UIOP_Connection_Handler*>(svc_handler); - - if (handler) - { - // Cancel from the connector - this->base_connector_.cancel (handler); - - return 0; - } - else - { - return -1; - } -} - #endif /* TAO_HAS_UIOP == 1 */ diff --git a/TAO/tao/Strategies/UIOP_Connector.h b/TAO/tao/Strategies/UIOP_Connector.h index ba23060bd9d..d3297c8b3a8 100644 --- a/TAO/tao/Strategies/UIOP_Connector.h +++ b/TAO/tao/Strategies/UIOP_Connector.h @@ -73,9 +73,6 @@ public: virtual int check_prefix (const char *endpoint); virtual char object_key_delimiter (void) const; - - /// Cancel the passed cvs handler from the connector - virtual int cancel_svc_handler (TAO_Connection_Handler * svc_handler); //@} public: |