From d2699afbca6d41818a546ccbbd126482c5beb6f1 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Tue, 22 Aug 2023 18:50:13 +1200 Subject: [PATCH] Prefer one-shot semantics for kqueue. --- ext/io/event/selector/epoll.c | 2 +- ext/io/event/selector/kqueue.c | 33 +++++---------------------------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/ext/io/event/selector/epoll.c b/ext/io/event/selector/epoll.c index 38b84a75..98d0490f 100644 --- a/ext/io/event/selector/epoll.c +++ b/ext/io/event/selector/epoll.c @@ -314,9 +314,9 @@ void IO_Event_Selector_EPoll_Descriptor_initialize(void *element) { struct IO_Event_Selector_EPoll_Descriptor *epoll_descriptor = element; IO_Event_List_initialize(&epoll_descriptor->list); + epoll_descriptor->io = 0; epoll_descriptor->waiting_events = 0; epoll_descriptor->registered_events = 0; - epoll_descriptor->io = 0; } void IO_Event_Selector_EPoll_Descriptor_free(void *element) diff --git a/ext/io/event/selector/kqueue.c b/ext/io/event/selector/kqueue.c index 35996d3a..0515e1a8 100644 --- a/ext/io/event/selector/kqueue.c +++ b/ext/io/event/selector/kqueue.c @@ -214,45 +214,26 @@ enum IO_Event events_from_kevent_filter(int filter) inline static int IO_Event_Selector_KQueue_Descriptor_update(struct IO_Event_Selector_KQueue *selector, uintptr_t identifier, struct IO_Event_Selector_KQueue_Descriptor *kqueue_descriptor) { - // if (kqueue_descriptor->registered_events == kqueue_descriptor->waiting_events) { - // // All the events we are interested in are already registered. - // return 0; - // } - int count = 0; struct kevent kevents[3] = {0}; if (kqueue_descriptor->waiting_events & IO_EVENT_READABLE) { kevents[count].ident = identifier; kevents[count].filter = EVFILT_READ; - kevents[count].flags = EV_ADD | EV_ENABLE; + kevents[count].flags = EV_ADD | EV_ONESHOT; kevents[count].udata = (void *)kqueue_descriptor; - // #ifdef EV_OOBAND // if (events & IO_EVENT_PRIORITY) { // kevents[count].flags |= EV_OOBAND; // } // #endif - - count++; - } else if (kqueue_descriptor->registered_events & IO_EVENT_READABLE) { - kevents[count].ident = identifier; - kevents[count].filter = EVFILT_READ; - kevents[count].flags = EV_DELETE; - kevents[count].udata = (void *)kqueue_descriptor; count++; } if (kqueue_descriptor->waiting_events & IO_EVENT_WRITABLE) { kevents[count].ident = identifier; kevents[count].filter = EVFILT_WRITE; - kevents[count].flags = EV_ADD | EV_ENABLE; - kevents[count].udata = (void *)kqueue_descriptor; - count++; - } else if (kqueue_descriptor->registered_events & IO_EVENT_WRITABLE) { - kevents[count].ident = identifier; - kevents[count].filter = EVFILT_WRITE; - kevents[count].flags = EV_DELETE; + kevents[count].flags = EV_ADD | EV_ONESHOT; kevents[count].udata = (void *)kqueue_descriptor; count++; } @@ -260,16 +241,10 @@ int IO_Event_Selector_KQueue_Descriptor_update(struct IO_Event_Selector_KQueue * if (kqueue_descriptor->waiting_events & IO_EVENT_EXIT) { kevents[count].ident = identifier; kevents[count].filter = EVFILT_PROC; - kevents[count].flags = EV_ADD | EV_ENABLE | EV_ONESHOT; + kevents[count].flags = EV_ADD | EV_ONESHOT; kevents[count].fflags = NOTE_EXIT; kevents[count].udata = (void *)kqueue_descriptor; count++; - } else if (kqueue_descriptor->registered_events & IO_EVENT_EXIT) { - kevents[count].ident = identifier; - kevents[count].filter = EVFILT_PROC; - kevents[count].flags = EV_DELETE; - kevents[count].udata = (void *)kqueue_descriptor; - count++; } if (count == 0) { @@ -887,6 +862,8 @@ int IO_Event_Selector_KQueue_handle(struct IO_Event_Selector_KQueue *selector, u if (ready_events) { kqueue_descriptor->ready_events = 0; + // Since we use one-shot semantics, we need to re-arm the events that are ready if needed: + kqueue_descriptor->registered_events &= ~ready_events; } else { return 0; }