Skip to content

Commit 3f3aab4

Browse files
committed
Improve error handling creating sockets and pipes
If e.g. `socketpair` fails, we now return the exception to the calling fiber rather than aborting the event loop. Also, attach FDs to switches before setting non-blocking mode, in case that fails (requested by Anil Madhavapeddy).
1 parent 4b58f8b commit 3f3aab4

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

lib_eio_posix/domain_mgr.ml

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,38 @@ let run_event_loop fn x =
2626
effc = fun (type a) (e : a Effect.t) : ((a, Sched.exit) continuation -> Sched.exit) option ->
2727
match e with
2828
| Eio_unix.Private.Get_monotonic_clock -> Some (fun k -> continue k (Time.mono_clock : Eio.Time.Mono.t))
29-
| Eio_unix.Private.Socket_of_fd (sw, close_unix, fd) -> Some (fun k ->
30-
Unix.set_nonblock fd;
31-
let fd = Fd.of_unix ~sw ~blocking:false ~close_unix fd in
29+
| Eio_unix.Private.Socket_of_fd (sw, close_unix, unix_fd) -> Some (fun k ->
30+
let fd = Fd.of_unix ~sw ~blocking:false ~close_unix unix_fd in
31+
Unix.set_nonblock unix_fd;
3232
continue k (Flow.of_fd fd :> Eio_unix.socket)
3333
)
3434
| Eio_unix.Private.Socketpair (sw, domain, ty, protocol) -> Some (fun k ->
35-
let a, b = Unix.socketpair ~cloexec:true domain ty protocol in
36-
Unix.set_nonblock a;
37-
Unix.set_nonblock b;
38-
let a = Fd.of_unix ~sw ~blocking:false ~close_unix:true a |> Flow.of_fd in
39-
let b = Fd.of_unix ~sw ~blocking:false ~close_unix:true b |> Flow.of_fd in
40-
continue k ((a :> Eio_unix.socket), (b :> Eio_unix.socket))
35+
match
36+
let unix_a, unix_b = Unix.socketpair ~cloexec:true domain ty protocol in
37+
let a = Fd.of_unix ~sw ~blocking:false ~close_unix:true unix_a in
38+
let b = Fd.of_unix ~sw ~blocking:false ~close_unix:true unix_b in
39+
Unix.set_nonblock unix_a;
40+
Unix.set_nonblock unix_b;
41+
(Flow.of_fd a :> Eio_unix.socket), (Flow.of_fd b :> Eio_unix.socket)
42+
with
43+
| r -> continue k r
44+
| exception Unix.Unix_error (code, name, arg) ->
45+
discontinue k (Err.wrap code name arg)
4146
)
4247
| Eio_unix.Private.Pipe sw -> Some (fun k ->
43-
let r, w = Unix.pipe ~cloexec:true () in
44-
Unix.set_nonblock r;
45-
Unix.set_nonblock w;
46-
let make x = Flow.of_fd (Fd.of_unix ~sw ~blocking:false ~close_unix:true x) in
47-
let r = (make r :> <Eio.Flow.source; Eio.Flow.close; Eio_unix.unix_fd>) in
48-
let w = (make w :> <Eio.Flow.sink; Eio.Flow.close; Eio_unix.unix_fd>) in
49-
continue k (r, w)
48+
match
49+
let unix_r, unix_w = Unix.pipe ~cloexec:true () in
50+
let r = Fd.of_unix ~sw ~blocking:false ~close_unix:true unix_r in
51+
let w = Fd.of_unix ~sw ~blocking:false ~close_unix:true unix_w in
52+
Unix.set_nonblock unix_r;
53+
Unix.set_nonblock unix_w;
54+
let source = (Flow.of_fd r :> <Eio.Flow.source; Eio.Flow.close; Eio_unix.unix_fd>) in
55+
let sink = (Flow.of_fd w :> <Eio.Flow.sink; Eio.Flow.close; Eio_unix.unix_fd>) in
56+
(source, sink)
57+
with
58+
| r -> continue k r
59+
| exception Unix.Unix_error (code, name, arg) ->
60+
discontinue k (Err.wrap code name arg)
5061
)
5162
| _ -> None
5263
}

0 commit comments

Comments
 (0)