Hej
While playing around with domainslib I have encountered an interesting case when using channels. I have created the following minimal example to demonstrate it:
module T = Domainslib.Task
module C = Domainslib.Chan
let num_domains = Sys.argv.(1) |> int_of_string
let () =
let pool = T.setup_pool ~num_domains:(num_domains - 1) () in
let ping = C.make_bounded 1 in
let pong = C.make_bounded 1 in
T.run pool (fun _ ->
let _ = T.async pool (fun _ ->
C.recv ping;
print_endline "Hello, World";
C.send pong ()
) in
C.send ping ();
C.recv pong
);
T.teardown_pool pool
If I call the program above with argument 1
(i.e. no additional domains), I get no output, while if I call it with anything bigger than 1
(i.e. there is gonna be more than 1 domain), I get the expected "Hello, World"
printed out.
The following is from Chan.mli:
val recv : 'a t -> 'a
(** [recv c] returns a value [v] received over the channel. If the channel
buffer is empty then the domain blocks until a message is sent on the
channel. *)
Somehow I would have expected that to mean, that if one thread is blocking on an empty channel, other threads in the pool might run, but that does not seem to be the behaviour. Have I misunderstood how channels work? And if so, is there something similar that gives me the expected behaviour? I assume I could use the promise mechanism offered by Eio, but if possible I’d like to stick to domainslib.
Thanks in advance for any hints