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
This commit is contained in:
Scott Long 2008-03-25 22:38:45 +00:00
parent 2e76e92b45
commit 478cfc7300
2 changed files with 30 additions and 1 deletions

View File

@ -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,13 +226,38 @@ 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);
return 0;
}
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)
{

View File

@ -58,6 +58,8 @@ void taskqueue_drain(struct taskqueue *queue, struct task *task);
struct taskqueue *taskqueue_find(const char *name);
void taskqueue_free(struct taskqueue *queue);
void taskqueue_run(struct taskqueue *queue);
void taskqueue_block(struct taskqueue *queue);
void taskqueue_unblock(struct taskqueue *queue);
/*
* Functions for dedicated thread taskqueues