Reputation: 177
I'm trying to understand the use case for EV_DISABLE and EV_ENABLE in kqueue.
int KQueue = kqueue();
struct kevent ev = {
.ident = fd,
.filter = EVFILT_READ,
.flags = EV_ADD | EV_DISABLE,
.udata = somePtr
};
kevent(KQueue, &ev, 1, NULL, 0, NULL);
...
struct kevent ev = {
.ident = fd,
.filter = EVFILT_READ,
.flags = EV_ENABLE
};
kevent(KQueue, &ev, 1, &ev, 1, NULL);
Now, when the last call to kevent()
returns, ev.udata
is NULL
instead of somePtr
. If kevent()
updates the udata
pointer even though EV_ADD isn't set, instead of just enable the event, what is the reason for allowing you to add a disabled event, then?
Upvotes: 3
Views: 1130
Reputation: 4387
Another use case for EV_ENABLE
is in conjunction with EV_DISPATCH
. This is necessary in multi-threaded scenario where you have multiple threads waiting for events in a kevent()
call. When an event occurs, without EV_DISPATCH
, all your threads would be woken up on the same event causing a thundering herd problem. With EV_DISPATCH
, the event is delivered to one thread and disabled right after that (ie. atomically from userspace point of view). The thread then handles the event and may re-enable it.
Upvotes: 4
Reputation: 26
kqueue
did not update udata
. YOU updated udata
by leaving it uninitialized. You are registering the filter with new values. The point of udata
is to cross the kernel with it. You can keep your own pointer in userland
.
The point of disabling an event is that you want it returned at another call, or that you don't want to cause kqueue
to return when it is triggered, but at a different time.
Upvotes: 1