Lines Matching refs:loop
95 static zx_status_t async_loop_run_once(async_loop_t* loop, zx_time_t deadline);
96 static zx_status_t async_loop_dispatch_wait(async_loop_t* loop, async_wait_t* wait,
98 static zx_status_t async_loop_dispatch_tasks(async_loop_t* loop);
99 static void async_loop_dispatch_task(async_loop_t* loop, async_task_t* task,
101 static zx_status_t async_loop_dispatch_packet(async_loop_t* loop, async_receiver_t* receiver,
103 static zx_status_t async_loop_dispatch_guest_bell_trap(async_loop_t* loop,
107 static zx_status_t async_loop_dispatch_exception(async_loop_t* loop,
111 static void async_loop_wake_threads(async_loop_t* loop);
112 static void async_loop_insert_task_locked(async_loop_t* loop, async_task_t* task);
113 static void async_loop_restart_timer_locked(async_loop_t* loop);
114 static void async_loop_invoke_prologue(async_loop_t* loop);
115 static void async_loop_invoke_epilogue(async_loop_t* loop);
151 async_loop_t* loop = calloc(1u, sizeof(async_loop_t)); in async_loop_create() local
152 if (!loop) in async_loop_create()
154 atomic_init(&loop->state, ASYNC_LOOP_RUNNABLE); in async_loop_create()
155 atomic_init(&loop->active_threads, 0u); in async_loop_create()
157 loop->dispatcher.ops = &async_loop_ops; in async_loop_create()
158 loop->config = *config; in async_loop_create()
159 mtx_init(&loop->lock, mtx_plain); in async_loop_create()
160 list_initialize(&loop->wait_list); in async_loop_create()
161 list_initialize(&loop->task_list); in async_loop_create()
162 list_initialize(&loop->due_list); in async_loop_create()
163 list_initialize(&loop->thread_list); in async_loop_create()
164 list_initialize(&loop->exception_list); in async_loop_create()
166 zx_status_t status = zx_port_create(0u, &loop->port); in async_loop_create()
168 status = zx_timer_create(0u, ZX_CLOCK_MONOTONIC, &loop->timer); in async_loop_create()
170 status = zx_object_wait_async(loop->timer, loop->port, KEY_CONTROL, in async_loop_create()
175 *out_loop = loop; in async_loop_create()
176 if (loop->config.make_default_for_current_thread) { in async_loop_create()
178 async_set_default_dispatcher(&loop->dispatcher); in async_loop_create()
181 loop->config.make_default_for_current_thread = false; in async_loop_create()
182 async_loop_destroy(loop); in async_loop_create()
187 void async_loop_destroy(async_loop_t* loop) { in async_loop_destroy() argument
188 ZX_DEBUG_ASSERT(loop); in async_loop_destroy()
190 async_loop_shutdown(loop); in async_loop_destroy()
192 zx_handle_close(loop->port); in async_loop_destroy()
193 zx_handle_close(loop->timer); in async_loop_destroy()
194 mtx_destroy(&loop->lock); in async_loop_destroy()
195 free(loop); in async_loop_destroy()
198 void async_loop_shutdown(async_loop_t* loop) { in async_loop_shutdown() argument
199 ZX_DEBUG_ASSERT(loop); in async_loop_shutdown()
202 atomic_exchange_explicit(&loop->state, ASYNC_LOOP_SHUTDOWN, in async_loop_shutdown()
207 async_loop_wake_threads(loop); in async_loop_shutdown()
208 async_loop_join_threads(loop); in async_loop_shutdown()
211 while ((node = list_remove_head(&loop->wait_list))) { in async_loop_shutdown()
213 async_loop_dispatch_wait(loop, wait, ZX_ERR_CANCELED, NULL); in async_loop_shutdown()
215 while ((node = list_remove_head(&loop->due_list))) { in async_loop_shutdown()
217 async_loop_dispatch_task(loop, task, ZX_ERR_CANCELED); in async_loop_shutdown()
219 while ((node = list_remove_head(&loop->task_list))) { in async_loop_shutdown()
221 async_loop_dispatch_task(loop, task, ZX_ERR_CANCELED); in async_loop_shutdown()
223 while ((node = list_remove_head(&loop->exception_list))) { in async_loop_shutdown()
225 async_loop_dispatch_exception(loop, exception, ZX_ERR_CANCELED, NULL); in async_loop_shutdown()
228 if (loop->config.make_default_for_current_thread) { in async_loop_shutdown()
229 ZX_DEBUG_ASSERT(async_get_default_dispatcher() == &loop->dispatcher); in async_loop_shutdown()
234 zx_status_t async_loop_run(async_loop_t* loop, zx_time_t deadline, bool once) { in async_loop_run() argument
235 ZX_DEBUG_ASSERT(loop); in async_loop_run()
238 atomic_fetch_add_explicit(&loop->active_threads, 1u, memory_order_acq_rel); in async_loop_run()
240 status = async_loop_run_once(loop, deadline); in async_loop_run()
242 atomic_fetch_sub_explicit(&loop->active_threads, 1u, memory_order_acq_rel); in async_loop_run()
246 zx_status_t async_loop_run_until_idle(async_loop_t* loop) { in async_loop_run_until_idle() argument
247 zx_status_t status = async_loop_run(loop, 0, false); in async_loop_run_until_idle()
254 static zx_status_t async_loop_run_once(async_loop_t* loop, zx_time_t deadline) { in async_loop_run_once() argument
255 async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire); in async_loop_run_once()
262 zx_status_t status = zx_port_wait(loop->port, deadline, &packet); in async_loop_run_once()
274 return async_loop_dispatch_tasks(loop); in async_loop_run_once()
280 mtx_lock(&loop->lock); in async_loop_run_once()
282 mtx_unlock(&loop->lock); in async_loop_run_once()
283 return async_loop_dispatch_wait(loop, wait, packet.status, &packet.signal); in async_loop_run_once()
289 return async_loop_dispatch_packet(loop, receiver, packet.status, &packet.user); in async_loop_run_once()
296 loop, trap, packet.status, &packet.guest_bell); in async_loop_run_once()
302 return async_loop_dispatch_exception(loop, exception, packet.status, in async_loop_run_once()
311 async_dispatcher_t* async_loop_get_dispatcher(async_loop_t* loop) { in async_loop_get_dispatcher() argument
313 return (async_dispatcher_t*)loop; in async_loop_get_dispatcher()
320 static zx_status_t async_loop_dispatch_guest_bell_trap(async_loop_t* loop, in async_loop_dispatch_guest_bell_trap() argument
324 async_loop_invoke_prologue(loop); in async_loop_dispatch_guest_bell_trap()
325 trap->handler((async_dispatcher_t*)loop, trap, status, bell); in async_loop_dispatch_guest_bell_trap()
326 async_loop_invoke_epilogue(loop); in async_loop_dispatch_guest_bell_trap()
330 static zx_status_t async_loop_dispatch_wait(async_loop_t* loop, async_wait_t* wait, in async_loop_dispatch_wait() argument
332 async_loop_invoke_prologue(loop); in async_loop_dispatch_wait()
333 wait->handler((async_dispatcher_t*)loop, wait, status, signal); in async_loop_dispatch_wait()
334 async_loop_invoke_epilogue(loop); in async_loop_dispatch_wait()
338 static zx_status_t async_loop_dispatch_tasks(async_loop_t* loop) { in async_loop_dispatch_tasks() argument
343 mtx_lock(&loop->lock); in async_loop_dispatch_tasks()
344 if (!loop->dispatching_tasks) { in async_loop_dispatch_tasks()
345 loop->dispatching_tasks = true; in async_loop_dispatch_tasks()
351 if (list_is_empty(&loop->due_list)) { in async_loop_dispatch_tasks()
352 zx_time_t due_time = async_loop_now((async_dispatcher_t*)loop); in async_loop_dispatch_tasks()
354 list_for_every(&loop->task_list, node) { in async_loop_dispatch_tasks()
360 list_node_t* head = loop->task_list.next; in async_loop_dispatch_tasks()
361 loop->task_list.next = tail->next; in async_loop_dispatch_tasks()
362 tail->next->prev = &loop->task_list; in async_loop_dispatch_tasks()
363 loop->due_list.next = head; in async_loop_dispatch_tasks()
364 head->prev = &loop->due_list; in async_loop_dispatch_tasks()
365 loop->due_list.prev = tail; in async_loop_dispatch_tasks()
366 tail->next = &loop->due_list; in async_loop_dispatch_tasks()
373 while ((node = list_remove_head(&loop->due_list))) { in async_loop_dispatch_tasks()
374 mtx_unlock(&loop->lock); in async_loop_dispatch_tasks()
378 async_loop_dispatch_task(loop, task, ZX_OK); in async_loop_dispatch_tasks()
380 mtx_lock(&loop->lock); in async_loop_dispatch_tasks()
381 async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire); in async_loop_dispatch_tasks()
386 loop->dispatching_tasks = false; in async_loop_dispatch_tasks()
387 async_loop_restart_timer_locked(loop); in async_loop_dispatch_tasks()
389 mtx_unlock(&loop->lock); in async_loop_dispatch_tasks()
393 static void async_loop_dispatch_task(async_loop_t* loop, in async_loop_dispatch_task() argument
397 async_loop_invoke_prologue(loop); in async_loop_dispatch_task()
398 task->handler((async_dispatcher_t*)loop, task, status); in async_loop_dispatch_task()
399 async_loop_invoke_epilogue(loop); in async_loop_dispatch_task()
402 static zx_status_t async_loop_dispatch_packet(async_loop_t* loop, async_receiver_t* receiver, in async_loop_dispatch_packet() argument
405 async_loop_invoke_prologue(loop); in async_loop_dispatch_packet()
406 receiver->handler((async_dispatcher_t*)loop, receiver, status, data); in async_loop_dispatch_packet()
407 async_loop_invoke_epilogue(loop); in async_loop_dispatch_packet()
411 static zx_status_t async_loop_dispatch_exception(async_loop_t* loop, in async_loop_dispatch_exception() argument
416 async_loop_invoke_prologue(loop); in async_loop_dispatch_exception()
417 exception->handler((async_dispatcher_t*)loop, exception, status, report); in async_loop_dispatch_exception()
418 async_loop_invoke_epilogue(loop); in async_loop_dispatch_exception()
422 void async_loop_quit(async_loop_t* loop) { in async_loop_quit() argument
423 ZX_DEBUG_ASSERT(loop); in async_loop_quit()
426 if (!atomic_compare_exchange_strong_explicit(&loop->state, &expected_state, in async_loop_quit()
431 async_loop_wake_threads(loop); in async_loop_quit()
434 static void async_loop_wake_threads(async_loop_t* loop) { in async_loop_wake_threads() argument
440 uint32_t n = atomic_load_explicit(&loop->active_threads, memory_order_acquire); in async_loop_wake_threads()
446 zx_status_t status = zx_port_queue(loop->port, &packet); in async_loop_wake_threads()
451 zx_status_t async_loop_reset_quit(async_loop_t* loop) { in async_loop_reset_quit() argument
452 ZX_DEBUG_ASSERT(loop); in async_loop_reset_quit()
458 uint32_t n = atomic_load_explicit(&loop->active_threads, memory_order_acquire); in async_loop_reset_quit()
463 if (atomic_compare_exchange_strong_explicit(&loop->state, &expected_state, in async_loop_reset_quit()
469 async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire); in async_loop_reset_quit()
475 async_loop_state_t async_loop_get_state(async_loop_t* loop) { in async_loop_get_state() argument
476 ZX_DEBUG_ASSERT(loop); in async_loop_get_state()
478 return atomic_load_explicit(&loop->state, memory_order_acquire); in async_loop_get_state()
486 async_loop_t* loop = (async_loop_t*)async; in async_loop_begin_wait() local
487 ZX_DEBUG_ASSERT(loop); in async_loop_begin_wait()
490 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_begin_wait()
493 mtx_lock(&loop->lock); in async_loop_begin_wait()
496 wait->object, loop->port, (uintptr_t)wait, wait->trigger, ZX_WAIT_ASYNC_ONCE); in async_loop_begin_wait()
498 list_add_head(&loop->wait_list, wait_to_node(wait)); in async_loop_begin_wait()
504 mtx_unlock(&loop->lock); in async_loop_begin_wait()
509 async_loop_t* loop = (async_loop_t*)async; in async_loop_cancel_wait() local
510 ZX_DEBUG_ASSERT(loop); in async_loop_cancel_wait()
517 mtx_lock(&loop->lock); in async_loop_cancel_wait()
522 mtx_unlock(&loop->lock); in async_loop_cancel_wait()
529 zx_status_t status = zx_port_cancel(loop->port, wait->object, in async_loop_cancel_wait()
538 mtx_unlock(&loop->lock); in async_loop_cancel_wait()
543 async_loop_t* loop = (async_loop_t*)async; in async_loop_post_task() local
544 ZX_DEBUG_ASSERT(loop); in async_loop_post_task()
547 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_post_task()
550 mtx_lock(&loop->lock); in async_loop_post_task()
552 async_loop_insert_task_locked(loop, task); in async_loop_post_task()
553 if (!loop->dispatching_tasks && in async_loop_post_task()
554 task_to_node(task)->prev == &loop->task_list) { in async_loop_post_task()
556 async_loop_restart_timer_locked(loop); in async_loop_post_task()
559 mtx_unlock(&loop->lock); in async_loop_post_task()
564 async_loop_t* loop = (async_loop_t*)async; in async_loop_cancel_task() local
565 ZX_DEBUG_ASSERT(loop); in async_loop_cancel_task()
575 mtx_lock(&loop->lock); in async_loop_cancel_task()
578 mtx_unlock(&loop->lock); in async_loop_cancel_task()
584 bool must_restart = !loop->dispatching_tasks && in async_loop_cancel_task()
585 node->prev == &loop->task_list && in async_loop_cancel_task()
586 node->next != &loop->task_list && in async_loop_cancel_task()
590 async_loop_restart_timer_locked(loop); in async_loop_cancel_task()
592 mtx_unlock(&loop->lock); in async_loop_cancel_task()
598 async_loop_t* loop = (async_loop_t*)async; in async_loop_queue_packet() local
599 ZX_DEBUG_ASSERT(loop); in async_loop_queue_packet()
602 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_queue_packet()
611 return zx_port_queue(loop->port, &packet); in async_loop_queue_packet()
617 async_loop_t* loop = (async_loop_t*)async; in async_loop_set_guest_bell_trap() local
618 ZX_DEBUG_ASSERT(loop); in async_loop_set_guest_bell_trap()
621 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_set_guest_bell_trap()
625 length, loop->port, (uintptr_t)trap); in async_loop_set_guest_bell_trap()
639 async_loop_t* loop = (async_loop_t*)async; in async_loop_bind_exception_port() local
640 ZX_DEBUG_ASSERT(loop); in async_loop_bind_exception_port()
643 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_bind_exception_port()
646 mtx_lock(&loop->lock); in async_loop_bind_exception_port()
649 zx_status_t status = zx_task_bind_exception_port(exception->task, loop->port, in async_loop_bind_exception_port()
652 list_add_head(&loop->exception_list, exception_to_node(exception)); in async_loop_bind_exception_port()
655 mtx_unlock(&loop->lock); in async_loop_bind_exception_port()
661 async_loop_t* loop = (async_loop_t*)async; in async_loop_unbind_exception_port() local
662 ZX_DEBUG_ASSERT(loop); in async_loop_unbind_exception_port()
669 mtx_lock(&loop->lock); in async_loop_unbind_exception_port()
674 mtx_unlock(&loop->lock); in async_loop_unbind_exception_port()
686 mtx_unlock(&loop->lock); in async_loop_unbind_exception_port()
694 async_loop_t* loop = (async_loop_t*)async; in async_loop_resume_from_exception() local
695 ZX_DEBUG_ASSERT(loop); in async_loop_resume_from_exception()
698 if (atomic_load_explicit(&loop->state, memory_order_acquire) == ASYNC_LOOP_SHUTDOWN) in async_loop_resume_from_exception()
701 return zx_task_resume_from_exception(task, loop->port, options); in async_loop_resume_from_exception()
704 static void async_loop_insert_task_locked(async_loop_t* loop, async_task_t* task) { in async_loop_insert_task_locked() argument
710 for (node = loop->task_list.prev; node != &loop->task_list; node = node->prev) { in async_loop_insert_task_locked()
717 static void async_loop_restart_timer_locked(async_loop_t* loop) { in async_loop_restart_timer_locked() argument
719 if (list_is_empty(&loop->due_list)) { in async_loop_restart_timer_locked()
720 list_node_t* head = list_peek_head(&loop->task_list); in async_loop_restart_timer_locked()
732 zx_status_t status = zx_timer_set(loop->timer, deadline, 0); in async_loop_restart_timer_locked()
736 static void async_loop_invoke_prologue(async_loop_t* loop) { in async_loop_invoke_prologue() argument
737 if (loop->config.prologue) in async_loop_invoke_prologue()
738 loop->config.prologue(loop, loop->config.data); in async_loop_invoke_prologue()
741 static void async_loop_invoke_epilogue(async_loop_t* loop) { in async_loop_invoke_epilogue() argument
742 if (loop->config.epilogue) in async_loop_invoke_epilogue()
743 loop->config.epilogue(loop, loop->config.data); in async_loop_invoke_epilogue()
747 async_loop_t* loop = (async_loop_t*)data; in async_loop_run_thread() local
748 async_set_default_dispatcher(&loop->dispatcher); in async_loop_run_thread()
749 async_loop_run(loop, ZX_TIME_INFINITE, false); in async_loop_run_thread()
753 zx_status_t async_loop_start_thread(async_loop_t* loop, const char* name, thrd_t* out_thread) { in async_loop_start_thread() argument
754 ZX_DEBUG_ASSERT(loop); in async_loop_start_thread()
758 async_loop_state_t state = atomic_load_explicit(&loop->state, memory_order_acquire); in async_loop_start_thread()
766 if (thrd_create_with_name(&rec->thread, async_loop_run_thread, loop, name) != thrd_success) { in async_loop_start_thread()
771 mtx_lock(&loop->lock); in async_loop_start_thread()
772 list_add_tail(&loop->thread_list, &rec->node); in async_loop_start_thread()
773 mtx_unlock(&loop->lock); in async_loop_start_thread()
780 void async_loop_join_threads(async_loop_t* loop) { in async_loop_join_threads() argument
781 ZX_DEBUG_ASSERT(loop); in async_loop_join_threads()
783 mtx_lock(&loop->lock); in async_loop_join_threads()
785 thread_record_t* rec = (thread_record_t*)list_remove_head(&loop->thread_list); in async_loop_join_threads()
789 mtx_unlock(&loop->lock); in async_loop_join_threads()
794 mtx_lock(&loop->lock); in async_loop_join_threads()
796 mtx_unlock(&loop->lock); in async_loop_join_threads()