summaryrefslogtreecommitdiff
path: root/main/sched.c
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2015-08-28 21:57:14 -0300
committerJoshua Colp <jcolp@digium.com>2015-08-28 20:04:53 -0500
commitc036e50fbeffea0fd6352905b87286440f555dbc (patch)
treede595817958a15eff335200d96316e517573976e /main/sched.c
parent229b95d253e7e3bf51cd431f021cff7993655dc7 (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.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/main/sched.c b/main/sched.c
index d50a31e56..062b2fd96 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 */
}