diff --git a/lib_eio/net.ml b/lib_eio/net.ml index c9e77ffa3..c35214b83 100644 --- a/lib_eio/net.ml +++ b/lib_eio/net.ml @@ -182,6 +182,9 @@ let accept_fork ~sw (t : #listening_socket) ~on_error handle = Fiber.fork ~sw (fun () -> match child_started := true; handle (flow :> stream_socket) addr with | x -> Flow.close flow; x + | exception (Cancel.Cancelled _ as ex) -> + Flow.close flow; + raise ex | exception ex -> Flow.close flow; on_error (Exn.add_context ex "handling connection from %a" Sockaddr.pp addr) diff --git a/lib_eio/net.mli b/lib_eio/net.mli index d9397f55a..a4b8b6f4d 100644 --- a/lib_eio/net.mli +++ b/lib_eio/net.mli @@ -208,8 +208,12 @@ val accept_fork : @param on_error Called if [connection_handler] raises an exception. This is typically a good place to log the error and continue. If the exception is an {!Eio.Io} error then the caller's address is added to it. + If you don't want to handle connection errors, - use [~on_error:raise] to cancel the caller's context. *) + use [~on_error:raise] to cancel the caller's context. + + [on_error] is not called for {!Cancel.Cancelled} exceptions, + which do not need to be reported. *) (** {2 Running Servers} *) diff --git a/tests/network.md b/tests/network.md index d7aee7f7c..7c6a2a19a 100644 --- a/tests/network.md +++ b/tests/network.md @@ -403,6 +403,23 @@ If the fork itself fails, we still close the connection: Exception: Failure "Simulated error". ``` +`accept_fork` doesn't send cancellations to `on_error`: + +```ocaml +# Eio_mock.Backend.run @@ fun () -> + let socket = Eio_mock.Net.listening_socket "tcp/80" in + let flow = Eio_mock.Flow.make "connection" in + let addr = `Tcp (Eio.Net.Ipaddr.V4.loopback, 1234) in + Eio_mock.Net.on_accept socket [`Return (flow, addr)]; + Switch.run @@ fun sw -> + Eio.Net.accept_fork ~sw ~on_error:(traceln "BUG: %a" Fmt.exn) socket + (fun _flow _addr -> Fiber.await_cancel ()); + Switch.fail sw (Failure "Simulated error");; ++tcp/80: accepted connection from tcp:127.0.0.1:1234 ++connection: closed +Exception: Failure "Simulated error". +``` + ## Socketpair ```ocaml