123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118(* 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"]openLwt.Infixletenter_iter_hooks=Lwt_sequence.create()letleave_iter_hooks=Lwt_sequence.create()letyielded=Lwt_sequence.create()letyield()=(Lwt.add_task_r[@ocaml.warning"-3"])yieldedletrecrunt=(* Wakeup paused threads now. *)Lwt.wakeup_paused();matchLwt.polltwith|Somex->x|None->(* Call enter hooks. *)Lwt_sequence.iter_l(funf->f())enter_iter_hooks;(* Do the main loop call. *)Lwt_engine.iter(Lwt.paused_count()=0&&Lwt_sequence.is_emptyyielded);(* Wakeup paused threads again. *)Lwt.wakeup_paused();(* Wakeup yielded threads now. *)ifnot(Lwt_sequence.is_emptyyielded)thenbeginlettmp=Lwt_sequence.create()inLwt_sequence.transfer_ryieldedtmp;Lwt_sequence.iter_l(funwakener->Lwt.wakeupwakener())tmpend;(* Call leave hooks. *)Lwt_sequence.iter_l(funf->f())leave_iter_hooks;runtletexit_hooks=Lwt_sequence.create()letreccall_hooks()=matchLwt_sequence.take_opt_lexit_hookswith|None->Lwt.return_unit|Somef->Lwt.catch(fun()->f())(fun_->Lwt.return_unit)>>=fun()->call_hooks()let()=at_exit(fun()->Lwt.abandon_wakeups();run(call_hooks()))letat_exitf=ignore(Lwt_sequence.add_lfexit_hooks)moduletypeHooks=sigtype'return_valuekindtypehookvaladd_first:(unit->unitkind)->hookvaladd_last:(unit->unitkind)->hookvalremove:hook->unitvalremove_all:unit->unitendmoduletypeHook_sequence=sigtype'return_valuekindvalsequence:(unit->unitkind)Lwt_sequence.tendmoduleWrap_hooks(Sequence:Hook_sequence)=structtype'akind='aSequence.kindtypehook=(unit->unitSequence.kind)Lwt_sequence.nodeletadd_firsthook_fn=lethook_node=Lwt_sequence.add_lhook_fnSequence.sequenceinhook_nodeletadd_lasthook_fn=lethook_node=Lwt_sequence.add_rhook_fnSequence.sequenceinhook_nodeletremovehook_node=Lwt_sequence.removehook_nodeletremove_all()=Lwt_sequence.iter_node_lLwt_sequence.removeSequence.sequenceendmoduleEnter_iter_hooks=Wrap_hooks(structtype'return_valuekind='return_valueletsequence=enter_iter_hooksend)moduleLeave_iter_hooks=Wrap_hooks(structtype'return_valuekind='return_valueletsequence=leave_iter_hooksend)moduleExit_hooks=Wrap_hooks(structtype'return_valuekind='return_valueLwt.tletsequence=exit_hooksend)