Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 09 Oct 2013 11:55:13 +0300
From:      Andriy Gapon <avg@FreeBSD.org>
To:        freebsd-hackers@FreeBSD.org
Subject:   taskqueue_drain_all
Message-ID:  <525519F1.3050703@FreeBSD.org>

next in thread | raw e-mail | index | archive | help

I would like to propose to extend taskqueue API with taskqueue_drain_all.
A potential use case: I have a private taskqueue, several kinds of tasks get
executed via it and then I want to make sure that all of them are completed.
Obviously, I have a way to ensure that no new ones get enqueued.

Is this a good addition?
Or should like consider looping over all of my tasks externally to taskqueue
implementation?

A quick prototype:

--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -316,6 +316,7 @@ taskqueue_run_locked(struct taskqueue *queue)
 		wakeup(task);
 	}
 	TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
+	wakeup(&queue->tq_active);
 }

 void
@@ -402,6 +403,22 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
 }

 void
+taskqueue_drain_all(struct taskqueue *queue)
+{
+	struct task *task;
+
+	TQ_LOCK(queue);
+	while ((task = STAILQ_FIRST(&queue->tq_queue)) != NULL) {
+		while (task->ta_pending != 0 || task_is_running(queue, task))
+			TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+	}
+	while (TAILQ_FIRST(&queue->tq_active) != NULL)
+			TQ_SLEEP(queue, &queue->tq_active,
+			    &queue->tq_mutex, PWAIT, "-", 0);
+	TQ_UNLOCK(queue);
+}
+
+void
 taskqueue_drain_timeout(struct taskqueue *queue,
     struct timeout_task *timeout_task)
 {


-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?525519F1.3050703>