Skip to content

Commit

Permalink
Move Eio.Stdenv.t to Eio_unix.Stdenv.base
Browse files Browse the repository at this point in the history
The old type wasn't directly useful for anything, since nothing provides
exactly this set of resources, and nothing needs to consume exactly this
set either. However, it is useful in Eio_unix as the set of resources
that a backend needs to provide to be compatible with `Eio_main.run`.

The new type is almost the same for now, except that the standard
streams include file descriptors. Other Unix-specific features can be
added later, such as support for passing file descriptors over sockets
or to child processes.
  • Loading branch information
talex5 committed May 2, 2023
1 parent 92f416f commit c576977
Show file tree
Hide file tree
Showing 15 changed files with 59 additions and 97 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Eio replaces existing concurrency libraries such as Lwt
* [Best Practices](#best-practices)
* [Switches](#switches-1)
* [Casting](#casting)
* [Passing Stdenv.t](#passing-stdenvt)
* [Passing env](#passing-env)
* [Further Reading](#further-reading)

<!-- vim-markdown-toc -->
Expand Down Expand Up @@ -1675,7 +1675,7 @@ end

Note: the `#type` syntax only works on types defined by classes, whereas the slightly more verbose `<type; ..>` works on all object types.

### Passing Stdenv.t
### Passing env

The `env` value you get from `Eio_main.run` is a powerful capability,
and programs are easier to understand when it's not passed around too much.
Expand Down
14 changes: 0 additions & 14 deletions lib_eio/eio.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ module Fs = Fs
module Path = Path

module Stdenv = struct
type t = <
stdin : Flow.source;
stdout : Flow.sink;
stderr : Flow.sink;
net : Net.t;
domain_mgr : Domain_manager.t;
clock : Time.clock;
mono_clock : Time.Mono.t;
fs : Fs.dir Path.t;
cwd : Fs.dir Path.t;
secure_random : Flow.source;
debug : Debug.t;
>

let stdin (t : <stdin : #Flow.source; ..>) = t#stdin
let stdout (t : <stdout : #Flow.sink; ..>) = t#stdout
let stderr (t : <stderr : #Flow.sink; ..>) = t#stderr
Expand Down
18 changes: 2 additions & 16 deletions lib_eio/eio.mli
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ end
methods directly. Using the functions results in better error messages from the compiler,
and may provide extra features or sanity checks.
The system resources are available from the {!Stdenv.t} provided by your event loop
The system resources are available from environment argument provided by your event loop
(e.g. {!Eio_main.run}). *)

(** A base class for objects that can be queried at runtime for extra features. *)
Expand Down Expand Up @@ -163,7 +163,7 @@ end
(** The standard environment of a process. *)
module Stdenv : sig
(** All access to the outside world comes from running the event loop,
which provides a {!t}.
which provides an environment (e.g. an {!Eio_unix.Stdenv.base}).
Example:
{[
Expand All @@ -175,20 +175,6 @@ module Stdenv : sig
]}
*)

type t = <
stdin : Flow.source;
stdout : Flow.sink;
stderr : Flow.sink;
net : Net.t;
domain_mgr : Domain_manager.t;
clock : Time.clock;
mono_clock : Time.Mono.t;
fs : Fs.dir Path.t;
cwd : Fs.dir Path.t;
secure_random : Flow.source;
debug : Debug.t;
>

(** {1 Standard streams}
To use these, see {!Flow}. *)
Expand Down
24 changes: 21 additions & 3 deletions lib_eio/unix/eio_unix.ml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[@@@alert "-unstable"]

open Eio.Std

module Fd = Fd

module Resource = struct
Expand Down Expand Up @@ -27,9 +29,9 @@ module Private = struct
| Await_readable : Unix.file_descr -> unit Effect.t
| Await_writable : Unix.file_descr -> unit Effect.t
| Get_monotonic_clock : Eio.Time.Mono.t Effect.t
| Socket_of_fd : Eio.Switch.t * bool * Unix.file_descr -> socket Effect.t
| Socketpair : Eio.Switch.t * Unix.socket_domain * Unix.socket_type * int -> (socket * socket) Effect.t
| Pipe : Eio.Switch.t -> (source * sink) Effect.t
| Socket_of_fd : Switch.t * bool * Unix.file_descr -> socket Effect.t
| Socketpair : Switch.t * Unix.socket_domain * Unix.socket_type * int -> (socket * socket) Effect.t
| Pipe : Switch.t -> (source * sink) Effect.t

module Rcfd = Rcfd

Expand Down Expand Up @@ -95,3 +97,19 @@ let getnameinfo (sockaddr : Eio.Net.Sockaddr.t) =
run_in_systhread (fun () ->
let Unix.{ni_hostname; ni_service} = Unix.getnameinfo sockaddr options in
(ni_hostname, ni_service))

module Stdenv = struct
type base = <
stdin : source;
stdout : sink;
stderr : sink;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
end
20 changes: 20 additions & 0 deletions lib_eio/unix/eio_unix.mli
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,26 @@ val pipe : Switch.t -> source * sink
can be read from [src].
Note that, like all FDs created by Eio, they are both marked as close-on-exec by default. *)

(** The set of resources provided to a process on a Unix-compatible system. *)
module Stdenv : sig
type base = <
stdin : source;
stdout : sink;
stderr : sink;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
(** The common set of features provided by all traditional operating systems (BSDs, Linux, Mac, Windows).
You can use the functions in {!Eio.Stdenv} to access these fields if you prefer. *)
end

(** API for Eio backends only. *)
module Private : sig
type _ Effect.t +=
Expand Down
14 changes: 1 addition & 13 deletions lib_eio_linux/eio_linux.ml
Original file line number Diff line number Diff line change
Expand Up @@ -281,19 +281,7 @@ let net = object
method getnameinfo = Eio_unix.getnameinfo
end

type stdenv = <
stdin : source;
stdout : sink;
stderr : sink;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
type stdenv = Eio_unix.Stdenv.base

let domain_mgr ~run_event_loop = object
inherit Eio.Domain_manager.t
Expand Down
14 changes: 1 addition & 13 deletions lib_eio_linux/eio_linux.mli
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,7 @@ end
type source = Eio_unix.source
type sink = Eio_unix.sink

type stdenv = <
stdin : source;
stdout : sink;
stderr : sink;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
type stdenv = Eio_unix.Stdenv.base

(**/**)
val get_fd : <Eio_unix.Resource.t; ..> -> fd
Expand Down
20 changes: 4 additions & 16 deletions lib_eio_posix/eio_posix.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,15 @@

module Low_level = Low_level

type stdenv = <
stdin : <Eio.Flow.source; Eio_unix.Resource.t>;
stdout : <Eio.Flow.sink; Eio_unix.Resource.t>;
stderr : <Eio.Flow.sink; Eio_unix.Resource.t>;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
type stdenv = Eio_unix.Stdenv.base

let run main =
(* SIGPIPE makes no sense in a modern application. *)
Sys.(set_signal sigpipe Signal_ignore);
Sys.(set_signal sigchld (Signal_handle (fun (_:int) -> Children.handle_sigchld ())));
let stdin = (Flow.of_fd Eio_unix.Fd.stdin :> <Eio.Flow.source; Eio_unix.Resource.t>) in
let stdout = (Flow.of_fd Eio_unix.Fd.stdout :> <Eio.Flow.sink; Eio_unix.Resource.t>) in
let stderr = (Flow.of_fd Eio_unix.Fd.stderr :> <Eio.Flow.sink; Eio_unix.Resource.t>) in
let stdin = (Flow.of_fd Eio_unix.Fd.stdin :> Eio_unix.source) in
let stdout = (Flow.of_fd Eio_unix.Fd.stdout :> Eio_unix.sink) in
let stderr = (Flow.of_fd Eio_unix.Fd.stderr :> Eio_unix.sink) in
Domain_mgr.run_event_loop main @@ object (_ : stdenv)
method stdin = stdin
method stdout = stdout
Expand Down
16 changes: 2 additions & 14 deletions lib_eio_posix/eio_posix.mli
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
(** Fallback Eio backend for POSIX systems. *)

type stdenv = <
stdin : <Eio.Flow.source; Eio_unix.Resource.t>;
stdout : <Eio.Flow.sink; Eio_unix.Resource.t>;
stderr : <Eio.Flow.sink; Eio_unix.Resource.t>;
net : Eio.Net.t;
domain_mgr : Eio.Domain_manager.t;
clock : Eio.Time.clock;
mono_clock : Eio.Time.Mono.t;
fs : Eio.Fs.dir Eio.Path.t;
cwd : Eio.Fs.dir Eio.Path.t;
secure_random : Eio.Flow.source;
debug : Eio.Debug.t;
>
(** An extended version of {!Eio.Stdenv.t} with some extra features available on POSIX systems. *)
type stdenv = Eio_unix.Stdenv.base
(** The type of the standard set of resources available on POSIX systems. *)

val run : (stdenv -> 'a) -> 'a
(** [run main] runs an event loop and calls [main stdenv] inside it.
Expand Down
2 changes: 1 addition & 1 deletion lib_main/eio_main.mli
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(** Select a suitable event loop for Eio. *)

val run : (Eio.Stdenv.t -> 'a) -> 'a
val run : (Eio_unix.Stdenv.base -> 'a) -> 'a
(** [run fn] runs an event loop and then calls [fn env] within it.
[env] provides access to the process's environment (file-system, network, etc).
Expand Down
2 changes: 1 addition & 1 deletion lib_main/linux_backend.enabled.ml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
let run ~fallback fn = Eio_linux.run ~fallback (fun env -> fn (env :> Eio.Stdenv.t))
let run ~fallback fn = Eio_linux.run ~fallback (fun env -> fn (env :> Eio_unix.Stdenv.base))
2 changes: 1 addition & 1 deletion lib_main/posix_backend.enabled.ml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
let run ~fallback:_ fn = Eio_posix.run (fun env -> fn (env :> Eio.Stdenv.t))
let run ~fallback:_ fn = Eio_posix.run (fun env -> fn (env :> Eio_unix.Stdenv.base))
2 changes: 1 addition & 1 deletion lib_main/windows_backend.enabled.ml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
let run ~fallback:_ fn = Eio_windows.run (fun env -> fn (env :> Eio.Stdenv.t))
let run ~fallback:_ fn = Eio_windows.run (fun env -> fn (env :> Eio_unix.Stdenv.base))
2 changes: 1 addition & 1 deletion tests/fs.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open Eio.Std
let ( / ) = Path.( / )
let run (fn : Eio.Stdenv.t -> unit) =
let run fn =
Eio_main.run @@ fun env ->
fn env
Expand Down
2 changes: 1 addition & 1 deletion tests/network.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
```ocaml
open Eio.Std
let run (fn : net:Eio.Net.t -> Switch.t -> unit) =
let run (fn : net:#Eio.Net.t -> Switch.t -> unit) =
Eio_main.run @@ fun env ->
let net = Eio.Stdenv.net env in
Switch.run (fn ~net)
Expand Down

0 comments on commit c576977

Please sign in to comment.