vestol
vestol

Reputation: 177

What's the purpose of kqueue EV_ENABLE and EV_DISABLE

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

Answers (2)

kralyk
kralyk

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

tautology
tautology

Reputation: 26

  1. 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.

  2. 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

Related Questions