svn commit: r215011 - in head: share/man/man9 sys/kern sys/sys

Matthew D Fleming mdf at FreeBSD.org
Mon Nov 8 20:56:31 UTC 2010


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);


More information about the svn-src-head mailing list