From 2ca397bfcca94c106380368b5b0ce920b0a62a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Sat, 6 Jan 2024 16:22:45 +0100 Subject: [PATCH] libevent: Fix computation of the timeout value. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Until now, sleeping for 10s or more wouldn’t work on platforms where internal-time-units-per-second = 1e9, such as x86_64-linux-gnu. On platforms where internal-time-units-per-second = 1e3, such as i586-pc-gnu, ‘tv’ would always be zero, leading to code that keeps spinning. * extensions/libevent.c (microsec_per_time_units): New variable. (run_event_loop): Fix computation of ‘tv_sec’ and ‘tv_usec’. (init_fibers_libevt): Initialize ‘microsec_per_time_units’. --- extensions/libevent.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/extensions/libevent.c b/extensions/libevent.c index 134460a..62e50a3 100644 --- a/extensions/libevent.c +++ b/extensions/libevent.c @@ -192,30 +192,27 @@ scm_primitive_resize (SCM lst, SCM eventsv) } #undef FUNC_NAME -static uint64_t time_units_per_microsec; +static uint64_t time_units_per_microsec, microsec_per_time_units; static void* run_event_loop (void *p) #define FUNC_NAME "primitive-event-loop" { - int ret = 0; - int microsec = 0; - struct timeval tv; - + int ret; struct loop_data *data = p; - if (data->timeout < 0) - microsec = -1; - else if (data->timeout >= 0) + if (data->timeout >= 0) { - microsec = (time_units_per_microsec == 0) - ? 0 : data->timeout / time_units_per_microsec; - tv.tv_sec = 0; - tv.tv_usec = microsec; - } + struct timeval tv; + + tv.tv_sec = data->timeout / scm_c_time_units_per_second; + tv.tv_usec = + time_units_per_microsec > 0 + ? ((data->timeout % scm_c_time_units_per_second) + / time_units_per_microsec) + : ((data->timeout % scm_c_time_units_per_second) + * microsec_per_time_units); - if (microsec >= 0) - { ret = event_base_loopexit (data->base, &tv); if (ret == -1) SCM_MISC_ERROR ("event loop exit failed", SCM_EOL); @@ -307,6 +304,7 @@ void init_fibers_libevt (void) { time_units_per_microsec = scm_c_time_units_per_second / 1000000; + microsec_per_time_units = 1000000 / scm_c_time_units_per_second; scm_c_define_gsubr ("primitive-event-wake", 1, 0, 0, scm_primitive_event_wake);