summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_taskqueue.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2008-03-25 22:38:45 +0000
committerscottl <scottl@FreeBSD.org>2008-03-25 22:38:45 +0000
commita3b7a4bce88ad1f77a75a7a226116a163052e8c8 (patch)
tree25ea898a84ae97aa0796cd38dd10df57607241df /sys/kern/subr_taskqueue.c
parent268354d5164d4b1e0a9a1abef4452b9e61700182 (diff)
downloadFreeBSD-src-a3b7a4bce88ad1f77a75a7a226116a163052e8c8.zip
FreeBSD-src-a3b7a4bce88ad1f77a75a7a226116a163052e8c8.tar.gz
Implement taskqueue_block() and taskqueue_unblock(). These functions allow
the owner of a queue to block and unblock execution of the tasks in the queue while allowing tasks to continue to be added queue. Combining this with taskqueue_drain() allows a queue to be safely disabled. The unblock function may run (or schedule to run) the queue when it is called, just as calling taskqueue_enqueue() would. Reviewed by: jhb, sam
Diffstat (limited to 'sys/kern/subr_taskqueue.c')
-rw-r--r--sys/kern/subr_taskqueue.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index c3ddb5f..7664861 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -63,6 +63,8 @@ struct taskqueue {
};
#define TQ_FLAGS_ACTIVE (1 << 0)
+#define TQ_FLAGS_BLOCKED (1 << 1)
+#define TQ_FLAGS_PENDING (1 << 2)
static __inline void
TQ_LOCK(struct taskqueue *tq)
@@ -224,7 +226,10 @@ taskqueue_enqueue(struct taskqueue *queue, struct task *task)
}
task->ta_pending = 1;
- queue->tq_enqueue(queue->tq_context);
+ if ((queue->tq_flags & TQ_FLAGS_BLOCKED) == 0)
+ queue->tq_enqueue(queue->tq_context);
+ else
+ queue->tq_flags |= TQ_FLAGS_PENDING;
TQ_UNLOCK(queue);
@@ -232,6 +237,28 @@ taskqueue_enqueue(struct taskqueue *queue, struct task *task)
}
void
+taskqueue_block(struct taskqueue *queue)
+{
+
+ TQ_LOCK(queue);
+ queue->tq_flags |= TQ_FLAGS_BLOCKED;
+ TQ_UNLOCK(queue);
+}
+
+void
+taskqueue_unblock(struct taskqueue *queue)
+{
+
+ TQ_LOCK(queue);
+ queue->tq_flags &= ~TQ_FLAGS_BLOCKED;
+ if (queue->tq_flags & TQ_FLAGS_PENDING) {
+ queue->tq_flags &= ~TQ_FLAGS_PENDING;
+ queue->tq_enqueue(queue->tq_context);
+ }
+ TQ_UNLOCK(queue);
+}
+
+void
taskqueue_run(struct taskqueue *queue)
{
struct task *task;
OpenPOWER on IntegriCloud