diff options
author | avg <avg@FreeBSD.org> | 2014-02-17 15:32:08 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2014-02-17 15:32:08 +0000 |
commit | 22073dc5fc6c528703efb1da893a0340043ffd69 (patch) | |
tree | 613ca9c92776cb1bcdeec1c04c2a71c5cc17b9bb /sys/kern/subr_taskqueue.c | |
parent | 9a6dcea530c74578e68091504a1abefc3e175832 (diff) | |
download | FreeBSD-src-22073dc5fc6c528703efb1da893a0340043ffd69.zip FreeBSD-src-22073dc5fc6c528703efb1da893a0340043ffd69.tar.gz |
MFC r258713,262062: add taskqueue_drain_all
Diffstat (limited to 'sys/kern/subr_taskqueue.c')
-rw-r--r-- | sys/kern/subr_taskqueue.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index 951b5fd..f104bb5 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -285,6 +285,15 @@ taskqueue_enqueue_timeout(struct taskqueue *queue, return (res); } +static void +taskqueue_drain_running(struct taskqueue *queue) +{ + + while (!TAILQ_EMPTY(&queue->tq_active)) + TQ_SLEEP(queue, &queue->tq_active, &queue->tq_mutex, + PWAIT, "-", 0); +} + void taskqueue_block(struct taskqueue *queue) { @@ -337,6 +346,8 @@ taskqueue_run_locked(struct taskqueue *queue) wakeup(task); } TAILQ_REMOVE(&queue->tq_active, &tb, tb_link); + if (TAILQ_EMPTY(&queue->tq_active)) + wakeup(&queue->tq_active); } void @@ -421,6 +432,25 @@ taskqueue_drain(struct taskqueue *queue, struct task *task) } void +taskqueue_drain_all(struct taskqueue *queue) +{ + struct task *task; + + if (!queue->tq_spin) + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__); + + TQ_LOCK(queue); + task = STAILQ_LAST(&queue->tq_queue, task, ta_link); + if (task != NULL) + while (task->ta_pending != 0) + TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0); + taskqueue_drain_running(queue); + KASSERT(STAILQ_EMPTY(&queue->tq_queue), + ("taskqueue queue is not empty after draining")); + TQ_UNLOCK(queue); +} + +void taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task) { |