From 491b27ebc36a48e39005748c30a0dcda61e3f904 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 02:38:12 +0300 Subject: [PATCH] veb: fix long process started from app hogging CPU (fixes #26742) --- vlib/picoev/picoev.v | 7 +++++++ vlib/picoev/picoev_interrupt_test_linux.c.v | 22 +++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 vlib/picoev/picoev_interrupt_test_linux.c.v diff --git a/vlib/picoev/picoev.v b/vlib/picoev/picoev.v index 6ace906d8..eb15913a4 100644 --- a/vlib/picoev/picoev.v +++ b/vlib/picoev/picoev.v @@ -131,6 +131,13 @@ pub fn (mut pv Picoev) delete(fd int) int { fn (mut pv Picoev) loop_once(max_wait_in_sec int) int { pv.loop.now = get_time() if pv.poll_once(max_wait_in_sec) != 0 { + $if !windows { + if C.errno == net.error_eintr { + // Signal-driven wakeups are transient. The caller should keep serving, + // instead of spinning on a logged "error" until the signal source stops. + return 0 + } + } elog('Error during poll_once') return -1 } diff --git a/vlib/picoev/picoev_interrupt_test_linux.c.v b/vlib/picoev/picoev_interrupt_test_linux.c.v new file mode 100644 index 000000000..d5388e754 --- /dev/null +++ b/vlib/picoev/picoev_interrupt_test_linux.c.v @@ -0,0 +1,22 @@ +module picoev + +import os + +#include + +fn C.alarm(seconds u32) u32 + +fn ignore_test_signal(_ os.Signal) {} + +fn test_loop_once_ignores_eintr() { + mut pv := &Picoev{} + pv.loop = create_epoll_loop(0) or { panic(err) } + pv.init() + prev_handler := os.signal_opt(.alrm, ignore_test_signal) or { panic(err) } + defer { + C.alarm(0) + os.signal_opt(.alrm, prev_handler) or { panic(err) } + } + C.alarm(1) + assert pv.loop_once(2) == 0 +} -- 2.39.5