* Block until all currently queued tasks in this taskqueue * have begun execution. Tasks queued during execution of * this function are ignored. */
| 259 | * this function are ignored. |
| 260 | */ |
| 261 | static void |
| 262 | gtaskqueue_drain_tq_queue(struct gtaskqueue *queue) |
| 263 | { |
| 264 | struct gtask t_barrier; |
| 265 | |
| 266 | if (STAILQ_EMPTY(&queue->tq_queue)) |
| 267 | return; |
| 268 | |
| 269 | /* |
| 270 | * Enqueue our barrier after all current tasks, but with |
| 271 | * the highest priority so that newly queued tasks cannot |
| 272 | * pass it. Because of the high priority, we can not use |
| 273 | * taskqueue_enqueue_locked directly (which drops the lock |
| 274 | * anyway) so just insert it at tail while we have the |
| 275 | * queue lock. |
| 276 | */ |
| 277 | GTASK_INIT(&t_barrier, 0, USHRT_MAX, gtaskqueue_task_nop_fn, &t_barrier); |
| 278 | STAILQ_INSERT_TAIL(&queue->tq_queue, &t_barrier, ta_link); |
| 279 | t_barrier.ta_flags |= TASK_ENQUEUED; |
| 280 | |
| 281 | /* |
| 282 | * Once the barrier has executed, all previously queued tasks |
| 283 | * have completed or are currently executing. |
| 284 | */ |
| 285 | while (t_barrier.ta_flags & TASK_ENQUEUED) |
| 286 | TQ_SLEEP(queue, &t_barrier, "gtq_qdrain"); |
| 287 | } |
| 288 | |
| 289 | /* |
| 290 | * Block until all currently executing tasks for this taskqueue |
no test coverage detected