summaryrefslogtreecommitdiff
path: root/ACE/ace/Connector.cpp
diff options
context:
space:
mode:
authorvzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-02-08 16:36:22 +0000
committervzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2010-02-08 16:36:22 +0000
commitf9c207c9ca81dac8b4658ae8e7a3bc38082fe51f (patch)
treecd649d0bb42b4606087dbc1f6dd4ae6217c9a85a /ACE/ace/Connector.cpp
parent4791cdf67cb1a4cadb5ac069dd8821b6173b2b7d (diff)
downloadATCD-f9c207c9ca81dac8b4658ae8e7a3bc38082fe51f.tar.gz
Mon Feb 8 16:21:06 UTC 2010 Vladimir Zykov <vladimir.zykov@prismtech.com>
* ace/Strategies_T.cpp: Changed the code so that close() is called in case of failure instead of destroy(). * ace/Connector.cpp: Changed a bit the code added by me on 'Wed Sep 2 14:45:27 UTC 2009' as a fix for bug#3731. After some more thinking it turned out that the original code could result in a crash when reference counting is not enabled and thus svc_handler could be destroyed at the time when there was an attempt to do remove_reference(). * ace/Svc_Handler.cpp: Moved the code added by me on 'Thu Feb 4 11:15:57 UTC 2010' from destroy() to handle_close(). * tests/NonBlocking_Conn_Test.h: * tests/NonBlocking_Conn_Test.cpp: Extended the test for using Svc_Handler with and without reference counting.
Diffstat (limited to 'ACE/ace/Connector.cpp')
-rw-r--r--ACE/ace/Connector.cpp60
1 files changed, 46 insertions, 14 deletions
diff --git a/ACE/ace/Connector.cpp b/ACE/ace/Connector.cpp
index db184ac1253..042a7f0415b 100644
--- a/ACE/ace/Connector.cpp
+++ b/ACE/ace/Connector.cpp
@@ -32,7 +32,10 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::ACE_NonBlocking_Connect_Handler
(ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
if (this->svc_handler_ != 0)
- this->svc_handler_->add_reference ();
+ {
+ // If reference counting is not enabled then this does nothing.
+ this->svc_handler_->add_reference ();
+ }
}
template <class SVC_HANDLER> SVC_HANDLER *
@@ -124,16 +127,27 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_timeout
SVC_HANDLER *svc_handler = 0;
int const 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 != 0 && svc_handler->handle_timeout (tv, arg) == -1)
- svc_handler->handle_close (svc_handler->get_handle (),
- ACE_Event_Handler::TIMER_MASK);
-
if (svc_handler != 0)
- svc_handler->remove_reference ();
+ {
+ ACE_Event_Handler_var ref_count_guard;
+
+ // We have to remove reference only when reference counting is enabled.
+ // Otherwise doing remove_reference() can be unsafe as svc_handler can
+ // be destroyed just before the point where we need to remove reference.
+ if (svc_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED)
+ {
+ ref_count_guard.reset (svc_handler);
+ }
+
+ // 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)
+ svc_handler->handle_close (svc_handler->get_handle (),
+ ACE_Event_Handler::TIMER_MASK);
+ }
return retval;
}
@@ -152,9 +166,18 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_input (ACE_HANDLE)
// Close Svc_Handler.
if (svc_handler != 0)
{
- svc_handler->close (NORMAL_CLOSE_OPERATION);
+ ACE_Event_Handler_var ref_count_guard;
- svc_handler->remove_reference ();
+ // We have to remove reference only when reference counting is enabled.
+ // Otherwise doing remove_reference() can be unsafe as svc_handler can
+ // be destroyed just before the point where we need to remove reference.
+ if (svc_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED)
+ {
+ ref_count_guard.reset (svc_handler);
+ }
+
+ svc_handler->close (NORMAL_CLOSE_OPERATION);
}
return retval;
@@ -173,9 +196,18 @@ ACE_NonBlocking_Connect_Handler<SVC_HANDLER>::handle_output (ACE_HANDLE handle)
if (svc_handler != 0)
{
- connector.initialize_svc_handler (handle, svc_handler);
+ ACE_Event_Handler_var ref_count_guard;
- svc_handler->remove_reference ();
+ // We have to remove reference only when reference counting is enabled.
+ // Otherwise doing remove_reference() can be unsafe as svc_handler can
+ // be destroyed just before the point where we need to remove reference.
+ if (svc_handler->reference_counting_policy ().value () ==
+ ACE_Event_Handler::Reference_Counting_Policy::ENABLED)
+ {
+ ref_count_guard.reset (svc_handler);
+ }
+
+ connector.initialize_svc_handler (handle, svc_handler);
}
return retval;