123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304moduleFfi=structexternalis_available:unit->bool="kqueue_stubs_is_available"externalkqueue:unit->Unix.file_descr="kqueue_ml_kqueue_create"externalkevent:Unix.file_descr->Bigstring.t->int->Bigstring.t->int->int64->int="kqueue_ml_kevent_bytecode""kqueue_ml_kevent_native"moduleKevent=structexternalsizeof:unit->int="kqueue_ml_kevent_sizeof"externalevent_ident_offset:unit->int="kqueue_ml_kevent_offset_event_fd"letevent_ident_offset=event_ident_offset()externalevent_filter_offset:unit->int="kqueue_ml_kevent_offset_filter"letevent_filter_offset=event_filter_offset()externalevent_flags_offset:unit->int="kqueue_ml_kevent_offset_flags"letevent_flags_offset=event_flags_offset()externalevent_fflags_offset:unit->int="kqueue_ml_kevent_offset_fflags"letevent_fflags_offset=event_fflags_offset()externalevent_data_offset:unit->int="kqueue_ml_kevent_offset_data"letevent_data_offset=event_data_offset()externalevent_udata_offset:unit->int="kqueue_ml_kevent_offset_udata"letevent_udata_offset=event_udata_offset()letsizeof=sizeof()letread_ident_atbufidx=Bigstring.unsafe_get_int64_le_truncbuf~pos:((idx*sizeof)+event_ident_offset)letwrite_ident_atbufidxident=Bigstring.unsafe_set_int64_lebuf~pos:((idx*sizeof)+event_ident_offset)identletread_filter_atbufidx=Bigstring.unsafe_get_int16_lebuf~pos:((idx*sizeof)+event_filter_offset)letwrite_filter_atbufidxfilter=Bigstring.unsafe_set_int16_lebuf~pos:((idx*sizeof)+event_filter_offset)filterletread_flags_atbufidx=Bigstring.unsafe_get_int16_lebuf~pos:((idx*sizeof)+event_flags_offset)letwrite_flags_atbufidxflags=Bigstring.unsafe_set_int16_lebuf~pos:((idx*sizeof)+event_flags_offset)flagsletread_fflags_atbufidx=Bigstring.unsafe_get_int32_lebuf~pos:((idx*sizeof)+event_fflags_offset)letwrite_fflags_atbufidxfflags=Bigstring.unsafe_set_int32_lebuf~pos:((idx*sizeof)+event_fflags_offset)fflagsletread_data_atbufidx=Bigstring.unsafe_get_int64_le_truncbuf~pos:((idx*sizeof)+event_data_offset)letwrite_data_atbufidxdata=Bigstring.unsafe_set_int64_lebuf~pos:((idx*sizeof)+event_data_offset)dataletread_udata_atbufidx=Bigstring.unsafe_get_int64_le_truncbuf~pos:((idx*sizeof)+event_udata_offset)letwrite_udata_atbufidxdata=Bigstring.unsafe_set_int64_lebuf~pos:((idx*sizeof)+event_udata_offset)dataendendmoduleNote=structtypet=intletequal=Int.equallet(=)=equalletempty=0externalseconds:unit->int="kqueue_constant_note_seconds"externaluseconds:unit->int="kqueue_constant_note_useconds"externalnseconds:unit->int="kqueue_constant_note_nseconds"externallowat:unit->int="kqueue_constant_note_lowat"externalexec:unit->int="kqueue_constant_note_exec"externalfork:unit->int="kqueue_constant_note_fork"externalexit:unit->int="kqueue_constant_note_exit"externalrevoke:unit->int="kqueue_constant_note_revoke"externalrename:unit->int="kqueue_constant_note_rename"externallink:unit->int="kqueue_constant_note_link"externalattrib:unit->int="kqueue_constant_note_attrib"externalextend:unit->int="kqueue_constant_note_extend"externalwrite:unit->int="kqueue_constant_note_write"externaldelete:unit->int="kqueue_constant_note_delete"letseconds=seconds()letuseconds=useconds()letnseconds=nseconds()letlowat=lowat()letexec=exec()letfork=fork()letexit=exit()letrevoke=revoke()letrename=rename()letlink=link()letattrib=attrib()letextend=extend()letwrite=write()letdelete=delete()endmoduleFlag=structtypet=intletequal=Int.equallet(=)=equallet(+)=(lor)letintersectt1t2=t1landt2<>0externalreceipt:unit->int="kqueue_constant_ev_receipt"externaladd:unit->int="kqueue_constant_ev_add"externalerror:unit->int="kqueue_constant_ev_error"externaleof:unit->int="kqueue_constant_ev_eof"externalclear:unit->int="kqueue_constant_ev_clear"externaloneshot:unit->int="kqueue_constant_ev_oneshot"externaldelete:unit->int="kqueue_constant_ev_delete"externaldisable:unit->int="kqueue_constant_ev_disable"externalenable:unit->int="kqueue_constant_ev_enable"letreceipt=receipt()letadd=add()leterror=error()leteof=eof()letclear=clear()letoneshot=oneshot()letdelete=delete()letdisable=disable()letenable=enable()letknown_flags=[(add,"EV_ADD");(receipt,"EV_RECEIPT");(error,"EV_ERROR");(eof,"EV_EOF");(clear,"EV_CLEAR");(oneshot,"EV_ONESHOT");(delete,"EV_DELETE");(disable,"EV_DISABLE");(enable,"EV_ENABLE");]letis_subsett~of_:flags=t=tlandflagsletppfmtt=letknown_flags=List.filter_map(fun(k,label)->ifis_subsetk~of_:tthenSomelabelelseNone)known_flagsinFormat.pp_print_list~pp_sep:(funfmt()->Format.fprintffmt", ")Format.pp_print_stringfmtknown_flagsendmoduleFilter=structtypet=intletppfmtx=Format.pp_print_intfmtxletequalab=Int.equalablet(=)=equalletcompareab=Int.compareabexternalread:unit->int="kqueue_constant_evfilt_read"externalwrite:unit->int="kqueue_constant_evfilt_write"externaltimer:unit->int="kqueue_constant_evfilt_timer"externalproc:unit->int="kqueue_constant_evfilt_proc"externalvnode:unit->int="kqueue_constant_evfilt_vnode"letread=read()letwrite=write()lettimer=timer()letproc=proc()letvnode=vnode()endmoduleTimeout=structtypet=int64letnever=-1Lletimmediate=0Lletof_nsx=ifx<0Ltheninvalid_arg"Timeout cannot be negative";xendmoduleEvent_list=structtypet={buffer:Bigstring.t;mutablelength:int;max_length:int}letnull={buffer=Bigstring.create0;length=0;max_length=0}letlengtht=t.lengthmoduleEvent=structtypet={buf:Bigstring.t;idx:int}letget_identt=Ffi.Kevent.read_ident_att.buft.idxletset_identtident=Ffi.Kevent.write_ident_att.buft.idxidentletget_filtert=Ffi.Kevent.read_filter_att.buft.idxletset_filtertfilter=Ffi.Kevent.write_filter_att.buft.idxfilterletget_flagst=Ffi.Kevent.read_flags_att.buft.idxletset_flagstflags=Ffi.Kevent.write_flags_att.buft.idxflagsletget_fflagst=Ffi.Kevent.read_fflags_att.buft.idxletset_fflagstfflags=Ffi.Kevent.write_fflags_att.buft.idxfflagsletget_datat=Ffi.Kevent.read_data_att.buft.idxletset_datatdata=Ffi.Kevent.write_data_att.buft.idxdataletget_udatat=Ffi.Kevent.read_udata_att.buft.idxletset_udatatudata=Ffi.Kevent.write_udata_att.buft.idxudataendletcreatesize=ifsize<1theninvalid_arg"Kqueue.create: changelist_size cannot be less than 1";ifnot(Ffi.is_available())thenbeginfailwith"Kqueue is not available"end;{buffer=Bigstring.create(Ffi.Kevent.sizeof*size);length=0;max_length=size;}letcleart=t.length<-0letfill_eventstcountf=ifcount<1theninvalid_arg(Printf.sprintf"Number of events (%d) cannot be less than 1"count);ifcount>t.max_lengththeninvalid_arg(Printf.sprintf"count cannot be greater than max event list size (%d)"t.max_length);fori=0tocount-1dofi{Event.buf=t.buffer;idx=i}done;t.length<-countletiter_eventstf=ift.length>0thenbeginfori=0tot.length-1dof{Event.buf=t.buffer;idx=i}doneendendtypet={fd:Unix.file_descr;mutableis_closed:bool}letensure_opent=ift.is_closedthenfailwith"Attempting to use a closed kqueue"letis_available=Ffi.is_available()letcreate()=letfd=Ffi.kqueue()in{fd;is_closed=false}letcloset=ifnott.is_closedthenbegint.is_closed<-true;Unix.closet.fdendletkeventt~(changelist:Event_list.t)~(eventlist:Event_list.t)timeout=ensure_opent;letevents_to_write=changelist.lengthinchangelist.length<-0;letcount=Ffi.keventt.fdchangelist.Event_list.bufferevents_to_writeeventlist.Event_list.buffereventlist.max_lengthtimeoutineventlist.length<-count;count