From 2593270498be82de82f770cb3744d9e5f8d0b0bd Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Tue, 11 Jul 2023 13:49:55 +0200 Subject: uloop: interrupt on VM signals When the VM instance loading the uloop module has signal dispatching enabled, implicitly register the signal pipe as file descriptor in the global uloop and dispatch received signals to the VM instance. This ensures that the respective managed ucode signal handlers are invoked immediately and not just after `uloop_run()` returns. Also end the uloop in case any invoked signal handler threw an exception, to match the expected behaviour with other kinds of callbacks. Signed-off-by: Jo-Philipp Wich --- lib/uloop.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'lib') diff --git a/lib/uloop.c b/lib/uloop.c index f45f8c3..99cd984 100644 --- a/lib/uloop.c +++ b/lib/uloop.c @@ -1155,8 +1155,22 @@ static void close_pipe(void *ud) } +static struct { + struct uloop_fd ufd; + uc_vm_t *vm; +} signal_handle; + +static void +uc_uloop_signal_cb(struct uloop_fd *ufd, unsigned int events) +{ + if (uc_vm_signal_dispatch(signal_handle.vm) != EXCEPTION_NONE) + uloop_end(); +} + void uc_module_init(uc_vm_t *vm, uc_value_t *scope) { + int signal_fd; + uc_function_list_register(scope, global_fns); #define ADD_CONST(x) ucv_object_add(scope, #x, ucv_int64_new(x)) @@ -1175,4 +1189,14 @@ void uc_module_init(uc_vm_t *vm, uc_value_t *scope) object_registry = ucv_array_new(vm); uc_vm_registry_set(vm, "uloop.registry", object_registry); + + signal_fd = uc_vm_signal_notifyfd(vm); + + if (signal_fd != -1 && uloop_init() == 0) { + signal_handle.vm = vm; + signal_handle.ufd.cb = uc_uloop_signal_cb; + signal_handle.ufd.fd = signal_fd; + + uloop_fd_add(&signal_handle.ufd, ULOOP_READ); + } } -- cgit v1.2.3