From aa7e2d8fc796d908805c04037a3cacfad2cdc459 Mon Sep 17 00:00:00 2001 From: coryan Date: Mon, 24 Aug 2009 02:29:48 +0000 Subject: Mon Aug 24 02:27:36 UTC 2009 Carlos O'Ryan * ace/Timer_Queue_T.cpp: Need to release the internal timer queue lock before dispatching calls in expire_single(), otherwise we get nasty deadlocks in the TP_Reactor implementation. --- ACE/ChangeLog | 7 +++++ ACE/ace/Timer_Queue_T.cpp | 68 +++++++++++++++++++++++++---------------------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/ACE/ChangeLog b/ACE/ChangeLog index f17597659b6..e26837074c7 100644 --- a/ACE/ChangeLog +++ b/ACE/ChangeLog @@ -1,3 +1,10 @@ +Mon Aug 24 02:27:36 UTC 2009 Carlos O'Ryan + + * ace/Timer_Queue_T.cpp: + Need to release the internal timer queue lock before dispatching + calls in expire_single(), otherwise we get nasty deadlocks in + the TP_Reactor implementation. + Thu Jul 2 02:55:09 UTC 2009 Carlos O'Ryan * ace/Abstract_Timer_Queue.h: diff --git a/ACE/ace/Timer_Queue_T.cpp b/ACE/ace/Timer_Queue_T.cpp index da8a8f75249..ebf65089bc1 100644 --- a/ACE/ace/Timer_Queue_T.cpp +++ b/ACE/ace/Timer_Queue_T.cpp @@ -283,39 +283,43 @@ ACE_Timer_Queue_T::expire_single ( ACE_Command_Base & pre_dispatch_command) { ACE_TRACE ("ACE_Timer_Queue_T::expire_single"); - ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); - - if (this->is_empty ()) - return 0; - - // Get the current time - ACE_Time_Value cur_time (this->gettimeofday_static () + - this->timer_skew ()); - - // Look for a node in the timer queue whose timer <= the present - // time. ACE_Timer_Node_Dispatch_Info_T info; - if (this->dispatch_info_i (cur_time, info)) - { - const void *upcall_act = 0; - - // Preinvoke (handles refcount if needed, etc.) - this->preinvoke (info, cur_time, upcall_act); - - // Release the token before expiration upcall. - pre_dispatch_command.execute(); - - // call the functor - this->upcall (info, cur_time); - - // Postinvoke (undo refcount if needed, etc.) - this->postinvoke (info, cur_time, upcall_act); - - // We have dispatched a timer - return 1; - } - - return 0; + ACE_Time_Value cur_time; + { + // Create a scope for the lock ... + ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1)); + + if (this->is_empty ()) + return 0; + + // Get the current time + cur_time = this->gettimeofday_static () + this->timer_skew (); + + // Look for a node in the timer queue whose timer <= the present + // time. + if (!this->dispatch_info_i (cur_time, info)) + { + return 0; + } + } + // We do not need the lock anymore, all these operations take place + // with local variables. + const void *upcall_act = 0; + + // Preinvoke (handles refcount if needed, etc.) + this->preinvoke (info, cur_time, upcall_act); + + // Release the token before expiration upcall. + pre_dispatch_command.execute(); + + // call the functor + this->upcall (info, cur_time); + + // Postinvoke (undo refcount if needed, etc.) + this->postinvoke (info, cur_time, upcall_act); + + // We have dispatched a timer + return 1; } template int -- cgit v1.2.1