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.
This commit is contained in:
Luke Gruber 2026-01-23 11:54:44 -05:00 committed by GitHub
parent 48848e8da4
commit e7e9303236
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
Notes: git 2026-01-23 16:55:13 +00:00
Merged-By: luke-gru <luke.gru@gmail.com>

View File

@ -617,11 +617,17 @@ kqueue_wait(rb_vm_t *vm)
struct timespec *timeout = NULL; struct timespec *timeout = NULL;
int timeout_ms = timer_thread_set_timeout(vm); 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_sec = timeout_ms / 1000;
calculated_timeout.tv_nsec = (timeout_ms % 1000) * 1000000; calculated_timeout.tv_nsec = (timeout_ms % 1000) * 1000000;
timeout = &calculated_timeout; 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); return kevent(timer_th.event_fd, NULL, 0, timer_th.finished_events, KQUEUE_EVENTS_MAX, timeout);
} }