diff options
author | Jo-Philipp Wich <jo@mein.io> | 2023-07-11 13:49:55 +0200 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2023-07-27 14:32:16 +0200 |
commit | 2593270498be82de82f770cb3744d9e5f8d0b0bd (patch) | |
tree | fb6cf7d52f641e35316b4db39a1a424927d77ba5 /lib/uloop.c | |
parent | 97a5292307bebc4c3be45f47743268084b376d09 (diff) |
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 <jo@mein.io>
Diffstat (limited to 'lib/uloop.c')
-rw-r--r-- | lib/uloop.c | 24 |
1 files changed, 24 insertions, 0 deletions
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); + } } |