Signal delivery in OCaml 4.06 vs. OCaml 4.07

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
1 Like

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.

1 Like

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.