Skip to content

Commit 2dd452b

Browse files
committed
Handle absence of EVFILT_USER with kevent backend.
Some kqueue implementations do not have EVFILT_USER. We can work around this by creating a timer implementation with a very small timeout.[1] [1] Thanks to this post, which provided the idea for the workaround: https://lists.macosforge.org/pipermail/libdispatch-dev/2009-September/000010.html
1 parent 9610948 commit 2dd452b

File tree

1 file changed

+32
-0
lines changed

1 file changed

+32
-0
lines changed

src/event/event_kevent.c

+32
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ _evfiltstr(short filt)
104104
#ifdef EVFILT_FS
105105
_evfilt2(EVFILT_FS);
106106
#endif
107+
#ifdef EVFILT_USER
107108
_evfilt2(EVFILT_USER);
109+
#endif
108110
#ifdef EVFILT_SOCK
109111
_evfilt2(EVFILT_SOCK);
110112
#endif
@@ -532,11 +534,17 @@ _dispatch_kevent_merge_muxed(dispatch_kevent_t ke)
532534
}
533535
}
534536

537+
#define DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT 0xfffffe00
538+
535539
DISPATCH_NOINLINE
536540
static void
537541
_dispatch_kevent_drain(dispatch_kevent_t ke)
538542
{
543+
#ifdef EVFILT_USER
539544
if (ke->filter == EVFILT_USER) {
545+
#else
546+
if (ke->filter == EVFILT_TIMER && ke->ident == DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT) {
547+
#endif
540548
_dispatch_kevent_mgr_debug("received", ke);
541549
return;
542550
}
@@ -583,10 +591,17 @@ static void
583591
_dispatch_kq_create(intptr_t *fd_ptr)
584592
{
585593
static const dispatch_kevent_s kev = {
594+
#ifdef EVFILT_USER
586595
.ident = 1,
587596
.filter = EVFILT_USER,
588597
.flags = EV_ADD|EV_CLEAR,
589598
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
599+
#else
600+
.ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT,
601+
.filter = EVFILT_TIMER,
602+
.flags = EV_ADD|EV_DISABLE|EV_ONESHOT,
603+
.data = 1,
604+
#endif
590605
};
591606
int kqfd;
592607

@@ -789,9 +804,15 @@ _dispatch_kq_drain(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
789804

790805
#if DISPATCH_DEBUG
791806
for (r = 0; r < n; r++) {
807+
#ifdef EVFILT_USER
792808
if (ke[r].filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
793809
_dispatch_kevent_debug_n(NULL, ke + r, r, n);
794810
}
811+
#else
812+
if (DISPATCH_MGR_QUEUE_DEBUG) {
813+
_dispatch_kevent_debug_n(NULL, ke + r, r, n);
814+
}
815+
#endif
795816
}
796817
#endif
797818

@@ -923,9 +944,13 @@ _dispatch_kq_deferred_update(dispatch_wlh_t wlh, dispatch_kevent_t ke)
923944
ke->udata);
924945
dispatch_kevent_t dk = _dispatch_kq_deferred_reuse_slot(wlh, ddi, slot);
925946
*dk = *ke;
947+
#ifdef EVFILT_USER
926948
if (ke->filter != EVFILT_USER) {
927949
_dispatch_kevent_mgr_debug("deferred", ke);
928950
}
951+
#else
952+
_dispatch_kevent_mgr_debug("deferred", ke);
953+
#endif
929954
} else {
930955
_dispatch_kq_update_one(wlh, ke);
931956
}
@@ -1887,10 +1912,17 @@ _dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t dq_state, uint32_t flags)
18871912
{
18881913
if (wlh == DISPATCH_WLH_MANAGER) {
18891914
dispatch_kevent_s ke = (dispatch_kevent_s){
1915+
#ifdef EVFILT_USER
18901916
.ident = 1,
18911917
.filter = EVFILT_USER,
18921918
.fflags = NOTE_TRIGGER,
18931919
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
1920+
#else
1921+
.ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT,
1922+
.filter = EVFILT_TIMER,
1923+
.flags = EV_ADD|EV_ENABLE|EV_ONESHOT,
1924+
.data = 1
1925+
#endif
18941926
};
18951927
return _dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke);
18961928
} else if (wlh && wlh != DISPATCH_WLH_ANON) {

0 commit comments

Comments
 (0)