summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2010-10-20 16:33:26 +0000
committerSteve Huston <shuston@riverace.com>2010-10-20 16:33:26 +0000
commit596d4feb7390e6970b4c6e6cc9704ea3201a0bc9 (patch)
tree3a60cb93590fe3262f38e84aec70b7ddde5a89a7
parentb812a556f5a9f7cdc170128367b27ae8fc0ae535 (diff)
downloadATCD-596d4feb7390e6970b4c6e6cc9704ea3201a0bc9.tar.gz
ChangeLogTag:Wed Oct 20 16:07:09 UTC 2010 Steve Huston <shuston@riverace.com>
-rw-r--r--ChangeLog8
-rw-r--r--ace/Timer_Queue_Adapters.cpp12
-rw-r--r--ace/Timer_Queue_T.cpp4
3 files changed, 22 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 76d1eb45176..a1f3316783b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Wed Oct 20 16:07:09 UTC 2010 Steve Huston <shuston@riverace.com>
+
+ * ace/Timer_Queue_Adapters.cpp (ACE_Thread_Timer_Queue_Adapter::svc):
+ * ace/Timer_Queue_T.cpp (expire):
+ Temporarily release and reacquire the mutex around timer dispatch.
+ This prevents a deadlock on user code with multiple threads doing
+ timer-related operations.
+
Fri Sep 24 11:54:16 EDT 2010 Steve Huston <shuston@riverace.com>
* ACE version 5.8a released.
diff --git a/ace/Timer_Queue_Adapters.cpp b/ace/Timer_Queue_Adapters.cpp
index 1c04fd6eed2..fe6be3f4adc 100644
--- a/ace/Timer_Queue_Adapters.cpp
+++ b/ace/Timer_Queue_Adapters.cpp
@@ -17,6 +17,7 @@
# include "ace/Timer_Queue_Adapters.inl"
# endif /* __ACE_INLINE__ */
+#include "ace/Reverse_Lock_T.h"
#include "ace/Signal.h"
#include "ace/OS_NS_unistd.h"
#include "ace/OS_NS_sys_time.h"
@@ -278,8 +279,15 @@ ACE_Thread_Timer_Queue_Adapter<TQ, TYPE>::svc (void)
}
}
- // Expire timers anyway, at worst this is a no-op.
- this->timer_queue_->expire ();
+ // Expire timers anyway, at worst this is a no-op. Release the lock
+ // while dispatching; the timer queue has its own lock to protect
+ // itself.
+ {
+ ACE_Reverse_Lock<ACE_SYNCH_RECURSIVE_MUTEX> rel (this->mutex_);
+ ACE_GUARD_RETURN (ACE_Reverse_Lock<ACE_SYNCH_RECURSIVE_MUTEX>,
+ rmon, rel, -1);
+ this->timer_queue_->expire ();
+ }
}
// Thread cancellation point, if ACE supports it.
diff --git a/ace/Timer_Queue_T.cpp b/ace/Timer_Queue_T.cpp
index 23d2628970d..f7d8f00675e 100644
--- a/ace/Timer_Queue_T.cpp
+++ b/ace/Timer_Queue_T.cpp
@@ -18,6 +18,7 @@
#include "ace/Guard_T.h"
#include "ace/Log_Msg.h"
#include "ace/Reactor_Timer_Interface.h"
+#include "ace/Reverse_Lock_T.h"
#include "ace/Null_Mutex.h"
#include "ace/OS_NS_sys_time.h"
@@ -267,6 +268,9 @@ ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_ti
while ((result = this->dispatch_info_i (cur_time, info)) != 0)
{
+ ACE_MT (ACE_Reverse_Lock<ACE_LOCK> rev_lk(this->mutex_));
+ ACE_MT (ACE_GUARD_RETURN (ACE_Reverse_Lock<ACE_LOCK>, rmon, rev_lk, -1));
+
const void *upcall_act = 0;
this->preinvoke (info, cur_time, upcall_act);