Skip to content

Commit

Permalink
Deprecated unix's yield functions implemented as calls to Lwt.pause
Browse files Browse the repository at this point in the history
  • Loading branch information
raphael-proust authored and Christopher Zimmermann committed Mar 2, 2022
1 parent fa15b38 commit 65dd0f3
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 24 deletions.
3 changes: 0 additions & 3 deletions src/core/lwt.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1908,9 +1908,6 @@ val pause : unit -> unit t
Putting the rest of your computation into a callback of [Lwt.pause ()]
creates a “yield” that gives other callbacks a chance to run first.
To wait for one complete iteration of the main loop you need to wait for
[Lwt.pause () >>= Lwt.pause]
For example, to break up a long-running computation, allowing I/O to be
handled between chunks:
Expand Down
14 changes: 2 additions & 12 deletions src/unix/lwt_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ open Lwt.Infix

let enter_iter_hooks = Lwt_sequence.create ()
let leave_iter_hooks = Lwt_sequence.create ()
let yielded = Lwt_sequence.create ()

let yield () = (Lwt.add_task_r [@ocaml.warning "-3"]) yielded
let yield () = Lwt.pause ()

let abandon_yielded_and_paused () =
Lwt_sequence.clear yielded;
Lwt.abandon_paused ()

let run p =
Expand All @@ -34,20 +32,12 @@ let run p =
Lwt_sequence.iter_l (fun f -> f ()) enter_iter_hooks;

(* Do the main loop call. *)
let should_block_waiting_for_io =
Lwt.paused_count () = 0 && Lwt_sequence.is_empty yielded in
let should_block_waiting_for_io = Lwt.paused_count () = 0 in
Lwt_engine.iter should_block_waiting_for_io;

(* Fulfill paused promises. *)
Lwt.wakeup_paused ();

(* Fulfill yield promises. *)
if not (Lwt_sequence.is_empty yielded) then begin
let tmp = Lwt_sequence.create () in
Lwt_sequence.transfer_r yielded tmp;
Lwt_sequence.iter_l (fun resolver -> Lwt.wakeup resolver ()) tmp
end;

(* Call leave hooks. *)
Lwt_sequence.iter_l (fun f -> f ()) leave_iter_hooks;

Expand Down
14 changes: 6 additions & 8 deletions src/unix/lwt_main.mli
Original file line number Diff line number Diff line change
Expand Up @@ -49,22 +49,20 @@ val yield : unit -> unit Lwt.t [@@deprecated "Use Lwt.pause instead"]
@deprecated Since 5.5.0 [yield] is deprecated in favor of the more general
{!Lwt.pause} in order to avoid discrepancies in resolution (see below) and
stay compatible with other execution environments such as js_of_ocaml.
stay compatible with other execution environments such as js_of_ocaml. *)

Currently, paused promises are resolved more frequently than yielded promises.
The difference is unintended but existing applications could depend on it.
Unifying the two pools of promises into one in the future would eliminate
possible discrepancies and simplify the code. *)

val abandon_yielded_and_paused : unit -> unit
val abandon_yielded_and_paused : unit -> unit [@@deprecated "Use Lwt.abandon_paused instead"]
(** Causes promises created with {!Lwt.pause} and {!Lwt_main.yield} to remain
forever pending.
[yield] is now deprecated in favor of the more general {!Lwt.pause}.
Once [yield] is phased out, this function will be deprecated as well.
This is meant for use with {!Lwt.fork}, as a way to "abandon" more promise
chains that are pending in your process. *)
chains that are pending in your process.
@deprecated Since 5.5.1 [abandon_yielded_and_paused] is deprecated in favour
of [Lwt.abandon_paused]. *)



Expand Down
2 changes: 1 addition & 1 deletion src/unix/lwt_unix.cppo.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ let sleep delay =
Lwt.on_cancel waiter (fun () -> Lwt_engine.stop_event ev);
waiter

let yield = (Lwt_main.yield [@warning "-3"])
let yield = Lwt.pause

let auto_yield timeout =
let limit = ref (Unix.gettimeofday () +. timeout) in
Expand Down

0 comments on commit 65dd0f3

Please sign in to comment.