aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-02 18:04:43 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-02 18:04:43 +0000
commitc10d914118c2789085062539ce4cbc1ae9af5238 (patch)
tree75fd9e5620adc59294b469e7ea57f759bdfb054c
parent442d6dbf99271aea06685e42f0cd1d63c542983e (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.4@77943 f38db490-d61c-443f-a65b-d21fe96a405b
-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 2dbc74f47..d21cf8827 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -7874,14 +7874,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)))
iaxdynamicthreadcount--;
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);