A signal can be handled in 2 ways after its handler has finished:
- return EINTR from the system call that got interrupted. This is the default behaviour
- automatically restart the system call, if the handler was registered using SA_RESTART.
I don’t see how the latter would be achievable in OCaml: sigaction
is always called with a hardcoded 0
flag (unless I make my own C binding to sigaction
).
(And all signal handlers must be registered this way)
And the former seems brittle: you need to wrap all calls to the Unix module with EINTR handlers (C applications have the same problem, they are probably not very robust against signals…),
and all libraries that could call the Unix module would need such wrappers.
But I don’t see how I could guarantee at compile time that this has happened.
I think it’d make sense to have SA_RESTART support in the runtime, but meanwhile is there an OCaml library that provides this already perhaps? I can’t be the first one who ran into this problem.
Background:
I tried using posix virtual timers (Unix.set_itimer) to decrease the 50ms OCaml’s timeslice, which sends a signal periodically where I can run Thread.yield. That part works, and decreases latency visibly.
However it then revealed that the application is not signal-safe at all (even though it has signal handlers for logrotate, etc.): it just raises an error in the middle of whatever system call it happens to be, and doesn’t actually handle EINTR in most places (there are very few places where it does).