diff --git a/ACE/ace/Asynch_IO.cpp b/ACE/ace/Asynch_IO.cpp index 5502dd2191c2c..6683c4a6eea92 100644 --- a/ACE/ace/Asynch_IO.cpp +++ b/ACE/ace/Asynch_IO.cpp @@ -1060,9 +1060,7 @@ ACE_Handler::ACE_Handler (ACE_Proactor *d) ACE_Handler::~ACE_Handler () { - ACE_Handler::Proxy *p = this->proxy_.get (); - if (p) - p->reset (); + deregister_callback (); } void @@ -1121,6 +1119,14 @@ ACE_Handler::handle_wakeup () { } +void +ACE_Handler::deregister_callback () +{ + ACE_Handler::Proxy* p = this->proxy_.get (); + if (p) + p->reset (); +} + ACE_Proactor * ACE_Handler::proactor () { diff --git a/ACE/ace/Asynch_IO.h b/ACE/ace/Asynch_IO.h index c528be4188ef9..56dea1c369c2c 100644 --- a/ACE/ace/Asynch_IO.h +++ b/ACE/ace/Asynch_IO.h @@ -1620,6 +1620,9 @@ class ACE_Export ACE_Handler */ virtual void handle_wakeup (); + /// Call before destruction to ensure no more callbacks can happen. + void deregister_callback (); + /// Get the proactor associated with this handler. ACE_Proactor *proactor (); @@ -1649,10 +1652,18 @@ class ACE_Export ACE_Handler { public: Proxy (ACE_Handler *handler) : handler_ (handler) {} - void reset () { this->handler_ = 0; } + void reset () + { + acquire (); + this->handler_ = 0; + release (); + } ACE_Handler *handler () { return this->handler_; } + int acquire () { return mutex_.acquire (); } + int release () { return mutex_.release (); } private: ACE_Handler *handler_; + ACE_SYNCH_MUTEX mutex_; }; typedef ACE_Refcounted_Auto_Ptr Proxy_Ptr; diff --git a/ACE/ace/Proactor.cpp b/ACE/ace/Proactor.cpp index 061bcb930aaaa..1c9ccba9f0645 100644 --- a/ACE/ace/Proactor.cpp +++ b/ACE/ace/Proactor.cpp @@ -182,16 +182,16 @@ ACE_Proactor_Handle_Timeout_Upcall::ACE_Proactor_Handle_Timeout_Upcall () int ACE_Proactor_Handle_Timeout_Upcall::registration (ACE_Proactor_Timer_Queue &, - ACE_Handler * handler, + const ACE_Handler::Proxy_Ptr& proxy, const void *) { - handler->proactor(proactor_); + proxy.get()->handler()->proactor(proactor_); return 0; } int ACE_Proactor_Handle_Timeout_Upcall::preinvoke (ACE_Proactor_Timer_Queue &, - ACE_Handler *, + ACE_Handler::Proxy_Ptr&, const void *, int, const ACE_Time_Value &, @@ -202,7 +202,7 @@ ACE_Proactor_Handle_Timeout_Upcall::preinvoke (ACE_Proactor_Timer_Queue &, int ACE_Proactor_Handle_Timeout_Upcall::postinvoke (ACE_Proactor_Timer_Queue &, - ACE_Handler *, + ACE_Handler::Proxy_Ptr&, const void *, int, const ACE_Time_Value &, @@ -213,7 +213,7 @@ ACE_Proactor_Handle_Timeout_Upcall::postinvoke (ACE_Proactor_Timer_Queue &, int ACE_Proactor_Handle_Timeout_Upcall::timeout (ACE_Proactor_Timer_Queue &, - ACE_Handler *handler, + ACE_Handler::Proxy_Ptr& proxy, const void *act, int, const ACE_Time_Value &time) @@ -226,7 +226,7 @@ ACE_Proactor_Handle_Timeout_Upcall::timeout (ACE_Proactor_Timer_Queue &, // Create the Asynch_Timer. ACE_Asynch_Result_Impl *asynch_timer = - this->proactor_->create_asynch_timer (handler->proxy (), + this->proactor_->create_asynch_timer (proxy, act, time, ACE_INVALID_HANDLE, @@ -259,7 +259,7 @@ ACE_Proactor_Handle_Timeout_Upcall::timeout (ACE_Proactor_Timer_Queue &, int ACE_Proactor_Handle_Timeout_Upcall::cancel_type (ACE_Proactor_Timer_Queue &, - ACE_Handler *, + const ACE_Handler::Proxy_Ptr&, int, int &) { @@ -269,7 +269,7 @@ ACE_Proactor_Handle_Timeout_Upcall::cancel_type (ACE_Proactor_Timer_Queue &, int ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (ACE_Proactor_Timer_Queue &, - ACE_Handler *, + const ACE_Handler::Proxy_Ptr&, int, int) { @@ -279,7 +279,7 @@ ACE_Proactor_Handle_Timeout_Upcall::cancel_timer (ACE_Proactor_Timer_Queue &, int ACE_Proactor_Handle_Timeout_Upcall::deletion (ACE_Proactor_Timer_Queue &, - ACE_Handler *, + ACE_Handler::Proxy_Ptr&, const void *) { // Do nothing @@ -681,7 +681,7 @@ ACE_Proactor::schedule_timer (ACE_Handler &handler, // absolute time. ACE_Time_Value absolute_time = this->timer_queue_->gettimeofday () + time; - long result = this->timer_queue_->schedule (&handler, + long result = this->timer_queue_->schedule (handler.proxy(), act, absolute_time, interval); @@ -713,7 +713,7 @@ ACE_Proactor::cancel_timer (ACE_Handler &handler, { // No need to signal timer event here. Even if the cancel timer was // the earliest, we will have an extra wakeup. - return this->timer_queue_->cancel (&handler, + return this->timer_queue_->cancel (handler.proxy(), dont_call_handle_close); } @@ -787,7 +787,7 @@ ACE_Proactor::timer_queue (ACE_Proactor_Timer_Queue *tq) } // Set the proactor in the timer queue's functor - using TQ_Base = ACE_Timer_Queue_Upcall_Base; + using TQ_Base = ACE_Timer_Queue_Upcall_Base; TQ_Base * tqb = dynamic_cast (this->timer_queue_); diff --git a/ACE/ace/Proactor.h b/ACE/ace/Proactor.h index 556bb63b5884a..1c32a86643de8 100644 --- a/ACE/ace/Proactor.h +++ b/ACE/ace/Proactor.h @@ -42,7 +42,7 @@ class ACE_Proactor_Impl; class ACE_Proactor_Timer_Handler; /// Type def for the timer queue. -typedef ACE_Abstract_Timer_Queue ACE_Proactor_Timer_Queue; +typedef ACE_Abstract_Timer_Queue ACE_Proactor_Timer_Queue; /** * @class ACE_Proactor_Handle_Timeout_Upcall @@ -63,12 +63,12 @@ class ACE_Export ACE_Proactor_Handle_Timeout_Upcall /// This method is called when a timer is registered. int registration (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + const ACE_Handler::Proxy_Ptr& proxy, const void *arg); /// This method is called before the timer expires. int preinvoke (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + ACE_Handler::Proxy_Ptr& proxy, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time, @@ -76,14 +76,14 @@ class ACE_Export ACE_Proactor_Handle_Timeout_Upcall /// This method is called when the timer expires. int timeout (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + ACE_Handler::Proxy_Ptr& proxy, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time); /// This method is called after the timer expires. int postinvoke (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + ACE_Handler::Proxy_Ptr& proxy, const void *arg, int recurring_timer, const ACE_Time_Value &cur_time, @@ -91,20 +91,20 @@ class ACE_Export ACE_Proactor_Handle_Timeout_Upcall /// This method is called when a handler is canceled. int cancel_type (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + const ACE_Handler::Proxy_Ptr& proxy, int dont_call_handle_close, int &requires_reference_counting); /// This method is called when a timer is canceled. int cancel_timer (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + const ACE_Handler::Proxy_Ptr& proxy, int dont_call_handle_close, int requires_reference_counting); /// This method is called when the timer queue is destroyed and the /// timer is still contained in it. int deletion (ACE_Proactor_Timer_Queue &timer_queue, - ACE_Handler *handler, + ACE_Handler::Proxy_Ptr& proxy, const void *arg); protected: @@ -129,29 +129,29 @@ class ACE_Export ACE_Proactor { // = Here are the private typedefs that the ACE_Proactor uses. - typedef ACE_Timer_Queue_Iterator_T + typedef ACE_Timer_Queue_Iterator_T TIMER_QUEUE_ITERATOR; - typedef ACE_Timer_List_T TIMER_LIST; - typedef ACE_Timer_List_Iterator_T TIMER_LIST_ITERATOR; - typedef ACE_Timer_Heap_T TIMER_HEAP; - typedef ACE_Timer_Heap_Iterator_T TIMER_HEAP_ITERATOR; - typedef ACE_Timer_Wheel_T TIMER_WHEEL; - typedef ACE_Timer_Wheel_Iterator_T TIMER_WHEEL_ITERATOR; diff --git a/ACE/tests/Proactor_Timer_Test.cpp b/ACE/tests/Proactor_Timer_Test.cpp index dad2adb5388b3..10f7d0c6e5d10 100644 --- a/ACE/tests/Proactor_Timer_Test.cpp +++ b/ACE/tests/Proactor_Timer_Test.cpp @@ -308,7 +308,7 @@ run_main (int argc, ACE_TCHAR *[]) // to do it right in at least one test. Notice the lack of // ACE_NEW_RETURN, that monstrosity has no business in proper C++ // code ... - using Timer_Queue = ACE_Timer_Heap_T; + using Timer_Queue = ACE_Timer_Heap_T; std::unique_ptr tq(new Timer_Queue); // ... notice how the policy is in the derived timer queue type.