aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-08-26 15:27:23 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-08-26 15:27:23 +0000
commite8055b199fedf6b327da7cf8c6b6ffeace54fa4a (patch)
tree6c49b0df66aa95c1fd348fe96f26d77a3f1ca478
parent2e07cd95ad31de9360dfb2cb6296298054404801 (diff)
Fix a race condition with the IAX scheduler thread. A lock and condition are
used here to allow newly scheduled tasks to wake up the scheduler just in case the new task needs to run sooner than the current wakeup time when the thread is sleeping. However, there was a race condition such that a newly scheduled task would not properly wake up the scheduler or affect the wake up period. The order of execution would have been: 1) Scheduler thread determines wake up time of N ms. 2) Another thread schedules a task and signals the condition, with an execution time of < N ms. 3) Scheduler thread locks and goes to sleep for N ms. By moving the sleep time determination to inside the critical section, this possibility is avoided. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@140051 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/chan_iax2.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 64f616bb9..af380e9e5 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -9082,15 +9082,14 @@ static void *sched_thread(void *ignore)
struct timespec ts;
for (;;) {
+ pthread_testcancel();
+ ast_mutex_lock(&sched_lock);
res = ast_sched_wait(sched);
if ((res > 1000) || (res < 0))
res = 1000;
tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
-
- pthread_testcancel();
- ast_mutex_lock(&sched_lock);
ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
ast_mutex_unlock(&sched_lock);
pthread_testcancel();