In the code below on OCaml 4.07 the Thread.delay blocks the delivery of a signal whereas in OCaml 4.06 the signal handler would be invoked. Is this as expected or should this be filed as a bug?
I understand the signals are not delivered at every point but the previous behaviour was quite useful to get out of sleeping threads when a program receives a SIGTERM.
(* ocamlc -thread -o foo unix.cma threads.cma foo.ml
*)
let on_sigterm _ =
prerr_endline "Received signal";
flush stderr;
exit 0
let () =
Sys.set_signal Sys.sigterm Sys.(Signal_handle on_sigterm);
Sys.catch_break true;
while true; do
Thread.delay 300.
done
It may be related to this change which makes Thread.delay an alias for Unix.sleepf in 4.07.0:
- GPR#1533: (a) The implementation of Thread.yield for system thread
now uses nanosleep(1) for enabling better preemption.
(b) Thread.delay is now an alias for Unix.sleepf.
(Jacques-Henri Jourdan, review by Xavier Leroy and David Allsopp)
It looks like the signal handling behavior of Unix.sleep changed in 4.03.0 with this change:
* Protect Unix.sleep against interruptions by handled signals.
Before, a handled signal could cause Unix.sleep to return early.
Now, the sleep is restarted until the given time is elapsed.
(Xavier Leroy)
I suspect that Unix.sleepf's behavior, when it was added in 4.03.0, was designed to match Unix.sleep.
I have filed this as a bug because I believe this needs to be discussed. A process where all threads are sleeping can’t be terminated with SIGTERM because it won’t be delivered.