123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596openCoreopenImportmodulePoller=structmoduleU=structtype'at={execution_context:Execution_context.t;result:'aIvar.t;poll:unit->[`Stop_pollingof'a|`Continue_polling];mutableis_alive:bool}[@@derivingfields,sexp_of]letinvarianta_invariantt:unit=Invariant.invariant[%here]t[%sexp_of:_t](fun()->letcheckf=Invariant.check_fieldtfinFields.iter~execution_context:(checkExecution_context.invariant)~result:(check(Ivar.invarianta_invariant))~poll:ignore~is_alive:ignore);;endtypet=T:_U.t->tletsexp_of_t(Tu)=[%sexp_of:_U.t]uletinvariant(Tu)=U.invariantignoreuletis_alive(Tu)=U.is_aliveuendtypet={(* [kernel_scheduler] is [@sexp.opaque] so that one doesn't get two copies of the
kernel scheduler in sexps of the scheduler, which already has its own
[kernel_scheduler] field. *)kernel_scheduler:(Kernel_scheduler.t[@sexp.opaque]);mutablepollers:Poller.tarray}[@@derivingfields,sexp_of]letis_emptyt=Array.is_emptyt.pollersletcreate()={kernel_scheduler=Kernel_scheduler.t();pollers=[||]}letinvariantt=Invariant.invariant[%here]t[%sexp_of:t](fun()->letcheckf=Invariant.check_fieldtfinFields.iter~kernel_scheduler:(checkKernel_scheduler.invariant)~pollers:(check(funpollers->Array.iterpollers~f:(funpoller->Poller.invariantpoller;assert(Poller.is_alivepoller)))));;letpollt=letkernel_scheduler=t.kernel_schedulerinletpollers=t.pollersinletkilled_some=reffalseinfori=0toArray.lengthpollers-1dolet(Poller.Tu)=pollers.(i)inKernel_scheduler.set_execution_contextkernel_scheduleru.execution_context;letshould_kill=trymatchu.poll()with|`Continue_polling->false|`Stop_pollinga->Ivar.fillu.resulta;truewith|exn->Monitor.send_exn(Execution_context.monitoru.execution_context)exn~backtrace:`Get;trueinifshould_killthen(u.is_alive<-false;killed_some:=true)done;if!killed_somethent.pollers<-Array.filtert.pollers~f:Poller.is_alive;;letaddtpoll=letexecution_context=Kernel_scheduler.current_execution_contextt.kernel_schedulerinletresult=Ivar.create()inletpoller=Poller.(T{execution_context;result;poll;is_alive=true})inletn=Array.lengtht.pollersint.pollers<-Array.init(1+n)~f:(funi->ifi<nthent.pollers.(i)elsepoller);Ivar.readresult;;