Hi, If you trigger the new optional NetBSD CI task, the oauthvalidator tests implode[1]. Apparently that OS's kevent() doesn't like zero relative timeouts for EVFILT_TIMER[2]. I see that you worked around the same problem for Linux timerfd already by rounding 0 up to 1, so we could just do the same here, and it passes with the attached. A cute alternative, not tested, might be to put NOTE_ABSTIME into fflag if timeout == 0 (then it's an absolute time in the past, which should fire immediately).
But I'm curious, how hard would it be to do this ↓ instead and not have that problem on any OS? * There might be an optimization opportunity here: if timeout == 0, we * could signal drive_request to immediately call * curl_multi_socket_action, rather than returning all the way up the * stack only to come right back. But it's not clear that the additional * code complexity is worth it. [1] https://cirrus-ci.com/task/6354435774873600 [2] https://github.com/NetBSD/src/blob/67c7c4658e77aa4534b6aac8c041d77097c5e722/sys/kern/kern_event.c#L1375
From 7deb153caf552c9bcb380f88eddbca94be33a0c2 Mon Sep 17 00:00:00 2001 From: Thomas Munro <thomas.mu...@gmail.com> Date: Sat, 1 Mar 2025 00:27:01 +1300 Subject: [PATCH] Fix OAUTH on NetBSD. NetBSD's EVFILT_TIMER doesn't like zero relative timeouts and fails with EINVAL. Steal the workaround from the same problem on Linux from a few lines up: round 0 up to 1. This could be seen on the optional NetBSD CI task, but not on the NetBSD build farm animals because they aren't finding curl and testing this code. --- src/interfaces/libpq/fe-auth-oauth-curl.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/interfaces/libpq/fe-auth-oauth-curl.c b/src/interfaces/libpq/fe-auth-oauth-curl.c index ae339579f88..6e60a81574d 100644 --- a/src/interfaces/libpq/fe-auth-oauth-curl.c +++ b/src/interfaces/libpq/fe-auth-oauth-curl.c @@ -1363,6 +1363,16 @@ set_timer(struct async_ctx *actx, long timeout) #ifdef HAVE_SYS_EVENT_H struct kevent ev; +#ifdef __NetBSD__ + + /* + * Work around NetBSD's rejection of zero timeouts (EINVAL), a bit like + * timerfd above. + */ + if (timeout == 0) + timeout = 1; +#endif + /* Enable/disable the timer itself. */ EV_SET(&ev, 1, EVFILT_TIMER, timeout < 0 ? EV_DELETE : (EV_ADD | EV_ONESHOT), 0, timeout, 0); -- 2.48.1