ocaml-multicore / eio

Effects-based direct-style IO for multicore OCaml
Other
555 stars 68 forks source link

Crash on writing to /dev/null on macOS #757

Open aaronjeline opened 22 hours ago

aaronjeline commented 22 hours ago

Attempting to use Eio.Flow.copy_string when stdout points to /dev/null crashes. main.ml:

open Eio

let main env =
    let stdout = Stdenv.stdout env in
    Eio.Flow.copy_string "Hello world!" stdout;
    ()

let () = Eio_main.run main

dune:

(executable
 (public_name demo)
 (name main)
 (libraries eio_main demo))

Interacting with it:


% dune exec demo
Hello world!
% dune exec demo > out
% cat out -p
Hello world!
% dune exec demo > /dev/null
Fatal error: exception File "lib_eio_posix/sched.ml", line 155, characters 2-8: Assertion failed

Eio version: 1.1
aaronjeline commented 19 hours ago

Looks like this is an issue with MacOS poll(), doesn't seem like it supports block devices. (https://nathancraddock.com/blog/macos-dev-tty-polling/). I'm happy to work on supporting this, I see two ways of going about it, not sure which you think is best?

1) Special case the handling of block devices, and use select for them. 2) Spawn a new thread for monitoring blocks devices, use select in that thread, and pipe data from that to the main thread, monitor that second thread as normal with poll

If you have better ideas I'm also happy to hear that.

talex5 commented 9 hours ago

Oh wow, that's annoying. I guess we need to do what libuv does then and use select when polling fails (https://github.com/libuv/libuv/blob/731adacad2426d349d4c51ca608184f7e01c93c6/src/unix/stream.c#L287).

https://lists.apple.com/archives/Darwin-dev/2006/Apr/msg00066.html

There's an issue with binary compatibility inside the kernel that prevented it being fixed in Tiger, but hopefully it can be sorted in Leopard because it's an ongoing headache.

aaronjeline commented 3 hours ago

sorted in Leopard

lol. Like I said, happy to hack on this if you'd like me to

aaronjeline commented 1 hour ago

Blog post on the trick uv does, I'll start down this road: https://code.saghul.net/2016/05/libuv-internals-the-osx-select2-trick/