add taskqueue_drain_all
This API has semantics similar to that of taskqueue_drain but acts on all tasks that might be queued or running on a taskqueue. A caller must ensure that no new tasks are being enqueued otherwise this call would be totally meaningless. For example, if the tasks are enqueued by an interrupt filter then its interrupt must be disabled. MFC after: 10 days
This commit is contained in:
parent
c43b087230
commit
80c477c9b4
@ -300,6 +300,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)
|
||||
{
|
||||
@ -350,6 +359,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
|
||||
@ -433,6 +444,25 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
|
||||
TQ_UNLOCK(queue);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -81,6 +81,7 @@ int taskqueue_cancel_timeout(struct taskqueue *queue,
|
||||
void taskqueue_drain(struct taskqueue *queue, struct task *task);
|
||||
void taskqueue_drain_timeout(struct taskqueue *queue,
|
||||
struct timeout_task *timeout_task);
|
||||
void taskqueue_drain_all(struct taskqueue *queue);
|
||||
void taskqueue_free(struct taskqueue *queue);
|
||||
void taskqueue_run(struct taskqueue *queue);
|
||||
void taskqueue_block(struct taskqueue *queue);
|
||||
|
Loading…
Reference in New Issue
Block a user