1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495openCoreopenCore.Otype'aoutcome=|Cancelledof'a|Not_cancelledtypehandlers=|End_of_handlers|Handlerof{ivar:unitoutcomeIvar.t;mutablenext:handlers;mutableprev:handlers}moduleState=structtypet=|Cancelled|Not_cancelledof{mutablehandlers:handlers}endtypet={mutablestate:State.t}letcreate()={state=Not_cancelled{handlers=End_of_handlers}}letrecinvoke_handlers=function|Handler{ivar;next;prev=_}->let*()=Ivar.fillivar(Cancelled())ininvoke_handlersnext|End_of_handlers->return()letfiret=of_thunk(fun()->matcht.statewith|Cancelled->return()|Not_cancelled{handlers}->t.state<-Cancelled;invoke_handlershandlers)letrecfills_of_handlersacc=function|Handler{ivar;next;prev=_}->fills_of_handlers(Scheduler.Fill(ivar,Cancelled())::acc)next|End_of_handlers->List.revaccletfire't=matcht.statewith|Cancelled->[]|Not_cancelled{handlers}->t.state<-Cancelled;fills_of_handlers[]handlersletfiredt=matcht.statewith|Cancelled->true|Not_cancelled_->falseletwith_handlertf~on_cancel=matcht.statewith|Cancelled->let+x,y=fork_and_joinfon_cancelin(x,Cancelledy)|Not_cancelledh->letivar=Ivar.create()inletnode=Handler{ivar;next=h.handlers;prev=End_of_handlers}in(matchh.handlerswith|End_of_handlers->()|Handlerfirst->first.prev<-node);h.handlers<-node;fork_and_join(fun()->let*y=f()inmatcht.statewith|Cancelled->returny|Not_cancelledh->(matchnodewith|End_of_handlers->(* We could avoid this [assert false] with GADT sorcery given that
we created [node] just above and we know for sure it is the
[Handler _] case, but it's not worth the code complexity. *)assertfalse|Handlernode->(matchnode.prevwith|End_of_handlers->h.handlers<-node.next|Handlerprev->prev.next<-node.next);(matchnode.nextwith|End_of_handlers->()|Handlernext->next.prev<-node.prev);let+()=Ivar.fillivarNot_cancellediny))(fun()->Ivar.readivar>>=function|Cancelled()->let+x=on_cancel()inCancelledx|Not_cancelled->returnNot_cancelled)