Hi,
I think, kevent() has a bug.
I tested sample programs by attached sources.
This sample tests about EVFILT_SIGNAL.

I build sample programs by the following commands.
% gcc -O2 -o child child.c
% gcc -O2 -o parent parent.c
The expected result is the following.
% ./parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
OK
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
OK
But, sometimes the result was the following.
% ./parent
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
This result means the number of times the signal has occured was
incorrect.
In case of EVFILT_SIGNAL, according to `man kevent', `data' retuns the
number of times the signal has occurred since the last call to
kevent(). This `data' is recorded by filt_signal() (This is f_event in
struct filterops).
The system call kevent()'s events are processed by kqueue_scan() in
kern_event.c. In kqueue_scan(), kn->kn_fop->f_event() is allways
called after KN_INFLUX is set to kn->kn_status.
On the other hand, kernel events are occured by knote() in
kern_event.c. (In EVFILT_SIGNAL, knote() is called from tdsendsignal()
in kern_sig.c.) In knote(), kn->kn_fop->f_event() is called only when
KN_INFLUX is not set in kn->kn_status.
In race condition between kqueue_scan() and knote(),
kn->kn_fop->f_event() from knote() may not be called, I think.
In knote(), because the context holds knlist's lock, the context can
not sleep. So, KN_INFLUX should not be set on calling
kn->kn_fop->f_event() in kqueue_scan(), I think.
What do you think about this issue?
Best regards,
Kohji Okuno