From a146f4a7505b05fbeb67eedc0e792734144af728 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sat, 14 Mar 2026 22:32:26 +0000 Subject: [PATCH] syscall: fix some missed-signal bugs in kern_object_wait --- syscall/object.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/syscall/object.c b/syscall/object.c index 23a07f8..5c9f939 100644 --- a/syscall/object.c +++ b/syscall/object.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -18,31 +19,36 @@ kern_status_t sys_kern_object_wait(kern_wait_item_t *items, size_t nr_items) return KERN_MEMORY_FAULT; } + self_thread->tr_state = THREAD_SLEEPING; + kern_status_t status = KERN_OK; struct object *objects[KERN_WAIT_MAX_ITEMS]; struct wait_item waiters[KERN_WAIT_MAX_ITEMS]; unsigned long irq_flags = 0; - size_t i = 0, to_release = 0; + size_t nr_retained = 0; bool signals_observed = false; - for (i = 0; i < nr_items; i++) { - kern_handle_t handle = items[i].w_handle; + for (nr_retained = 0; nr_retained < nr_items; nr_retained++) { + kern_handle_t handle = items[nr_retained].w_handle; handle_flags_t flags; struct object *object = NULL; + status = task_resolve_handle(self, handle, &object, &flags); if (status != KERN_OK) { break; } - objects[i] = object; + objects[nr_retained] = object; object_lock_irqsave(object, &irq_flags); - wait_item_init(&waiters[i], self_thread); - thread_wait_begin(&waiters[i], &object->ob_wq); + wait_item_init(&waiters[nr_retained], self_thread); + thread_wait_begin_nosleep( + &waiters[nr_retained], + &object->ob_wq); - if (object->ob_signals & items[i].w_waitfor) { + if (object->ob_signals & items[nr_retained].w_waitfor) { signals_observed = true; - items[i].w_observed = object->ob_signals; + items[nr_retained].w_observed = object->ob_signals; } object_unlock_irqrestore(object, irq_flags); @@ -54,22 +60,23 @@ kern_status_t sys_kern_object_wait(kern_wait_item_t *items, size_t nr_items) schedule(SCHED_NORMAL); - for (i = 0; i < nr_items; i++) { + for (size_t i = 0; i < nr_retained; i++) { object_lock_irqsave(objects[i], &irq_flags); if (objects[i]->ob_signals & items[i].w_waitfor) { signals_observed = true; + items[i].w_observed = objects[i]->ob_signals; } object_unlock_irqrestore(objects[i], irq_flags); } cleanup: - to_release = i; - for (i = 0; i < to_release; i++) { - thread_wait_end(&waiters[i], &objects[i]->ob_wq); + for (size_t i = 0; i < nr_retained; i++) { + thread_wait_end_nosleep(&waiters[i], &objects[i]->ob_wq); object_unref(objects[i]); } + self_thread->tr_state = THREAD_READY; return status; }