Skip to content

Commit 146d246

Browse files
authored
Merge pull request #448 from talex5/eio-posix
Initial Eio_posix backend
2 parents 0a4b3f9 + 8118c1f commit 146d246

32 files changed

+1767
-13
lines changed

.github/workflows/main.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
ocaml-compiler:
1515
- 5.0.x
1616
local-packages:
17-
- eio eio_luv eio_main
17+
- eio eio_posix eio_main
1818

1919
runs-on: ${{ matrix.os }}
2020

@@ -26,8 +26,9 @@ jobs:
2626
uses: ocaml/setup-ocaml@v2
2727
with:
2828
ocaml-compiler: ${{ matrix.ocaml-compiler }}
29-
opam-local-packages: ${{ matrix.local-packages }}
29+
opam-local-packages:
3030
opam-disable-sandboxing: true
3131

32+
- run: opam --cli=2.1 pin -yn --with-version=dev .
3233
- run: opam install ${{ matrix.local-packages }} --deps-only --with-test
3334
- run: opam install ${{ matrix.local-packages }} --with-test

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ bench:
1717
test_luv:
1818
EIO_BACKEND=luv dune runtest
1919

20+
test_posix:
21+
EIO_BACKEND=posix dune runtest
22+
2023
dscheck:
2124
dune exec -- ./lib_eio/tests/dscheck/test_rcfd.exe
2225
dune exec -- ./lib_eio/tests/dscheck/test_sync.exe

dune-project

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
(package
3333
(name eio_linux)
3434
(synopsis "Eio implementation for Linux using io-uring")
35-
(description "An eio implementation for Linux using io-uring.")
35+
(description "An Eio implementation for Linux using io-uring.")
3636
(depends
3737
(alcotest (and (>= 1.4.0) :with-test))
3838
(eio (= :version))
@@ -41,10 +41,19 @@
4141
(fmt (>= 0.8.9))
4242
(cmdliner (and (>= 1.1.0) :with-test))
4343
(uring (>= 0.5))))
44+
(package
45+
(name eio_posix)
46+
(synopsis "Eio implementation for POSIX systems")
47+
(description "An Eio implementation for most Unix-like platforms")
48+
(depends
49+
(eio (= :version))
50+
(iomux (>= 0.2))
51+
(mdx (and (>= 1.10.0) :with-test))
52+
(fmt (>= 0.8.9))))
4453
(package
4554
(name eio_luv)
4655
(synopsis "Eio implementation using luv (libuv)")
47-
(description "An eio implementation for most platforms, using luv.")
56+
(description "An Eio implementation for most platforms, using luv.")
4857
(depends
4958
(eio (= :version))
5059
(luv (>= 0.5.11))
@@ -55,8 +64,10 @@
5564
(name eio_main)
5665
(synopsis "Effect-based direct-style IO mainloop for OCaml")
5766
(description "Selects an appropriate Eio backend for the current platform.")
67+
(depopts eio_luv)
5868
(depends
59-
(eio_linux (and (= :version) (= :os "linux")))
6069
(mdx (and (>= 1.10.0) :with-test))
61-
(eio_luv (= :version))))
70+
(eio_linux (and (= :version) (= :os "linux")))
71+
(eio_posix (and (= :version) (<> :os "windows")))
72+
(eio_luv (and (= :version) (or (= :os "windows") :with-test)))))
6273
(using mdx 0.2)

eio_linux.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file is generated by dune, edit dune-project instead
22
opam-version: "2.0"
33
synopsis: "Eio implementation for Linux using io-uring"
4-
description: "An eio implementation for Linux using io-uring."
4+
description: "An Eio implementation for Linux using io-uring."
55
maintainer: ["anil@recoil.org"]
66
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
77
license: "ISC"

eio_luv.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# This file is generated by dune, edit dune-project instead
22
opam-version: "2.0"
33
synopsis: "Eio implementation using luv (libuv)"
4-
description: "An eio implementation for most platforms, using luv."
4+
description: "An Eio implementation for most platforms, using luv."
55
maintainer: ["anil@recoil.org"]
66
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
77
license: "ISC"

