1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192(* This file is part of Lwt, released under the MIT license. See LICENSE.md for
details, or visit https://github.com/ocsigen/lwt/blob/master/LICENSE.md. *)(* [Lwt_sequence] is deprecated – we don't want users outside Lwt using it.
However, it is still used internally by Lwt. So, briefly disable warning 3
("deprecated"), and create a local, non-deprecated alias for
[Lwt_sequence] that can be referred to by the rest of the code in this
module without triggering any more warnings. *)[@@@ocaml.warning"-3"]moduleLwt_sequence=Lwt_sequence[@@@ocaml.warning"+3"]letensure_terminationt=ifLwt.statet=Lwt.Sleepthenbeginlethook=Lwt_sequence.add_l(fun_->t)Lwt_main.exit_hooks[@ocaml.warning"-3"]in(* Remove the hook when t has terminated *)ignore(Lwt.finalize(fun()->t)(fun()->Lwt_sequence.removehook;Lwt.return_unit))endletfinaliserf=(* In order not to create a reference to the value in the
notification callback, we use an initially unset option cell
which will be filled when the finaliser is called. *)letopt=refNoneinletid=Lwt_unix.make_notification~once:true(fun()->match!optwith|None->assertfalse|Somex->opt:=None;ensure_termination(fx))in(* The real finaliser: fill the cell and send a notification. *)(funx->opt:=Somex;Lwt_unix.send_notificationid)letfinalisefx=Gc.finalise(finaliserf)x(* Exit hook for a finalise_or_exit *)letfoe_exitfcalledweak()=matchWeak.getweak0with|None->(* The value has been garbage collected, normally this point
is never reached *)Lwt.return_unit|Somex->(* Just to avoid double finalisation *)Weak.setweak0None;if!calledthenLwt.return_unitelsebegincalled:=true;fxend(* Finaliser for a finalise_or_exit *)letfoe_finaliserfcalledhook=finaliser(funx->(* Remove the exit hook, it is not needed anymore. *)Lwt_sequence.removehook;(* Call the real finaliser. *)if!calledthenLwt.return_unitelsebegincalled:=true;fxend)letfinalise_or_exitfx=(* Create a weak pointer, so the exit-hook does not keep a reference
to [x]. *)letweak=Weak.create1inWeak.setweak0(Somex);letcalled=reffalseinlethook=Lwt_sequence.add_l(foe_exitfcalledweak)Lwt_main.exit_hooks[@ocaml.warning"-3"]inGc.finalise(foe_finaliserfcalledhook)x