diff options
author | vzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-02-08 16:36:22 +0000 |
---|---|---|
committer | vzykov <vzykov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2010-02-08 16:36:22 +0000 |
commit | f9c207c9ca81dac8b4658ae8e7a3bc38082fe51f (patch) | |
tree | cd649d0bb42b4606087dbc1f6dd4ae6217c9a85a /ACE/ace/Connector.cpp | |
parent | 4791cdf67cb1a4cadb5ac069dd8821b6173b2b7d (diff) | |
download | ATCD-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.cpp | 60 |
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; |