diff options
author | sam <sam@FreeBSD.org> | 2005-04-24 16:52:45 +0000 |
---|---|---|
committer | sam <sam@FreeBSD.org> | 2005-04-24 16:52:45 +0000 |
commit | 0f63abff2a842df0f9b53a6a11bf2ad4d38b4e00 (patch) | |
tree | 5a6fe7fb2312cf12d5ca0ea2b9d79549f4f97743 /sys/kern/subr_taskqueue.c | |
parent | f09f100e44ebd0ea91f000f67d2a7c8c9d3a4859 (diff) | |
download | FreeBSD-src-0f63abff2a842df0f9b53a6a11bf2ad4d38b4e00.zip FreeBSD-src-0f63abff2a842df0f9b53a6a11bf2ad4d38b4e00.tar.gz |
o eliminate modification of task structures after their run to avoid
modify-after-free races when the task structure is malloc'd
o shrink task structure by removing ta_flags (no longer needed with
avoid fix) and combining ta_pending and ta_priority
Reviewed by: dwhite, dfr
MFC after: 4 days
Diffstat (limited to 'sys/kern/subr_taskqueue.c')
-rw-r--r-- | sys/kern/subr_taskqueue.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index 7758fbd..9d0ada4 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -51,6 +51,7 @@ struct taskqueue { const char *tq_name; taskqueue_enqueue_fn tq_enqueue; void *tq_context; + struct task *tq_running; struct mtx tq_mutex; }; @@ -186,13 +187,13 @@ taskqueue_run(struct taskqueue *queue) STAILQ_REMOVE_HEAD(&queue->tq_queue, ta_link); pending = task->ta_pending; task->ta_pending = 0; - task->ta_flags |= TAF_PENDING; + queue->tq_running = task; mtx_unlock(&queue->tq_mutex); task->ta_func(task->ta_context, pending); mtx_lock(&queue->tq_mutex); - task->ta_flags &= ~TAF_PENDING; + queue->tq_running = NULL; wakeup(task); } @@ -209,7 +210,7 @@ taskqueue_drain(struct taskqueue *queue, struct task *task) { WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "taskqueue_drain"); mtx_lock(&queue->tq_mutex); - while (task->ta_pending != 0 || (task->ta_flags & TAF_PENDING)) { + while (task->ta_pending != 0 || task == queue->tq_running) { msleep(task, &queue->tq_mutex, PWAIT, "-", 0); } mtx_unlock(&queue->tq_mutex); |