Skip to content

Eio.Flow.read hangs on closed flow #214

@quartz55

Description

@quartz55

Not sure if I'm doing something wrong, but I've run into the following issue (on the Luv backend).

A fiber waiting on a Eio.Flow.read before another fiber closes it will hang forever, at least for a client type Eio.Net.connect flow.

I've managed to trim it down to the following case:

reproduce.ml
open Eio.Std

let main env =
  let run_client ~net ~addr =
    traceln "client on";
    Switch.run (fun sw ->
        let flow = Eio.Net.connect ~sw net addr in
        traceln "client <-> server";
        let read_loop () =
          let b = Cstruct.create 4 in
          traceln "client will be stuck after this";
          while true do
            Eio.Flow.read flow b |> ignore;
            traceln "unreachable"
          done
        in
        let d = "Hello from client" in
        traceln "client -> %S" d;
        Eio.Flow.copy_string d flow;
        Fiber.fork ~sw read_loop;
        Eio.Flow.close flow);
    traceln "client off"
  in
  let run_server socket =
    traceln "server on";
    Switch.run (fun sw ->
        Eio.Net.accept_sub socket ~sw
          (fun ~sw:_ flow _addr ->
            traceln "server <-> client";
            let b = Buffer.create 100 in
            Eio.Flow.copy flow (Eio.Flow.buffer_sink b);
            traceln "server <[EOF]- %S" (Buffer.contents b))
          ~on_error:(traceln "Error handling connection: %a" Fmt.exn));
    traceln "server off"
  in

  let net = Eio.Stdenv.net env in
  let addr = `Tcp (Eio.Net.Ipaddr.V4.loopback, 9999) in
  Switch.run @@ fun sw ->
  let server = Eio.Net.listen net ~sw ~reuse_addr:true ~backlog:5 addr in
  Fiber.both (fun () -> run_server server) (fun () -> run_client ~net ~addr)

Where the expected output would be:

+server on
+client on
+client <-> server
+client -> "Hello from client"
+server <-> client
+client will be stuck after this
+server <[EOF]- "Hello from client"
+server off
*hangs forever*

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions