summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-08-24 02:29:48 +0000
committercoryan <coryan@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2009-08-24 02:29:48 +0000
commitaa7e2d8fc796d908805c04037a3cacfad2cdc459 (patch)
tree39d86f3065c3024d4b334f3bc844b2f8e53a872b
parent50441f4c6ea7f89bc4bfd28b28e07c108347655e (diff)
downloadATCD-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/ChangeLog7
-rw-r--r--ACE/ace/Timer_Queue_T.cpp68
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