mheily / libkqueue

kqueue(2) compatibility library
Other
236 stars 77 forks source link

Against master/HEAD, EVFILT_TIMER EV_CLEAR and EV_DISPATCH Flags Do Not Seem to Work Correctly with an Updating Data Value #122

Open gerickson opened 2 years ago

gerickson commented 2 years ago

Somewhat related to issue #116, with some changes following the commits aimed to address that issue, behavior of EV_ONESHOT seems to have changed, correctly I believe, however. With EV_ONESHOT, the event and knote are being deleted after the event fires. Per the kevent man page and the description of EV_ONESHOT, that seems to be correct behavior:

EV_ONESHOT Causes the event to return only the first occurrence of the filter being triggered. After the user retrieves the event from the queue, it is deleted.

So, I've change the sample program to use EV_CLEAR | EV_DISPATCH (see attached). However, now, as with the EV_ONESHOT example before it, the data field of the event does not change across calls to kevent as expected and as demonstrated on Mach / Darwin.

On Linux:

% clear && clang-11 -Wall -Werror -fsanitize=address -I/usr/local/include/kqueue kqueue-timer-example.c -L/usr/local/lib -lkqueue -o kqueue-timer-example && ./kqueue-timer-example
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 250 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata (nil)
nevents 1
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa1 (EV_ADD | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata (nil)
start   267680.425620958
stop    267680.675804612
elapsed 0.250183654
[ 0] ==============================
[ 1] ------------------------------
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 333 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata (nil)
nevents 1
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa1 (EV_ADD | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata (nil)
start   267680.680638531
stop    267680.931022231
elapsed 0.250383700
[ 1] ==============================
[ 2] ------------------------------
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 750 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata (nil)
nevents 1
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa1 (EV_ADD | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata (nil)
start   267680.931320008
stop    267681.182399407
elapsed 0.251079399
[ 2] ==============================
[ 3] ------------------------------
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 500 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata (nil)
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata (nil)
nevents 1
[ 0] 0x7ffc21fc7ca0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata (nil)
[ 0] 0x7ffc21fc7ce0 ident 0x7ffc21fc7ca0 filter -7 (EVFILT_TIMER) flags 0xa1 (EV_ADD | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata (nil)
start   267681.182845260
stop    267681.432968610
elapsed 0.250123350
[ 3] ==============================

Note that all of the timers fire at 0.25s, which was the first data value set when the timer was first created.

On Mach/Darwin:

% clear && clang -Wall -Werror -fsanitize=address kqueue-timer-example.c -o kqueue-timer-example && ./kqueue-timer-example
[ 0] ------------------------------
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 250 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata 0x0
nevents 1
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 300 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata 0x0
start   2585260.508240000
stop    2585260.813305000
elapsed 0.305065000
[ 0] ==============================
[ 1] ------------------------------
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 333 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata 0x0
nevents 1
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 400 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata 0x0
start   2585260.813509000
stop    2585261.214593000
elapsed 0.401084000
[ 1] ==============================
[ 2] ------------------------------
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 750 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata 0x0
nevents 1
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 800 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata 0x0
start   2585261.214897000
stop    2585262.20024000
elapsed 0.805127000
[ 2] ==============================
[ 3] ------------------------------
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 500 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata 0x0
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x0 filter 0 (EVFILT_UNKNOWN) flags 0x0 fflags 0x00000000 data 0 udata 0x0
nevents 1
[ 0] 0x7ffeec51be40 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 600 udata 0x0
[ 0] 0x7ffeec51be80 ident 0x7ffeec51be40 filter -7 (EVFILT_TIMER) flags 0xa5 (EV_ADD | EV_ENABLE | EV_CLEAR | EV_DISPATCH) fflags 0x00000000 data 1 udata 0x0
start   2585262.20326000
stop    2585262.624735000
elapsed 0.604409000
[ 3] ==============================

The events fire at the last data value pushed into the event change list for each firing iteration before waiting, correctly and as expected.

arr2036 commented 2 years ago

Can you reduce this down to the behaviour changes that need to be made to bring libkqueue into line with native kqueue?