summaryrefslogtreecommitdiff
path: root/TAO/tao/IIOP_Connector.cpp
diff options
context:
space:
mode:
authorirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-07-07 23:58:34 +0000
committerirfan <irfan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2003-07-07 23:58:34 +0000
commitf17aa1c26ea86d00ec1cf57cbccdaea829ba0220 (patch)
tree8aaf3418082d4c3b107e2f01eedf0d55095c7ec7 /TAO/tao/IIOP_Connector.cpp
parentc5795bf619c5cd394920f8a03d475b60df8d8516 (diff)
downloadATCD-f17aa1c26ea86d00ec1cf57cbccdaea829ba0220.tar.gz
ChangeLogTag: Mon Jul 07 18:00:38 2003 Irfan Pyarali <irfan@oomworks.com>
Diffstat (limited to 'TAO/tao/IIOP_Connector.cpp')
-rw-r--r--TAO/tao/IIOP_Connector.cpp321
1 files changed, 195 insertions, 126 deletions
diff --git a/TAO/tao/IIOP_Connector.cpp b/TAO/tao/IIOP_Connector.cpp
index feaaeede5f9..fa3c81b0d21 100644
--- a/TAO/tao/IIOP_Connector.cpp
+++ b/TAO/tao/IIOP_Connector.cpp
@@ -15,25 +15,17 @@
#include "ace/Strategies_T.h"
-
ACE_RCSID (TAO,
IIOP_Connector,
"$Id$")
-
#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class TAO_Connect_Concurrency_Strategy<TAO_IIOP_Connection_Handler>;
template class TAO_Connect_Creation_Strategy<TAO_IIOP_Connection_Handler>;
template class ACE_Strategy_Connector<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>;
template class ACE_Connect_Strategy<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>;
template class ACE_Connector<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>;
-template class ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>;
-
-template class ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<TAO_IIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>;
-template class ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<TAO_IIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>;
-template class ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*>;
-template class ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>;
-template class ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>;
+template class ACE_NonBlocking_Connect_Handler<TAO_IIOP_Connection_Handler>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
@@ -42,17 +34,10 @@ template class ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connec
#pragma instantiate ACE_Strategy_Connector<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>
#pragma instantiate ACE_Connect_Strategy<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>
#pragma instantiate ACE_Connector<TAO_IIOP_Connection_Handler, ACE_SOCK_CONNECTOR>
-#pragma instantiate ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>
-
-#pragma instantiate ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<TAO_IIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>
-#pragma instantiate ACE_Map_Iterator_Base<ACE_HANDLE, ACE_Svc_Tuple<TAO_IIOP_Connection_Handler> *, TAO_SYNCH_RW_MUTEX>
-#pragma instantiate ACE_Map_Entry<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*>
-#pragma instantiate ACE_Map_Iterator<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>
-#pragma instantiate ACE_Map_Reverse_Iterator<ACE_HANDLE,ACE_Svc_Tuple<TAO_IIOP_Connection_Handler>*,TAO_SYNCH_RW_MUTEX>
+#pragma instantiate ACE_NonBlocking_Connect_Handler<TAO_IIOP_Connection_Handler>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
-
TAO_IIOP_Connector::TAO_IIOP_Connector (CORBA::Boolean flag)
: TAO_Connector (IOP::TAG_INTERNET_IOP),
lite_flag_ (flag),
@@ -154,130 +139,214 @@ TAO_IIOP_Connector::make_connection (TAO_GIOP_Invocation *invocation,
TAO_IIOP_Endpoint *iiop_endpoint =
this->remote_endpoint (desc->endpoint ());
- if (iiop_endpoint == 0)
- return -1;
-
- 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>\n",
- iiop_endpoint->host(), iiop_endpoint->port()));
-
- // Get the right synch options
- ACE_Synch_Options synch_options;
-
- this->active_connect_strategy_->synch_options (max_wait_time,
- synch_options);
-
- TAO_IIOP_Connection_Handler *svc_handler = 0;
-
- // Active connect
- int result = this->base_connector_.connect (svc_handler,
- remote_address,
- synch_options);
-
-
- 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 ()));
-
- result =
- this->active_connect_strategy_->wait (svc_handler,
- max_wait_time);
-
- if (TAO_debug_level > 2)
- {
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection"
- "wait done for handle[%d], result = %d\n",
- svc_handler->get_handle (), result));
- }
-
- }
-
- int status =
- svc_handler->is_finalized ();
-
- // Reduce the refcount to the svc_handler that we have. The
- // increment to the handler is done in make_svc_handler (). Now
- // that we dont need the reference to it anymore we can decrement
- // the refcount whether the connection is successful ot not.
-
- // REFCNT: Matches with TAO_Connect_Strategy<>::make_svc_handler()
- long refcount = svc_handler->decr_refcount ();
+ if (iiop_endpoint == 0)
+ return -1;
- ACE_ASSERT (refcount >= 0);
+ 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>\n",
+ iiop_endpoint->host(), iiop_endpoint->port()));
+
+ // Get the right synch options
+ ACE_Synch_Options synch_options;
+
+ this->active_connect_strategy_->synch_options (max_wait_time,
+ synch_options);
+
+ TAO_IIOP_Connection_Handler *svc_handler = 0;
+
+ // Connect.
+ int result =
+ this->base_connector_.connect (svc_handler,
+ remote_address,
+ synch_options);
+
+ // The connect() method creates the service handler and bumps the
+ // #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.
+ //
+ // The extra reference count in
+ // TAO_Connect_Creation_Strategy::make_svc_handler() is needed in
+ // the case when connection completion is pending and we are going
+ // to wait on a variable in the handler to changes, signifying
+ // success or failure. Note, that this increment cannot be done
+ // once the connect() returns since this might be too late if
+ // another thread pick up the completion and potentially deletes the
+ // handler before we get a chance to increment the reference count.
+
+ // 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 ()));
+
+ // Wait for connection completion. No need to specify timeout
+ // to wait() since the correct timeout was passed to the
+ // Connector. The Connector will close the handler in the case
+ // of timeouts, so the event will complete (either success or
+ // failure) within timeout.
+ result =
+ this->active_connect_strategy_->wait (svc_handler,
+ 0);
+
+ if (TAO_debug_level > 2)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "TAO (%P|%t) - IIOP_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.
+ 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 ();
+ }
+ }
+ }
+ }
- ACE_UNUSED_ARG (refcount);
+ // Irrespective of success or failure, remove the extra #REFCOUNT#.
+ svc_handler->remove_reference ();
- if (result == -1)
- {
- // Give users a clue to the problem.
- 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 (),
- "errno"));
- }
+ // 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) - IIOP_Connector::make_connection, "
+ "connection to <%s:%d> failed (%p)\n",
+ iiop_endpoint->host (), iiop_endpoint->port (),
+ "errno"));
+ }
+
+ return -1;
+ }
- (void) this->active_connect_strategy_->post_failed_connect (svc_handler,
- status);
+ // 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 connection to <%s:%d> on Transport[%d]\n",
+ 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);
+
+ // Failure in adding to cache.
+ if (retval != 0)
+ {
+ // Close the handler.
+ svc_handler->close ();
- return -1;
- }
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "could not add the new connection to cache\n"));
+ }
- if (TAO_debug_level > 2)
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection, "
- "new connection to <%s:%d> on Transport[%d]\n",
- iiop_endpoint->host (), iiop_endpoint->port (),
- svc_handler->peer ().get_handle ()));
+ return -1;
+ }
- TAO_Transport *base_transport =
- TAO_Transport::_duplicate (svc_handler->transport ());
+ // 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 ();
- // Add the handler to Cache
- int retval =
- this->orb_core ()->lane_resources ().transport_cache ().cache_transport (desc,
- base_transport);
+ // Registration failures.
+ if (retval != 0)
+ {
+ // Purge from the connection cache.
+ transport->purge_entry ();
- if (retval != 0 && TAO_debug_level > 0)
- {
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection, "
- "could not add the new connection to cache\n"));
- }
+ // Close the handler.
+ svc_handler->close ();
- // If the wait strategy wants us to be registered with the reactor
- // then we do so.
- retval = base_transport->wait_strategy ()->register_handler ();
+ if (TAO_debug_level > 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "TAO (%P|%t) - IIOP_Connector::make_connection, "
+ "could not register the new connection in the reactor\n"));
+ }
- if (retval != 0 && TAO_debug_level > 0)
- {
- ACE_DEBUG ((LM_DEBUG,
- "TAO (%P|%t) - IIOP_Connector::make_connection, "
- "could not register the new connection in the reactor\n"));
- }
+ return -1;
+ }
- // Handover the transport pointer to the Invocation class.
- TAO_Transport *&transport = invocation->transport ();
- transport = base_transport;
+ // Handover the transport pointer to the Invocation class.
+ TAO_Transport *&invocation_transport =
+ invocation->transport ();
+ invocation_transport = transport;
- return 0;
+ return 0;
}
-
-
TAO_Profile *
TAO_IIOP_Connector::create_profile (TAO_InputCDR& cdr)
{