Hi guys!
I have Linux multithread application with synchronization based on events (eventfd/poll). I would like to port it to FreeBSD using native FreeBSD calls and don't use linuxuator. So, I'm investigating kqueue and
EVFILT_USER approach. But I have faced with problem when I want to poll some number of particular events. My first approach is to use one kqueue descriptor for all events. For example: I created 50 EVFILT_USER events and attach them to one kqueue. In one of my thread I want to poll 10 from 50 events, so I do:
In the "default" case in the "switch" there may be situation when I catch events that I'm not interesting in that thread (but another threads may awaits them). Do I need to just resend them? Is that good approach?
In Linux I can await just particular events and be sure that events 11-50 will not be caught by the thread's poll().
:
Another approach that I'm pondering is 1 kqueue <=> 1 event: I create a number of kqueue and attach just one EVFILT_USER event to each of them. In this case I could use poll() like in Linux example and poll kqueue descriptors. But this approach has problem two: I cannot reset kqueue descriptor like Linux eventfd descriptor by reading from it.
Could you please advice what is the best approach for event-driven application in FreeBSD? Is resending of non-interested events good like in my first code example?
I have Linux multithread application with synchronization based on events (eventfd/poll). I would like to port it to FreeBSD using native FreeBSD calls and don't use linuxuator. So, I'm investigating kqueue and
EVFILT_USER approach. But I have faced with problem when I want to poll some number of particular events. My first approach is to use one kqueue descriptor for all events. For example: I created 50 EVFILT_USER events and attach them to one kqueue. In one of my thread I want to poll 10 from 50 events, so I do:
C:
void *thread1(void *arg)
{
int ret = -1;
while (1) {
struct kevent tevent[10] = { 0 };
ret = kevent(kq, NULL, 0, tevent, 10, NULL);
if (ret < 0) {
/* handle error */
break;
}
if (ret > 0) {
for (int i = 0; i < ret; i++) {
int event = tevent[i].ident;
switch (event) {
case EVENT1:
/* handle EVENT1 */
break;
case EVENT2:
/* handle EVENT2 */
break;
...
case EVENT10:
/* handle EVENT10 */
break;
default:
/*
Here we can catch the remaining 40 events.
Resend them?
*/
break;
}
}
}
}
}
In the "default" case in the "switch" there may be situation when I catch events that I'm not interesting in that thread (but another threads may awaits them). Do I need to just resend them? Is that good approach?
In Linux I can await just particular events and be sure that events 11-50 will not be caught by the thread's poll().
:
C:
void *thread1(void *arg)
{
int ret = -1;
struct pollfd wait_events[10] = {0};
wait_events[0].fd = event1;
wait_events[0].events = POLLIN;
...
wait_events[9].fd = event10;
wait_events[9].events = POLLIN;
while (1) {
ret = poll(wait_events, 10, -1);
if (ret < 0) {
/* handle error */
break;
}
if (ret > 0) {
if ((wait_events[0].revents & POLLIN) != 0) {
/* handle event1 */
continue;
}
....
if ((wait_events[9].revents & POLLIN) != 0) {
/* handle event10 */
continue;
}
}
}
}
Another approach that I'm pondering is 1 kqueue <=> 1 event: I create a number of kqueue and attach just one EVFILT_USER event to each of them. In this case I could use poll() like in Linux example and poll kqueue descriptors. But this approach has problem two: I cannot reset kqueue descriptor like Linux eventfd descriptor by reading from it.
Could you please advice what is the best approach for event-driven application in FreeBSD? Is resending of non-interested events good like in my first code example?