Question

I'm using kqueue for socket synchronization in OS X. I can register an event of interest like the following:

struct kevent change;
EV_SET(&change, connected_socket, EVFILT_READ, EV_ADD, 0, NULL, NULL);
kevent(k_queue_, &change, 1, NULL, 0, NULL);

And the question is, is there a way to trigger this event by force so that the waiting kevent call would return?

Was it helpful?

Solution

Some possibilities aside from natural writing of data to the other side of the socket :)

  • shutdown(2) the read side of that socket - you'll get EV_EOF in flags (silly),
  • Use the timeout argument and call the same handling function,
  • Use the self-pipe trick when you need to break the wait.

My question though: why do you need this?

Edit:

If I understand your comments correctly you are looking for a way to get around edge-triggered behavior (EV_CLEAR) for write events. I believe that the proper way of doing this is to un-register your socket from EVFILT_WRITE when you don't have anything in the outgoing queue, then re-register it again when there's data to send. It's a bit more work, but that's how it works, and you don't need any additional system calls since kevent(2) accepts both changes and results. Take a look into libevent and see how it handles this sort of stuff. And you are using non-blocking sockets, right?

OTHER TIPS

I would recommend a slightly different solution.

Add another registered event to the kqueue. Specifically a EVFILT_USER.

You can use this to trigger whatever behavior you want to wake the kevent() thread up for without the code looking weird or being hard to maintain.

The OSX sources have a real rough test for it in

http://www.opensource.apple.com/source/xnu/xnu-1699.24.23/tools/tests/xnu_quick_test/kqueue_tests.c

OSX 10.6 and FreeBSD 8.1 add support for EVFILT_USER, which we can use to wake up the event loop from another thread.

Note that if you use this to implement your own condition and timedwait, you still need locks in order to avoid race conditions, as explained in this excellent answer.

See my other answer for a full code example: https://stackoverflow.com/a/31174803/432

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top