diff options
author | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-08-24 02:29:48 +0000 |
---|---|---|
committer | coryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2009-08-24 02:29:48 +0000 |
commit | aa7e2d8fc796d908805c04037a3cacfad2cdc459 (patch) | |
tree | 39d86f3065c3024d4b334f3bc844b2f8e53a872b | |
parent | 50441f4c6ea7f89bc4bfd28b28e07c108347655e (diff) | |
download | ATCD-bug-3707.tar.gz |
Mon Aug 24 02:27:36 UTC 2009 Carlos O'Ryan <coryan@glamdring>bug-3707
* 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.
-rw-r--r-- | ACE/ChangeLog | 7 | ||||
-rw-r--r-- | 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 <coryan@glamdring> + + * 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 <coryan@glamdring> * 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<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::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<TYPE> 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 <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int |