summaryrefslogtreecommitdiff
path: root/apps/Gateway/Gateway/Channel_Connector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'apps/Gateway/Gateway/Channel_Connector.cpp')
-rw-r--r--apps/Gateway/Gateway/Channel_Connector.cpp92
1 files changed, 92 insertions, 0 deletions
diff --git a/apps/Gateway/Gateway/Channel_Connector.cpp b/apps/Gateway/Gateway/Channel_Connector.cpp
new file mode 100644
index 00000000000..429fa595df2
--- /dev/null
+++ b/apps/Gateway/Gateway/Channel_Connector.cpp
@@ -0,0 +1,92 @@
+#include "Channel_Connector.h"
+// @(#)Channel_Connector.cpp 1.1 10/18/96
+
+
+Channel_Connector::Channel_Connector (void)
+{
+}
+
+// Override the connection-failure method to add timer support.
+// Note that these timers perform "expoential backoff" to
+// avoid rapidly trying to reestablish connections when a link
+// goes down.
+
+int
+Channel_Connector::handle_close (ACE_HANDLE sd, ACE_Reactor_Mask)
+{
+ ACE_Connector<Channel, CHANNEL_PEER_CONNECTOR>::AST *stp = 0;
+
+ // Locate the ACE_Svc_Handler corresponding to the socket descriptor.
+ if (this->handler_map_.find (sd, stp) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) can't locate channel %d in map, %p\n",
+ sd, "find"), -1);
+
+ Channel *channel = stp->svc_handler ();
+
+ // Schedule a reconnection request at some point in the future
+ // (note that channel uses an exponential backoff scheme).
+ if (ACE_Service_Config::reactor ()->schedule_timer (channel, 0,
+ channel->timeout ()) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n",
+ "schedule_timer"), -1);
+ return 0;
+}
+
+// Initiate (or reinitiate) a connection to the Channel.
+
+int
+Channel_Connector::initiate_connection (Channel *channel,
+ ACE_Synch_Options &synch_options)
+{
+ char buf[MAXHOSTNAMELEN];
+
+ // Mark ourselves as idle so that the various iterators
+ // will ignore us until we are reconnected.
+ channel->state (Channel::IDLE);
+
+ if (channel->remote_addr ().addr_to_string (buf, sizeof buf) == -1
+ || channel->local_addr ().addr_to_string (buf, sizeof buf) == -1)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n",
+ "can't obtain peer's address"), -1);
+
+ // Try to connect to the Peer.
+
+ if (this->connect (channel, channel->remote_addr (),
+ synch_options, channel->local_addr ()) == -1)
+ {
+ if (errno != EWOULDBLOCK)
+ {
+ channel->state (Channel::FAILED);
+ ACE_DEBUG ((LM_DEBUG, "(%t) %p on address %s\n",
+ "connect", buf));
+
+ // Reschedule ourselves to try and connect again.
+ if (synch_options[ACE_Synch_Options::USE_REACTOR])
+ {
+ if (ACE_Service_Config::reactor ()->schedule_timer
+ (channel, 0, channel->timeout ()) == 0)
+ ACE_ERROR_RETURN ((LM_ERROR, "(%t) %p\n",
+ "schedule_timer"), -1);
+ }
+ else
+ // Failures on synchronous connects are reported as errors
+ // so that the caller can decide how to proceed.
+ return -1;
+ }
+ else
+ {
+ channel->state (Channel::CONNECTING);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) in the process of connecting %s to %s\n",
+ synch_options[ACE_Synch_Options::USE_REACTOR]
+ ? "asynchronously" : "synchronously", buf));
+ }
+ }
+ else
+ {
+ channel->state (Channel::ESTABLISHED);
+ ACE_DEBUG ((LM_DEBUG, "(%t) connected to %s on %d\n",
+ buf, channel->get_handle ()));
+ }
+ return 0;
+}