summaryrefslogtreecommitdiff
path: root/ace/Connector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ace/Connector.cpp')
-rw-r--r--ace/Connector.cpp187
1 files changed, 77 insertions, 110 deletions
diff --git a/ace/Connector.cpp b/ace/Connector.cpp
index c4a40988e59..f588b605462 100644
--- a/ace/Connector.cpp
+++ b/ace/Connector.cpp
@@ -1,10 +1,10 @@
-// Connector.cpp
// $Id$
-#ifndef ACE_CONNECTOR_C
-#define ACE_CONNECTOR_C
+#ifndef ACE_CONNECTOR_CPP
+#define ACE_CONNECTOR_CPP
#include "ace/Connector.h"
+#include "ace/ACE.h"
#include "ace/OS_NS_stdio.h"
#include "ace/OS_NS_string.h"
#include "ace/os_include/os_fcntl.h" /* Has ACE_NONBLOCK */
@@ -13,7 +13,7 @@
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
-ACE_RCSID(ace, Connector, "$Id$")
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
ACE_ALLOC_HOOK_DEFINE(ACE_Connector)
@@ -66,46 +66,6 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::dump (void) const
#endif /* ACE_HAS_DUMP */
}
-template <class SVC_HANDLER> SVC_HANDLER *
-ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (void)
-{
- // @@ TODO: This method should be removed after a couple of betas.
- SVC_HANDLER *svc_handler = 0;
-
- // Make sure that we haven't already initialized the Svc_Handler.
- if (this->svc_handler_)
- {
- // Exclusive access to the Reactor.
- ACE_GUARD_RETURN (ACE_Lock, ace_mon, this->reactor ()->lock (), 0);
-
- // Double check.
- if (this->svc_handler_)
- {
- // Remember the Svc_Handler.
- svc_handler = this->svc_handler_;
-
- // Remove from Reactor.
- this->reactor ()->remove_handler
- (this->svc_handler_->get_handle (),
- ACE_Event_Handler::ALL_EVENTS_MASK);
-
- // Cancel timer.
- this->reactor ()->cancel_timer
- (this->timer_id (), 0, 0);
-
- // Remove this handle from the set of non-blocking handles
- // in the Connector.
- this->connector_.non_blocking_handles ().clr_bit
- (this->svc_handler_->get_handle ());
-
- // We are done. Don't initialize the Svc_Handler again.
- this->svc_handler_ = 0;
- }
- }
-
- return svc_handler;
-}
-
template <class SVC_HANDLER> bool
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
{
@@ -126,14 +86,12 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
// Remember the Svc_Handler.
sh = this->svc_handler_;
-
+ ACE_HANDLE h = sh->get_handle ();
this->svc_handler_ = 0;
- // Remove from Reactor.
- if (this->reactor ()->remove_handler (
- sh->get_handle (),
- ACE_Event_Handler::ALL_EVENTS_MASK) == -1)
- return false;
+ // Remove this handle from the set of non-blocking handles
+ // in the Connector.
+ this->connector_.non_blocking_handles ().remove (h);
// Cancel timer.
if (this->reactor ()->cancel_timer (this->timer_id (),
@@ -141,10 +99,11 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
0) == -1)
return false;
- // Remove this handle from the set of non-blocking handles
- // in the Connector.
- this->connector_.non_blocking_handles ().clr_bit
- (sh->get_handle ());
+ // Remove from Reactor.
+ if (this->reactor ()->remove_handler (
+ h,
+ ACE_Event_Handler::ALL_EVENTS_MASK) == -1)
+ return false;
}
return true;
@@ -159,21 +118,18 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout
// This method is called if a connection times out before completing.
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout");
- SVC_HANDLER *svc_handler =
- this->close ();
-
- if (svc_handler == 0)
- return 0;
+ SVC_HANDLER *svc_handler = 0;
+ int retval = this->close (svc_handler) ? 0 : -1;
// Forward to the SVC_HANDLER the <arg> that was passed in as a
// magic cookie during ACE_Connector::connect(). This gives the
// SVC_HANDLER an opportunity to take corrective action (e.g., wait
// a few milliseconds and try to reconnect again.
- if (svc_handler->handle_timeout (tv, arg) == -1)
+ if (svc_handler != 0 && svc_handler->handle_timeout (tv, arg) == -1)
svc_handler->handle_close (svc_handler->get_handle (),
ACE_Event_Handler::TIMER_MASK);
- return 0;
+ return retval;
}
@@ -184,16 +140,14 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
// establishment.
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input");
- SVC_HANDLER *svc_handler =
- this->close ();
-
- if (svc_handler == 0)
- return 0;
+ SVC_HANDLER *svc_handler = 0;
+ int retval = this->close (svc_handler) ? 0 : -1;
// Close Svc_Handler.
- svc_handler->close (0);
+ if (svc_handler != 0)
+ svc_handler->close (0);
- return 0;
+ return retval;
}
template <class SVC_HANDLER> int
@@ -202,16 +156,15 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
// Called when a connection is establishment asynchronous.
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output");
- SVC_HANDLER *svc_handler =
- this->close ();
-
- if (svc_handler == 0)
- return 0;
+ // Grab the connector ref before smashing ourselves in close().
+ ACE_Connector_Base<SVC_HANDLER> &connector = this->connector_;
+ SVC_HANDLER *svc_handler = 0;
+ int retval = this->close (svc_handler) ? 0 : -1;
- this->connector_.initialize_svc_handler (handle,
- svc_handler);
+ if (svc_handler != 0)
+ connector.initialize_svc_handler (handle, svc_handler);
- return 0;
+ return retval;
}
template <class SVC_HANDLER> int
@@ -220,7 +173,6 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception (ACE_HANDLE h)
// On Win32, the except mask must also be set for asynchronous
// connects.
ACE_TRACE ("ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_exception");
-
return this->handle_output (h);
}
@@ -417,7 +369,7 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::connect_i
if (this->make_svc_handler (sh) == -1)
return -1;
- ACE_Time_Value *timeout;
+ ACE_Time_Value *timeout = 0;
int use_reactor = synch_options[ACE_Synch_Options::USE_REACTOR];
if (use_reactor)
@@ -529,6 +481,7 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::cancel (SVC_HANDLER *sh)
if (handler == 0)
return -1;
+ // find_handler() increments handler's refcount; ensure we decrement it.
ACE_Event_Handler_var safe_handler (handler);
NBCH *nbch =
@@ -583,25 +536,24 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect
goto reactor_registration_failure;
// Add handle to non-blocking handle set.
- this->non_blocking_handles ().set_bit (handle);
+ this->non_blocking_handles ().insert (handle);
// If we're starting connection under timer control then we need to
// schedule a timeout with the ACE_Reactor.
tv = const_cast<ACE_Time_Value *> (synch_options.time_value ());
- if (tv == 0)
- return 0;
-
- timer_id =
- this->reactor ()->schedule_timer (nbch,
- synch_options.arg (),
- *tv);
- if (timer_id == -1)
- goto timer_registration_failure;
-
- // Remember timer id.
- nbch->timer_id (timer_id);
+ if (tv != 0)
+ {
+ timer_id =
+ this->reactor ()->schedule_timer (nbch,
+ synch_options.arg (),
+ *tv);
+ if (timer_id == -1)
+ goto timer_registration_failure;
+
+ // Remember timer id.
+ nbch->timer_id (timer_id);
+ }
- // Everything was successful.
return 0;
// Undo previous actions using the ol' "goto label and fallthru"
@@ -612,7 +564,7 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::nonblocking_connect
this->reactor ()->remove_handler (handle, mask);
// Remove handle from the set of non-blocking handles.
- this->non_blocking_handles ().clr_bit (handle);
+ this->non_blocking_handles ().remove (handle);
/* FALLTHRU */
@@ -681,7 +633,7 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::reactor (void) const
return this->reactor_;
}
-template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Handle_Set &
+template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> ACE_Unbounded_Set<ACE_HANDLE> &
ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::non_blocking_handles (void)
{
return this->non_blocking_handles_;
@@ -691,7 +643,7 @@ template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1> int
ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
{
// If there are no non-blocking handle pending, return immediately.
- if (this->non_blocking_handles ().num_set () == 0)
+ if (this->non_blocking_handles ().size () == 0)
return 0;
// Exclusive access to the Reactor.
@@ -700,28 +652,41 @@ ACE_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::close (void)
// Go through all the non-blocking handles. It is necessary to
// create a new iterator each time because we remove from the handle
// set when we cancel the Svc_Handler.
+ ACE_HANDLE *handle = 0;
while (1)
{
- ACE_Handle_Set_Iterator iterator (this->non_blocking_handles ());
- ACE_HANDLE handle = iterator ();
-
- if (handle == ACE_INVALID_HANDLE)
+ ACE_Unbounded_Set_Iterator<ACE_HANDLE>
+ iterator (this->non_blocking_handles ());
+ if (!iterator.next (handle))
break;
ACE_Event_Handler *handler =
- this->reactor ()->find_handler (handle);
-
- ACE_ASSERT (handler != 0);
+ this->reactor ()->find_handler (*handle);
+ if (handler == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("%t: Connector::close h %d, no handler\n"),
+ *handle));
+ // Remove handle from the set of non-blocking handles.
+ this->non_blocking_handles ().remove (*handle);
+ continue;
+ }
+ // find_handler() incremented handler's refcount; ensure it's decremented
ACE_Event_Handler_var safe_handler (handler);
-
- NBCH *nbch =
- dynamic_cast<NBCH *> (handler);
-
- ACE_ASSERT (nbch != 0);
-
- SVC_HANDLER *svc_handler =
- nbch->svc_handler ();
+ NBCH *nbch = dynamic_cast<NBCH *> (handler);
+ if (nbch == 0)
+ {
+ ACE_ERROR ((LM_ERROR,
+ ACE_LIB_TEXT ("%t: Connector::close h %d handler %@ ")
+ ACE_LIB_TEXT ("not a legit handler\n"),
+ *handle,
+ handler));
+ // Remove handle from the set of non-blocking handles.
+ this->non_blocking_handles ().remove (*handle);
+ continue;
+ }
+ SVC_HANDLER *svc_handler = nbch->svc_handler ();
// Cancel the non-blocking connection.
this->cancel (svc_handler);
@@ -994,4 +959,6 @@ ACE_Strategy_Connector<SVC_HANDLER, ACE_PEER_CONNECTOR_2>::concurrency_strategy
return this->concurrency_strategy_;
}
+ACE_END_VERSIONED_NAMESPACE_DECL
+
#endif /* ACE_CONNECTOR_C */