diff options
author | Joshua Colp <jcolp@digium.com> | 2015-08-28 21:57:14 -0300 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2015-08-28 21:57:14 -0300 |
commit | 85e1cb51b21c2d194647e16b81b5a1344d2ff911 (patch) | |
tree | b9dc72a04563005e89455e897c94f492318b33da /main/sched.c | |
parent | b5801fe42c37f4a9c075b2e96b108ce2344d23e9 (diff) |
sched: ast_sched_del may return prematurely due to spurious wakeup
When deleting a scheduled item if the item in question is currently
executing the ast_sched_del function waits until it has completed.
This is accomplished using ast_cond_wait. Unfortunately the
ast_cond_wait function can suffer from spurious wakeups so the
predicate needs to be checked after it returns to make sure it has
really woken up as a result of being signaled.
This change adds a loop around the ast_cond_wait to make sure that
it only exits when the executing task has really completed.
ASTERISK-25355 #close
Change-Id: I51198270eb0b637c956c61aa409f46283432be61
Diffstat (limited to 'main/sched.c')
-rw-r--r-- | main/sched.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/main/sched.c b/main/sched.c index 4443497c5..033d238c7 100644 --- a/main/sched.c +++ b/main/sched.c @@ -497,7 +497,9 @@ int _ast_sched_del(struct ast_sched_context *con, int id, const char *file, int /* Wait for executing task to complete so that caller of ast_sched_del() does not * free memory out from under the task. */ - ast_cond_wait(&s->cond, &con->lock); + while (con->currently_executing && (id == con->currently_executing->id)) { + ast_cond_wait(&s->cond, &con->lock); + } /* Do not sched_release() here because ast_sched_runq() will do it */ } |