Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signals don't get processed while Fibers are scheduled? #301

Closed
anmonteiro opened this issue Sep 1, 2022 · 6 comments
Closed

Signals don't get processed while Fibers are scheduled? #301

anmonteiro opened this issue Sep 1, 2022 · 6 comments

Comments

@anmonteiro
Copy link
Contributor

anmonteiro commented Sep 1, 2022

I couldn't get eio to handle my signals while another fiber is running (even if sleeping). Take this pathological case:

open Eio.Std

let () =
  Sys.(
    set_signal
      sigint
      (Signal_handle
         (fun i ->
           Format.eprintf "handle signal: %d@." i;
           exit 0)));
  Eio_main.run (fun _env ->
      Switch.run (fun sw ->
          Fiber.fork ~sw (fun () -> Eio.Time.sleep (Eio.Stdenv.clock _env) 5.)))

You can send ctrl+C to the program while it's running and it won't process it until after 5 seconds (when the eio fiber ends).

Tested on macOS (with eio_luv)

@anmonteiro
Copy link
Contributor Author

This seems to work well with eio_linux.

@anmonteiro
Copy link
Contributor Author

anmonteiro commented Sep 1, 2022

I'm not sure whether this can work with eio_luv at all (it looks like it takes over signal handling while its event loop is running). A workaround I've found is to install my own signal handling with Luv and run a separate loop:

open Eio.Std

let () =
  let loop = Luv.Loop.init () |> Result.get_ok in
  let () =
    match Luv.Signal.init ~loop () with
    | Ok handle ->
      let handler () =
        Format.eprintf "handle signal@.";
        Luv.Handle.close handle ignore
      in
      Result.get_ok (Luv.Signal.start handle Luv.Signal.sigint handler)
    | Error _ -> ()
  in

    Eio_main.run (fun env ->
      Switch.run (fun sw ->
          let _d =
            (* Not sure why `Eio.Domain_manager.run` doesn't work *)
            Domain.spawn (fun () ->
                let (_ : bool) = Luv.Loop.run ~loop () in
                ())
          in
          Fiber.fork ~sw (fun () -> Eio.Time.sleep (Eio.Stdenv.clock env) 5.)))

This works for now but it imposes a dependency on luv on linux.

@talex5
Copy link
Collaborator

talex5 commented Sep 4, 2022

We probably need an abstraction for signals (an env#signals perhaps, or something in Eio_unix).

@haesbaert
Copy link
Contributor

haesbaert commented Sep 19, 2022

I'm having a quick jab at this, one of the possible issues is that luv exports a considerably smaller set of signals, blame is on windows support:

(** {1:signals Signal numbers}

    For the moment, the signals exposed are those that are both present on Unix
    and present or emulated by libuv on Windows. See
    {{:http://docs.libuv.org/en/v1.x/signal.html#windows-notes} {i Windows
    notes}} and {{:http://docs.libuv.org/en/v1.x/signal.html#unix-notes} {i Unix
    notes}}.

    Note that these signal numbers do not, in general, match the ones in module
    [Sys] in the OCaml standard library. *)

val sigabrt : int
val sigfpe : int
val sighup : int
val sigill : int
val sigint : int
val sigkill : int
val sigsegv : int
val sigterm : int
val sigwinch : int

@haesbaert
Copy link
Contributor

So I have this, needs cleanup and a bit more work:

  Eio_main.run @@ fun env ->
  let signal = Eio.Stdenv.signal env in
  let clock = Eio.Stdenv.clock env in
  signal#set Sys.sigint (fun signum -> traceln "got signal %d" signum);
  Eio.Time.sleep clock 10.0;
  signal#unset Sys.sigint;
  Eio.Time.sleep clock 10.0;
  traceln ":*"  
sam:eio: dune build && EIO_BACKEND=luv ./_build/default/bench/sigtest.exe
+luv signal -6 set
^C+got signal -6
^C+got signal -6
^C+got signal -6
^C+got signal -6
^C+got signal -6
+luv signal -6 unset
^C

@talex5
Copy link
Collaborator

talex5 commented Feb 6, 2023

Closed by #436.

@talex5 talex5 closed this as completed Feb 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants