Author: mdf
Date: Mon Nov  8 20:56:31 2010
New Revision: 215011
URL: http://svn.freebsd.org/changeset/base/215011

Log:
  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

Modified:
  head/share/man/man9/Makefile
  head/share/man/man9/taskqueue.9
  head/sys/kern/subr_taskqueue.c
  head/sys/sys/taskqueue.h

Modified: head/share/man/man9/Makefile
==============================================================================
--- head/share/man/man9/Makefile        Mon Nov  8 20:44:11 2010        
(r215010)
+++ head/share/man/man9/Makefile        Mon Nov  8 20:56:31 2010        
(r215011)
@@ -1212,6 +1212,7 @@ MLINKS+=sysctl_ctx_init.9 sysctl_ctx_ent
        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 \

Modified: head/share/man/man9/taskqueue.9
==============================================================================
--- head/share/man/man9/taskqueue.9     Mon Nov  8 20:44:11 2010        
(r215010)
+++ head/share/man/man9/taskqueue.9     Mon Nov  8 20:56:31 2010        
(r215011)
@@ -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

Modified: head/sys/kern/subr_taskqueue.c
==============================================================================
--- head/sys/kern/subr_taskqueue.c      Mon Nov  8 20:44:11 2010        
(r215010)
+++ head/sys/kern/subr_taskqueue.c      Mon Nov  8 20:56:31 2010        
(r215011)
@@ -275,6 +275,24 @@ task_is_running(struct taskqueue *queue,
        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)
 {

Modified: head/sys/sys/taskqueue.h
==============================================================================
--- head/sys/sys/taskqueue.h    Mon Nov  8 20:44:11 2010        (r215010)
+++ head/sys/sys/taskqueue.h    Mon Nov  8 20:56:31 2010        (r215011)
@@ -54,6 +54,8 @@ struct taskqueue *taskqueue_create(const
 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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to