eio_main.opam

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ doc: "https://ocaml-multicore.github.io/eio/"
1010
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
1111
depends: [
1212
"dune" {>= "3.0"}
13-
"eio_linux" {= version & os = "linux"}
1413
"mdx" {>= "1.10.0" & with-test}
15-
"eio_luv" {= version}
14+
"eio_linux" {= version & os = "linux"}
15+
"eio_posix" {= version & os != "windows"}
16+
"eio_luv" {= version & os = "windows" | with-test}
1617
"odoc" {with-doc}
1718
]
19+
depopts: ["eio_luv"]
1820
build: [
1921
["dune" "subst"] {dev}
2022
[

eio_posix.opam

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# This file is generated by dune, edit dune-project instead
2+
opam-version: "2.0"
3+
synopsis: "Eio implementation for POSIX systems"
4+
description: "An Eio implementation for most Unix-like platforms"
5+
maintainer: ["anil@recoil.org"]
6+
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
7+
license: "ISC"
8+
homepage: "https://github.com/ocaml-multicore/eio"
9+
doc: "https://ocaml-multicore.github.io/eio/"
10+
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
11+
depends: [
12+
"dune" {>= "3.0"}
13+
"eio" {= version}
14+
"iomux" {>= "0.2"}
15+
"mdx" {>= "1.10.0" & with-test}
16+
"fmt" {>= "0.8.9"}
17+
"odoc" {with-doc}
18+
]
19+
build: [
20+
["dune" "subst"] {dev}
21+
[
22+
"dune"
23+
"build"
24+
"-p"
25+
name
26+
"-j"
27+
jobs
28+
"@install"
29+
"@runtest" {with-test}
30+
"@doc" {with-doc}
31+
]
32+
]
33+
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"

lib_eio_posix/domain_mgr.ml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
(*
2+
* Copyright (C) 2023 Thomas Leonard
3+
*
4+
* Permission to use, copy, modify, and distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*)
16+
17+
open Eio.Std
18+
19+
[@@@alert "-unstable"]
20+
21+
(* Run an event loop in the current domain, using [fn x] as the root fiber. *)
22+
let run_event_loop fn x =
23+
Sched.with_sched @@ fun sched ->
24+
let open Effect.Deep in
25+
let extra_effects : _ effect_handler = {
26+
effc = fun (type a) (e : a Effect.t) : ((a, Sched.exit) continuation -> Sched.exit) option ->
27+
match e with
28+
| 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, 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;
32+
continue k (Flow.of_fd fd :> Eio_unix.socket)
33+
)
34+
| Eio_unix.Private.Socketpair (sw, domain, ty, protocol) -> Some (fun k ->
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)
46+
)
47+
| Eio_unix.Private.Pipe sw -> Some (fun k ->
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)
61+
)
62+
| _ -> None
63+
}
64+
in
65+
Sched.run ~extra_effects sched fn x
66+
67+
let v = object
68+
inherit Eio.Domain_manager.t
69+
70+
method run_raw fn =
71+
let domain = ref None in
72+
Eio.Private.Suspend.enter (fun _ctx enqueue ->
73+
domain := Some (Domain.spawn (fun () -> Fun.protect fn ~finally:(fun () -> enqueue (Ok ()))))
74+
);
75+
Domain.join (Option.get !domain)
76+
77+
method run fn =
78+
let domain = ref None in
79+
Eio.Private.Suspend.enter (fun ctx enqueue ->
80+
let cancelled, set_cancelled = Promise.create () in
81+
Eio.Private.Fiber_context.set_cancel_fn ctx (Promise.resolve set_cancelled);
82+
domain := Some (Domain.spawn (fun () ->
83+
Fun.protect (run_event_loop (fun () -> fn ~cancelled))
84+
~finally:(fun () -> enqueue (Ok ()))))
85+
);
86+
Domain.join (Option.get !domain)
87+
end

lib_eio_posix/dune

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
(library
2+
(name eio_posix)
3+
(public_name eio_posix)
4+
(enabled_if (= %{os_type} "Unix"))
5+
(foreign_stubs
6+
(language c)
7+
(flags :standard -D_LARGEFILE64_SOURCE)
8+
(names eio_posix_stubs))
9+
(libraries eio eio.utils eio.unix fmt iomux))
10+
11+
(rule
12+
(targets config.ml)
13+
(action (run ./include/discover.exe)))

lib_eio_posix/eio_posix.ml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
(*
2+
* Copyright (C) 2023 Thomas Leonard
3+
*
4+
* Permission to use, copy, modify, and distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*)
16+
17+
module Low_level = Low_level
18+
19+
type stdenv = <
20+
stdin : <Eio.Flow.source; Eio_unix.unix_fd>;
21+
stdout : <Eio.Flow.sink; Eio_unix.unix_fd>;
22+
stderr : <Eio.Flow.sink; Eio_unix.unix_fd>;
23+
net : Eio.Net.t;
24+
domain_mgr : Eio.Domain_manager.t;
25+
clock : Eio.Time.clock;
26+
mono_clock : Eio.Time.Mono.t;
27+
fs : Eio.Fs.dir Eio.Path.t;
28+
cwd : Eio.Fs.dir Eio.Path.t;
29+
secure_random : Eio.Flow.source;
30+
debug : Eio.Debug.t;
31+
>
32+
33+
let run main =
34+
(* SIGPIPE makes no sense in a modern application. *)
35+
Sys.(set_signal sigpipe Signal_ignore);
36+
let stdin = (Flow.of_fd Low_level.Fd.stdin :> <Eio.Flow.source; Eio_unix.unix_fd>) in
37+
let stdout = (Flow.of_fd Low_level.Fd.stdout :> <Eio.Flow.sink; Eio_unix.unix_fd>) in
38+
let stderr = (Flow.of_fd Low_level.Fd.stderr :> <Eio.Flow.sink; Eio_unix.unix_fd>) in
39+
Domain_mgr.run_event_loop main @@ object (_ : stdenv)
40+
method stdin = stdin
41+
method stdout = stdout
42+
method stderr = stderr
43+
method debug = Eio.Private.Debug.v
44+
method clock = Time.clock
45+
method mono_clock = Time.mono_clock
46+
method net = Net.v
47+
method domain_mgr = Domain_mgr.v
48+
method cwd = ((Fs.cwd, "") :> Eio.Fs.dir Eio.Path.t)
49+
method fs = ((Fs.fs, "") :> Eio.Fs.dir Eio.Path.t)
50+
method secure_random = Flow.secure_random
51+
end

0 commit comments

Comments
 (0)