From e7e930323660c6b0b277a998e178f18b074c3d5c Mon Sep 17 00:00:00 2001 From: Luke Gruber Date: Fri, 23 Jan 2026 11:54:44 -0500 Subject: [PATCH] Fix kqueue timeout for 0-valued timespec (#15940) Timeout with 0-valued timespec means try to get an event, but return immediately if there is none. Apparently timespec can have other members, so best to 0 it out in that case. --- thread_pthread_mn.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/thread_pthread_mn.c b/thread_pthread_mn.c index 5c21f212e4..72a5d8fce2 100644 --- a/thread_pthread_mn.c +++ b/thread_pthread_mn.c @@ -617,11 +617,17 @@ kqueue_wait(rb_vm_t *vm) struct timespec *timeout = NULL; int timeout_ms = timer_thread_set_timeout(vm); - if (timeout_ms >= 0) { + if (timeout_ms > 0) { calculated_timeout.tv_sec = timeout_ms / 1000; calculated_timeout.tv_nsec = (timeout_ms % 1000) * 1000000; timeout = &calculated_timeout; } + else if (timeout_ms == 0) { + // Relying on the absence of other members of struct timespec is not strictly portable, + // and kevent needs a 0-valued timespec to mean immediate timeout. + memset(&calculated_timeout, 0, sizeof(struct timespec)); + timeout = &calculated_timeout; + } return kevent(timer_th.event_fd, NULL, 0, timer_th.finished_events, KQUEUE_EVENTS_MAX, timeout); }