Skip to content

Add bind_on and await_on to Picos_lwt #338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/picos_lwt.unix/picos_lwt_unix.ml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let rec notify () =
end
else notify ()

module System = struct
module System : Picos_lwt.System = struct
let sleep = Lwt_unix.sleep

type trigger = unit Lwt.t * unit Lwt.u
Expand Down
3 changes: 3 additions & 0 deletions lib/picos_lwt.unix/picos_lwt_unix.mli
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

open Picos

val system : (module Picos_lwt.System)
(** The system module for Unix. *)

val run_fiber : Fiber.t -> (Fiber.t -> unit) -> unit Lwt.t
(** [run_fiber fiber main] runs the [main] program as the specified [fiber] as a
promise with {!Lwt} as the scheduler using a {!Lwt_unix} based
Expand Down
31 changes: 31 additions & 0 deletions lib/picos_lwt/picos_lwt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,37 @@ let await promise =
| Return value -> value
| Fail exn -> raise exn

let bind_on (module System : System) thunk =
let trigger = System.trigger () in
let promise = Lwt.bind (System.await trigger) thunk in
System.signal trigger;
promise

let await_on (module System : System) promise =
let computation = Computation.create ~mode:`LIFO () in
let trigger = System.trigger () in
let promise =
Lwt.bind (System.await trigger) @@ fun () ->
Lwt.try_bind
(fun () -> promise)
(fun value ->
Computation.return computation value;
Lwt.return_unit)
(fun exn ->
Computation.cancel computation exn empty_bt;
Lwt.return_unit)
in
System.signal trigger;
let trigger = Trigger.create () in
if Computation.try_attach computation trigger then begin
match Trigger.await trigger with
| None -> Computation.peek_exn computation
| Some (exn, bt) ->
Lwt.cancel promise;
Printexc.raise_with_backtrace exn bt
end
else Computation.peek_exn computation

let[@alert "-handler"] rec go : type a r.
Fiber.t ->
(module System) ->
Expand Down
6 changes: 6 additions & 0 deletions lib/picos_lwt/picos_lwt.mli
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ val await : 'a Lwt.t -> 'a

include module type of Intf

val bind_on : (module System) -> (unit -> 'a Lwt.t) -> 'a Lwt.t
(** *)

val await_on : (module System) -> 'a Lwt.t -> 'a
(** *)

val run_fiber : (module System) -> Fiber.t -> (Fiber.t -> unit) -> unit Lwt.t
(** [run_fiber (module System) fiber main] runs the [main] program as the
specified [fiber] as a promise with {!Lwt} as the scheduler using the given
Expand Down