From owner-svn-src-head@FreeBSD.ORG Mon Nov 8 20:56:31 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C00B9106566B; Mon, 8 Nov 2010 20:56:31 +0000 (UTC) (envelope-from mdf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id ADCD68FC12; Mon, 8 Nov 2010 20:56:31 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id oA8KuVM3053229; Mon, 8 Nov 2010 20:56:31 GMT (envelope-from mdf@svn.freebsd.org) Received: (from mdf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id oA8KuVoJ053224; Mon, 8 Nov 2010 20:56:31 GMT (envelope-from mdf@svn.freebsd.org) Message-Id: <201011082056.oA8KuVoJ053224@svn.freebsd.org> From: Matthew D Fleming Date: Mon, 8 Nov 2010 20:56:31 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r215011 - in head: share/man/man9 sys/kern sys/sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Nov 2010 20:56:31 -0000 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);