summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2010-08-27 15:10:19 +0000
committerSteve Huston <shuston@riverace.com>2010-08-27 15:10:19 +0000
commit0f3eb1982d9c45a815dde5e23a022aacb9bc7014 (patch)
treebe4b506a1f5b589b84d290cd0baea7968eaf4fb2
parent2a9854c1d15da29168be6a5b7348a6a16070e53c (diff)
downloadATCD-0f3eb1982d9c45a815dde5e23a022aacb9bc7014.tar.gz
ChangeLogTag:Fri Aug 27 15:01:41 UTC 2010 Steve Huston <shuston@riverace.com>
-rw-r--r--ChangeLog10
-rw-r--r--ace/Connector.cpp18
-rw-r--r--ace/Connector.h3
3 files changed, 29 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 2a803927e72..29bbd637e55 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Fri Aug 27 15:01:41 UTC 2010 Steve Huston <shuston@riverace.com>
+
+ * Connector.{h cpp} (ACE_NonBlocking_Connect_Handler): Add a
+ handle_close() which calls handle_input() if called by the
+ ACE_Dev_Poll_Reactor to remove a failed connect. Apparently,
+ Linux epoll, at least sometimes, signals EPOLLERR on a failed
+ nonblocking connect, unlike the select() case which selects the
+ failed fd for read. Thanks to Kannan Ramaswamy <kannan dot
+ ramaswamy at cogcap dot com> for this information and fix.
+
Thu Jul 15 17:53:47 UTC 2010 Phil Mesnier <mesnier_p@ociweb.com>
* ace/Service_Gestalt.cpp:
diff --git a/ace/Connector.cpp b/ace/Connector.cpp
index 6d6834e4bda..c8f2a96b89f 100644
--- a/ace/Connector.cpp
+++ b/ace/Connector.cpp
@@ -121,9 +121,9 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::close (SVC_HANDLER *&sh)
return false;
// Remove from Reactor.
- if (this->reactor ()->remove_handler (
+ if (-1 == this->reactor ()->remove_handler (
h,
- ACE_Event_Handler::ALL_EVENTS_MASK) == -1)
+ ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL))
return false;
}
@@ -174,6 +174,20 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
}
template <class SVC_HANDLER> int
+ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_close (ACE_HANDLE handle,
+ ACE_Reactor_Mask m)
+{
+ // epoll on Linux will, at least sometimes, return EPOLLERR when a connect
+ // fails, triggering a total removal from the reactor. This is different from
+ // select()-based systems which select the fd for read on a connect failure.
+ // So just call handle_input() to rejoin common handling for a failed
+ // connect.
+ if (m == ACE_Event_Handler::ALL_EVENTS_MASK)
+ return this->handle_input (handle);
+ return -1;
+}
+
+template <class SVC_HANDLER> int
ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
{
// Called when a connection is establishment asynchronous.
diff --git a/ace/Connector.h b/ace/Connector.h
index 5d77ae430e4..27473e835f6 100644
--- a/ace/Connector.h
+++ b/ace/Connector.h
@@ -102,6 +102,9 @@ public:
/// Called by ACE_Reactor when asynchronous connections fail.
virtual int handle_input (ACE_HANDLE);
+ /// Called by ACE_Dev_Poll_Reactor when asynchronous connections fail.
+ virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
+
/// Called by ACE_Reactor when asynchronous connections succeed.
virtual int handle_output (ACE_HANDLE);