diff --git a/CHANGES b/CHANGES index 5a80a2d1e..2b0328dd6 100644 --- a/CHANGES +++ b/CHANGES @@ -39,6 +39,10 @@ * Fix marshall header size in Lwt_io.read_value. (Simmo Saan, #995) +====== Misc ====== + + * Resolve paused promises only once in main loop. This lets Lwt.pause behave identical to Lwt_unix.yield. (#917, Christopher Zimmermann, Favonia) + ===== 5.6.1 ===== diff --git a/src/unix/lwt_main.ml b/src/unix/lwt_main.ml index 0cac449b8..25d0ccaee 100644 --- a/src/unix/lwt_main.ml +++ b/src/unix/lwt_main.ml @@ -16,18 +16,14 @@ 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 = let rec run_loop () = - (* Fulfill paused promises now. *) - Lwt.wakeup_paused (); match Lwt.poll p with | Some x -> x @@ -36,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 again. *) + (* 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; diff --git a/src/unix/lwt_main.mli b/src/unix/lwt_main.mli index 0d5c6b3dc..3b4f174b7 100644 --- a/src/unix/lwt_main.mli +++ b/src/unix/lwt_main.mli @@ -49,22 +49,19 @@ 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. + (Note that [yield] is deprecated in favor of the more general {!Lwt.pause}.) This is meant for use with {!Lwt_unix.fork}, as a way to “abandon” more - promise chains that are pending in your process. *) + promise chains that are pending in your process. + + @deprecated Since 5.7 [abandon_yielded_and_paused] is deprecated in favour + of [Lwt.abandon_paused]. *) diff --git a/src/unix/lwt_unix.cppo.ml b/src/unix/lwt_unix.cppo.ml index eda06efdf..8d1fa7f31 100644 --- a/src/unix/lwt_unix.cppo.ml +++ b/src/unix/lwt_unix.cppo.ml @@ -123,7 +123,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