]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix another race condition in the handling of dynamic threads. If the dynamic
authorRussell Bryant <russell@russellbryant.com>
Thu, 2 Aug 2007 18:04:43 +0000 (18:04 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 2 Aug 2007 18:04:43 +0000 (18:04 +0000)
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/branches/1.4@77943 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index 2dbc74f470303585be4e9dd08ab5dd792ee460a1..d21cf88274065b91a513210b800d887896048837 100644 (file)
@@ -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);