Question

I have trouble to understand, how to use kqueue for user space events.
I look for 2 use cases.
Use case 1: Manual Reset event
Use case 2: Auto Reset event

I think I understand, how to use kqueue() and kevent(), yet I am unclear on how the events passed to kevent() look for the related operations:
Let there be a struct kevent variable named "event".
Let us assume, we have no problem finding a new event id which is not colliding with other event ids for that kqueue instance, named "eventId".

  1. Create user event: EV_SET(&event, eventId, EVFILT_USER, EV_ADD, NOTE_FFNOP, 0, NULL)
  2. Destroy user event: EV_SET(&event, eventId, EVFILT_USER, EV_DESTROY, NOTE_FFNOP, 0, NULL)
  3. Set the user event: EV_SET(&event, eventId, EVFILT_USER, ?????, NOTE_FFNOP, 0, NULL)
  4. Reset user event: EV_SET(&event, eventId, EVFILT_USER, ??EV_CLEAR???, NOTE_FFNOP, 0, NULL )
  5. Pulse user event: EV_SET(&event, eventId, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL )
  6. In the wait loop, I think the snipped would be along: if( event.filter == EVFILT_USER && event.ident == eventId ) { // this is my event! Do something! }

See the ???? in the above EV_SET() calls to see where I need help.
For use case 1 (Manual reset event), operation (1) Create might look different compared to use case 2 (auto reset event).
Operations (3) and (4) I am completely in the dark. Might I need EV_ENABLE/EV_DISABLE for those? Where is EV_CLEAR fitting in?
So far I assume that I do not need to do anything in operation (6) beyond the "dispatching". I am pretty positive, that operation (5) could work as I gave it above.

I spent now the better of a day trying to find documentation or samples showing how it is done. I found in apple codebase a kqueue test program but I doubt, it is doing it right. Also, it only sends 1 event in the test and that event terminates the loop of the receiving thread. So it is not helping me to understand the details for my 2 use cases.

I plan to use it under FreeBsd 9.1 on a x86 machine...for now.

Was it helpful?

Solution

After some experimenting, I found:

  1. Create user event: EV_SET(&ev, identifier, EVFILT_USER, EV_ADD, NOTE_FFCOPY, 0, NULL )
  2. Destroy user event: EV_SET(&ev, identifier, EVFILT_USER, EV_DELETE, 0, 0, 0)
  3. Set user event: EV_SET( &event, m_eventId, EVFILT_USER, EV_ENABLE, NOTE_FFCOPY|NOTE_TRIGGER|0x1, 0, NULL )
  4. Reset user event: EV_SET( &event, m_eventId, EVFILT_USER, EV_DISABLE, EV_CLEAR|NOTE_FFCOPY, 0, NULL )
  5. Pulse user event: Not tested...did use case 1 for now.
  6. Wait code snippet: As given in original post.

Test works like a charm. In my test I did the NOTE_FFCOPY thing but I don't think it is necessary.

The user events have 2 states - signalled, not signalled. EV_ENABLE and EV_DISABLE set those states it seems.

The test verified, that the events in signalled state actually are reported by kevent() repeatedly.

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