mirror of
https://github.com/ocaml-multicore/eio.git
synced 2025-10-05 00:04:45 -04:00
Allow returning a result from Eio_main.run
This is useful for e.g. cmdliner. We want to parse the command line arguments inside the event loop so that we can use Eio, but we want to call `exit` with the exit code after the loop has cleaned up.
This commit is contained in:
parent
338d74bc8c
commit
a9620bcf3d
@ -41,7 +41,7 @@ Before we start, we'll define a wrapper around `Eio_main.run` for the examples b
|
||||
Eio_main.run @@ fun env ->
|
||||
let domain_mgr = Eio.Stdenv.domain_mgr env in
|
||||
fn (Eio.Domain_manager.run domain_mgr);;
|
||||
val run : (((unit -> 'a) -> 'a) -> unit) -> unit = <fun>
|
||||
val run : (((unit -> 'a) -> 'a) -> 'b) -> 'b = <fun>
|
||||
```
|
||||
|
||||
## Problems with Multicore Programming
|
||||
|
@ -1222,7 +1222,8 @@ let monitor_event_fd t =
|
||||
assert (got = 8);
|
||||
(* We just go back to sleep now, but this will cause the scheduler to look
|
||||
at the run queue again and notice any new items. *)
|
||||
done
|
||||
done;
|
||||
assert false
|
||||
|
||||
let no_fallback (`Msg msg) = failwith msg
|
||||
|
||||
@ -1241,7 +1242,9 @@ let with_uring ~queue_depth ?polling_timeout ?(fallback=no_fallback) fn =
|
||||
end;
|
||||
Printexc.raise_with_backtrace ex bt
|
||||
|
||||
let rec run ?(queue_depth=64) ?n_blocks ?(block_size=4096) ?polling_timeout ?fallback main =
|
||||
let rec run : type a.
|
||||
?queue_depth:int -> ?n_blocks:int -> ?block_size:int -> ?polling_timeout:int -> ?fallback:(_ -> a) -> (_ -> a) -> a =
|
||||
fun ?(queue_depth=64) ?n_blocks ?(block_size=4096) ?polling_timeout ?fallback main ->
|
||||
Log.debug (fun l -> l "starting run");
|
||||
let n_blocks = Option.value n_blocks ~default:queue_depth in
|
||||
let stdenv = stdenv ~run_event_loop:(run ~queue_depth ~n_blocks ~block_size ?polling_timeout ?fallback:None) in
|
||||
@ -1383,6 +1386,7 @@ let rec run ?(queue_depth=64) ?n_blocks ?(block_size=4096) ?polling_timeout ?fal
|
||||
| _ -> None
|
||||
}
|
||||
in
|
||||
let result = ref None in
|
||||
let `Exit_scheduler =
|
||||
let new_fiber = Fiber_context.make_root () in
|
||||
fork ~new_fiber (fun () ->
|
||||
@ -1396,10 +1400,13 @@ let rec run ?(queue_depth=64) ?n_blocks ?(block_size=4096) ?polling_timeout ?fal
|
||||
Unix.close fd
|
||||
);
|
||||
Log.debug (fun f -> f "Monitoring eventfd %a" FD.pp st.eventfd);
|
||||
Fiber.first
|
||||
(fun () -> main stdenv)
|
||||
(fun () -> monitor_event_fd st)
|
||||
result := Some (
|
||||
Fiber.first
|
||||
(fun () -> main stdenv)
|
||||
(fun () -> monitor_event_fd st)
|
||||
)
|
||||
)
|
||||
)
|
||||
in
|
||||
Log.debug (fun l -> l "exit")
|
||||
Log.debug (fun l -> l "exit");
|
||||
Option.get !result
|
||||
|
@ -84,8 +84,8 @@ val run :
|
||||
?n_blocks:int ->
|
||||
?block_size:int ->
|
||||
?polling_timeout:int ->
|
||||
?fallback:([`Msg of string] -> unit) ->
|
||||
(stdenv -> unit) -> unit
|
||||
?fallback:([`Msg of string] -> 'a) ->
|
||||
(stdenv -> 'a) -> 'a
|
||||
(** Run an event loop using io_uring.
|
||||
|
||||
Uses {!Uring.create} to create the io_uring,
|
||||
|
@ -813,7 +813,7 @@ let rec wakeup ~async run_q =
|
||||
Luv.Async.send async |> or_raise
|
||||
| None -> ()
|
||||
|
||||
let rec run main =
|
||||
let rec run : type a. (_ -> a) -> a = fun main ->
|
||||
Log.debug (fun l -> l "starting run");
|
||||
let loop = Luv.Loop.init () |> or_raise in
|
||||
let run_q = Lf_queue.create () in
|
||||
@ -908,7 +908,7 @@ let rec run main =
|
||||
let new_fiber = Fiber_context.make_root () in
|
||||
fork ~new_fiber (fun () ->
|
||||
begin match main stdenv with
|
||||
| () -> main_status := `Done
|
||||
| v -> main_status := `Done v
|
||||
| exception ex -> main_status := `Ex (ex, Printexc.get_raw_backtrace ())
|
||||
end;
|
||||
Luv.Loop.stop loop
|
||||
@ -917,6 +917,6 @@ let rec run main =
|
||||
Lf_queue.close st.run_q;
|
||||
Luv.Handle.close async (fun () -> Luv.Loop.close loop |> or_raise);
|
||||
match !main_status with
|
||||
| `Done -> ()
|
||||
| `Done v -> v
|
||||
| `Ex (ex, bt) -> Printexc.raise_with_backtrace ex bt
|
||||
| `Running -> failwith "Deadlock detected: no events scheduled but main function hasn't returned"
|
||||
|
@ -122,4 +122,4 @@ val get_fd_opt : #Eio.Generic.t -> Low_level.File.t option
|
||||
|
||||
(** {1 Main Loop} *)
|
||||
|
||||
val run : (stdenv -> unit) -> unit
|
||||
val run : (stdenv -> 'a) -> 'a
|
||||
|
@ -1,6 +1,6 @@
|
||||
(** Select a suitable event loop for Eio. *)
|
||||
|
||||
val run : (Eio.Stdenv.t -> unit) -> unit
|
||||
val run : (Eio.Stdenv.t -> '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).
|
||||
|
Loading…
x
Reference in New Issue
Block a user