summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-08-02 18:05:23 +0000
committerRussell Bryant <russell@russellbryant.com>2007-08-02 18:05:23 +0000
commit85ba8d515abbc54435f5edf2f5e27f6f28852e92 (patch)
treee85df061d2f4f278ef522dd20be651627f5d3eb7 /channels
parent12ed8e8d07aa2f662bb2faf405e8291f2223ebf7 (diff)
Merged revisions 77943 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r77943 | russell | 2007-08-02 13:04:43 -0500 (Thu, 02 Aug 2007) | 9 lines Fix another race condition in the handling of dynamic threads. If the dynamic thread timed out waiting for something to do, but was acquired to perform an action immediately afterwords, then wait on the condition again to give the other thread a chance to finish setting up the data for what action this thread should perform. Otherwise, if it immediately continues, it will perform the wrong action. (reported on IRC by mihai, patch by me) (related to issue #10289) ........ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@77944 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_iax2.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index e4be160ba..c035b151a 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -8392,14 +8392,20 @@ static void *iax2_process_thread(void *data)
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
- ast_mutex_unlock(&thread->lock);
AST_LIST_LOCK(&dynamic_list);
/* Account for the case where this thread is acquired *right* after a timeout */
if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
AST_LIST_UNLOCK(&dynamic_list);
- if (t)
+ if (t) {
+ ast_mutex_unlock(&thread->lock);
break; /* exiting the main loop */
+ }
+ /* Someone grabbed our thread *right* after we timed out.
+ * Wait for them to set us up with something to do and signal
+ * us to continue. */
+ ast_cond_timedwait(&thread->cond, &thread->lock, &ts);
+ ast_mutex_unlock(&thread->lock);
}
if (!t)
ast_mutex_unlock(&thread->lock);