mirror of
https://github.com/freebsd/freebsd-src
synced 2024-11-05 18:22:52 +00:00
Add a taskqueue_cancel(9) to cancel a pending task without waiting for
it to run as taskqueue_drain(9) does. Requested by: hselasky Original code: jeff Reviewed by: jhb MFC after: 2 weeks
This commit is contained in:
parent
75ba301116
commit
f46276a9b0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=215011
4 changed files with 48 additions and 0 deletions
|
@ -1212,6 +1212,7 @@ MLINKS+=sysctl_ctx_init.9 sysctl_ctx_entry_add.9 \
|
|||
sysctl_ctx_init.9 sysctl_ctx_entry_find.9 \
|
||||
sysctl_ctx_init.9 sysctl_ctx_free.9
|
||||
MLINKS+=taskqueue.9 TASK_INIT.9 \
|
||||
taskqueue.9 taskqueue_cancel.9 \
|
||||
taskqueue.9 taskqueue_create.9 \
|
||||
taskqueue.9 taskqueue_create_fast.9 \
|
||||
taskqueue.9 TASKQUEUE_DECLARE.9 \
|
||||
|
|
|
@ -63,6 +63,8 @@ struct task {
|
|||
.Fn taskqueue_enqueue "struct taskqueue *queue" "struct task *task"
|
||||
.Ft int
|
||||
.Fn taskqueue_enqueue_fast "struct taskqueue *queue" "struct task *task"
|
||||
.Ft int
|
||||
.Fn taskqueue_cancel "struct taskqueue *queue" "struct task *task" "u_int *pendp"
|
||||
.Ft void
|
||||
.Fn taskqueue_drain "struct taskqueue *queue" "struct task *task"
|
||||
.Ft int
|
||||
|
@ -162,6 +164,31 @@ is called on the task pointer passed to
|
|||
.Fn taskqueue_enqueue .
|
||||
.Pp
|
||||
The
|
||||
.Fn taskqueue_cancel
|
||||
function is used to cancel a task.
|
||||
The
|
||||
.Va ta_pending
|
||||
count is cleared, and the old value returned in the reference
|
||||
parameter
|
||||
.Fa pendp ,
|
||||
if it is non- Dv NULL .
|
||||
If the task is currently running,
|
||||
.Dv EBUSY
|
||||
is returned, otherwise 0.
|
||||
To implement a blocking
|
||||
.Fn taskqueue_cancel
|
||||
that waits for a running task to finish, it could look like:
|
||||
.Bd -literal -offset indent
|
||||
while (taskqueue_cancel(tq, task, NULL) != 0)
|
||||
taskqueue_drain(tq, task);
|
||||
.Ed
|
||||
.Pp
|
||||
Note that, as with
|
||||
.Fn taskqueue_drain ,
|
||||
the caller is responsible for ensuring that the task is not re-enqueued
|
||||
after being canceled.
|
||||
.Pp
|
||||
The
|
||||
.Fn taskqueue_drain
|
||||
function is used to wait for the task to finish.
|
||||
There is no guarantee that the task will not be
|
||||
|
|
|
@ -275,6 +275,24 @@ task_is_running(struct taskqueue *queue, struct task *task)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
taskqueue_cancel(struct taskqueue *queue, struct task *task, u_int *pendp)
|
||||
{
|
||||
u_int pending;
|
||||
int error;
|
||||
|
||||
TQ_LOCK(queue);
|
||||
if ((pending = task->ta_pending) > 0)
|
||||
STAILQ_REMOVE(&queue->tq_queue, task, task, ta_link);
|
||||
task->ta_pending = 0;
|
||||
error = task_is_running(queue, task) ? EBUSY : 0;
|
||||
TQ_UNLOCK(queue);
|
||||
|
||||
if (pendp != NULL)
|
||||
*pendp = pending;
|
||||
return (error);
|
||||
}
|
||||
|
||||
void
|
||||
taskqueue_drain(struct taskqueue *queue, struct task *task)
|
||||
{
|
||||
|
|
|
@ -54,6 +54,8 @@ struct taskqueue *taskqueue_create(const char *name, int mflags,
|
|||
int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
|
||||
const char *name, ...) __printflike(4, 5);
|
||||
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
|
||||
int taskqueue_cancel(struct taskqueue *queue, struct task *task,
|
||||
u_int *pendp);
|
||||
void taskqueue_drain(struct taskqueue *queue, struct task *task);
|
||||
void taskqueue_free(struct taskqueue *queue);
|
||||
void taskqueue_run(struct taskqueue *queue);
|
||||
|
|
Loading…
Reference in a new issue