123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107(* 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. *)typet={mutabledelay:int;action:unit->unit;mutableprev:t;mutablenext:t}letmakedelayaction=letrecx={delay=delay;action=action;prev=x;next=x}inxletlst_empty()=make(-1)(fun()->())letlst_removex=letp=x.previnletn=x.nextinp.next<-n;n.prev<-p;x.next<-x;x.prev<-xletlst_insertpx=letn=p.nextinp.next<-x;x.prev<-p;x.next<-n;n.prev<-xletlst_in_listx=x.next!=xletlst_is_emptyset=set.next==setletlst_peeks=letx=s.nextinlst_removex;x(****)letcount=ref0letbuckets=ref[||]letcurr=ref0letstopped=reftrueletsizel=letlen=Array.length!bucketsinifl>=lenthenbeginletb=Array.init(l+1)(fun_->lst_empty())inArray.blit!buckets!currb0(len-!curr);Array.blit!buckets0b(len-!curr)!curr;buckets:=b;curr:=0;end(****)lethandle_exn=ref(funexn->!Lwt.async_exception_hookexn)letset_exn_handlerf=handle_exn:=fletrecloop()=stopped:=false;Lwt.bind(Lwt_unix.sleep1.)(fun()->lets=!buckets.(!curr)inwhilenot(lst_is_emptys)doletx=lst_peeksindecrcount;(*XXX Should probably report any exception *)tryx.action()withewhenLwt.Exception_filter.rune->!handle_exnedone;curr:=(!curr+1)mod(Array.length!buckets);if!count>0thenloop()elsebeginstopped:=true;Lwt.return_unitend)letstartx=letin_list=lst_in_listxinletslot=(!curr+x.delay)mod(Array.length!buckets)inlst_removex;lst_insert!buckets.(slot)x;ifnotin_listthenbeginincrcount;if!count=1&&!stoppedthenignore(loop())endletcreatedelayaction=ifdelay<1theninvalid_arg"Lwt_timeout.create";letx=makedelayactioninsizedelay;xletstopx=iflst_in_listxthenbeginlst_removex;decrcountendletchangexdelay=ifdelay<1theninvalid_arg"Lwt_timeout.change";x.delay<-delay;sizedelay;iflst_in_listxthenstartx