Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using kqueue for EVFILT_USER

Tags:

freebsd

kqueue

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.

like image 786
BitTickler Avatar asked Oct 31 '25 20:10

BitTickler


1 Answers

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.

like image 53
user2173833 Avatar answered Nov 04 '25 10:11

user2173833



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!