summaryrefslogtreecommitdiffhomepage
path: root/lib/uloop.c
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2023-07-11 13:49:55 +0200
committerJo-Philipp Wich <jo@mein.io>2023-07-27 14:32:16 +0200
commit2593270498be82de82f770cb3744d9e5f8d0b0bd (patch)
treefb6cf7d52f641e35316b4db39a1a424927d77ba5 /lib/uloop.c
parent97a5292307bebc4c3be45f47743268084b376d09 (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.c24
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);
+ }
}