mirror of
https://github.com/HeyPuter/gex.git
synced 2026-11-13 20:12:43 -10:00
A blocked waitpid answered EINTR under a handler installed with SA_RESTART (stream C): every parked call a signal ended said EINTR. Linux restarts it (signal(7), "Interruption of system calls"): - read, write, wait4, accept and an untimed futex wait after a handler with SA_RESTART (-ERESTARTSYS), and when no handler runs; - FUTEX_LOCK_PI always (-ERESTARTNOINTR); - never poll, select, epoll_wait, nanosleep, a timed futex wait, sigsuspend or connect. BlockOp::restart names the class, and Signals::restarts asks the signal about to be delivered. A call that restarts gets no result: its registers are as the guest made the call, its context's PC goes back to the call's instruction, and the handler's frame returns there (restart_call). Both hosts do this: the kernel's finish_blocking (gexc; per thread through PendingCall) and the page's finish_wait. A wasm32 program's PC belongs to its syscall stub, so its context is marked instead. The i386 frame keeps the mark in sigcontext.err, and the program's sigreturn makes the call again before it returns to the stub. With no handler to run, a wasm32 call still says EINTR. Also fixed: i386 setitimer scaled the microseconds of its timevals to nanoseconds, so a 100 ms timer fired after 100 s. Every i386 and wasm32 program's interval timer was 1000 times slow. Leg: tests/x86-programs/sa-restart.c (x86-64 and i386, native, gexc and the page) and tests/gexcc/sarestart.c (wasm32, gexc and the page). Each checks wait4, read and futex with SA_RESTART, wait4 without it, and poll and nanosleep. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_ea9f71488b6e448da93d6c2dabf4879c