Author: markj
Date: Wed Nov 28 17:00:18 2018
New Revision: 341154
URL: https://svnweb.freebsd.org/changeset/base/341154

Log:
  MFC r340730, r340731:
  Add taskqueue_quiesce(9) and use it to implement taskq_wait().
  
  PR:   227784

Modified:
  stable/11/share/man/man9/Makefile
  stable/11/share/man/man9/taskqueue.9
  stable/11/sys/kern/subr_taskqueue.c
  stable/11/sys/sys/taskqueue.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/share/man/man9/Makefile
==============================================================================
--- stable/11/share/man/man9/Makefile   Wed Nov 28 16:58:35 2018        
(r341153)
+++ stable/11/share/man/man9/Makefile   Wed Nov 28 17:00:18 2018        
(r341154)
@@ -1814,6 +1814,7 @@ MLINKS+=taskqueue.9 TASK_INIT.9 \
        taskqueue.9 TASKQUEUE_FAST_DEFINE_THREAD.9 \
        taskqueue.9 taskqueue_free.9 \
        taskqueue.9 taskqueue_member.9 \
+       taskqueue.9 taskqueue_quiesce.9 \
        taskqueue.9 taskqueue_run.9 \
        taskqueue.9 taskqueue_set_callback.9 \
        taskqueue.9 taskqueue_start_threads.9 \

Modified: stable/11/share/man/man9/taskqueue.9
==============================================================================
--- stable/11/share/man/man9/taskqueue.9        Wed Nov 28 16:58:35 2018        
(r341153)
+++ stable/11/share/man/man9/taskqueue.9        Wed Nov 28 17:00:18 2018        
(r341154)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd July 30, 2017
+.Dd November 21, 2018
 .Dt TASKQUEUE 9
 .Os
 .Sh NAME
@@ -94,6 +94,8 @@ struct timeout_task;
 .Ft void
 .Fn taskqueue_drain_all "struct taskqueue *queue"
 .Ft void
+.Fn taskqueue_quiesce "struct taskqueue *queue"
+.Ft void
 .Fn taskqueue_block "struct taskqueue *queue"
 .Ft void
 .Fn taskqueue_unblock "struct taskqueue *queue"
@@ -298,6 +300,12 @@ do not extend the wait time of
 and may complete after
 .Fn taskqueue_drain_all
 returns.
+The
+.Fn taskqueue_quiesce
+function is used to wait for the queue to become empty and for all
+running tasks to finish.
+To avoid blocking indefinitely, the caller must ensure by some mechanism
+that tasks will eventually stop being posted to the queue.
 .Pp
 The
 .Fn taskqueue_block

Modified: stable/11/sys/kern/subr_taskqueue.c
==============================================================================
--- stable/11/sys/kern/subr_taskqueue.c Wed Nov 28 16:58:35 2018        
(r341153)
+++ stable/11/sys/kern/subr_taskqueue.c Wed Nov 28 17:00:18 2018        
(r341154)
@@ -344,13 +344,13 @@ taskqueue_task_nop_fn(void *context, int pending)
  * have begun execution.  Tasks queued during execution of
  * this function are ignored.
  */
-static void
+static int
 taskqueue_drain_tq_queue(struct taskqueue *queue)
 {
        struct task t_barrier;
 
        if (STAILQ_EMPTY(&queue->tq_queue))
-               return;
+               return (0);
 
        /*
         * Enqueue our barrier after all current tasks, but with
@@ -370,6 +370,7 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
         */
        while (t_barrier.ta_pending != 0)
                TQ_SLEEP(queue, &t_barrier, &queue->tq_mutex, PWAIT, "-", 0);
+       return (1);
 }
 
 /*
@@ -377,13 +378,13 @@ taskqueue_drain_tq_queue(struct taskqueue *queue)
  * complete.  Tasks that begin execution during the execution
  * of this function are ignored.
  */
-static void
+static int
 taskqueue_drain_tq_active(struct taskqueue *queue)
 {
        struct taskqueue_busy tb_marker, *tb_first;
 
        if (TAILQ_EMPTY(&queue->tq_active))
-               return;
+               return (0);
 
        /* Block taskq_terminate().*/
        queue->tq_callouts++;
@@ -410,6 +411,7 @@ taskqueue_drain_tq_active(struct taskqueue *queue)
        queue->tq_callouts--;
        if ((queue->tq_flags & TQ_FLAGS_ACTIVE) == 0)
                wakeup_one(queue->tq_threads);
+       return (1);
 }
 
 void
@@ -580,8 +582,8 @@ taskqueue_drain_all(struct taskqueue *queue)
                WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__);
 
        TQ_LOCK(queue);
-       taskqueue_drain_tq_queue(queue);
-       taskqueue_drain_tq_active(queue);
+       (void)taskqueue_drain_tq_queue(queue);
+       (void)taskqueue_drain_tq_active(queue);
        TQ_UNLOCK(queue);
 }
 
@@ -607,6 +609,20 @@ taskqueue_drain_timeout(struct taskqueue *queue,
         */
        TQ_LOCK(queue);
        timeout_task->f &= ~DT_DRAIN_IN_PROGRESS;
+       TQ_UNLOCK(queue);
+}
+
+void
+taskqueue_quiesce(struct taskqueue *queue)
+{
+       int ret;
+
+       TQ_LOCK(queue);
+       do {
+               ret = taskqueue_drain_tq_queue(queue);
+               if (ret == 0)
+                       ret = taskqueue_drain_tq_active(queue);
+       } while (ret != 0);
        TQ_UNLOCK(queue);
 }
 

Modified: stable/11/sys/sys/taskqueue.h
==============================================================================
--- stable/11/sys/sys/taskqueue.h       Wed Nov 28 16:58:35 2018        
(r341153)
+++ stable/11/sys/sys/taskqueue.h       Wed Nov 28 17:00:18 2018        
(r341154)
@@ -91,6 +91,7 @@ void  taskqueue_drain(struct taskqueue *queue, struct t
 void   taskqueue_drain_timeout(struct taskqueue *queue,
            struct timeout_task *timeout_task);
 void   taskqueue_drain_all(struct taskqueue *queue);
+void   taskqueue_quiesce(struct taskqueue *queue);
 void   taskqueue_free(struct taskqueue *queue);
 void   taskqueue_run(struct taskqueue *queue);
 void   taskqueue_block(struct taskqueue *queue);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to