262 lines
7.6 KiB
Text
262 lines
7.6 KiB
Text
backport of https://github.com/apple/swift-corelibs-libdispatch/pull/559
|
|
|
|
Index: src/event/event_kevent.c
|
|
--- src/event/event_kevent.c.orig
|
|
+++ src/event/event_kevent.c
|
|
@@ -101,8 +101,12 @@ _evfiltstr(short filt)
|
|
_evfilt2(EVFILT_MACHPORT);
|
|
_evfilt2(DISPATCH_EVFILT_MACH_NOTIFICATION);
|
|
#endif
|
|
+#ifdef EVFILT_FS
|
|
_evfilt2(EVFILT_FS);
|
|
+#endif
|
|
+#ifdef EVFILT_USER
|
|
_evfilt2(EVFILT_USER);
|
|
+#endif
|
|
#ifdef EVFILT_SOCK
|
|
_evfilt2(EVFILT_SOCK);
|
|
#endif
|
|
@@ -236,9 +240,9 @@ dispatch_kevent_debug(const char *verb, const dispatch
|
|
|
|
#define _dispatch_du_debug(what, du) \
|
|
_dispatch_debug("kevent-source[%p]: %s kevent[%p] " \
|
|
- "{ filter = %s, ident = 0x%x }", \
|
|
+ "{ filter = %s, ident = 0x%llx }", \
|
|
_dispatch_wref2ptr((du)->du_owner_wref), what, \
|
|
- (du), _evfiltstr((du)->du_filter), (du)->du_ident)
|
|
+ (du), _evfiltstr((du)->du_filter), (unsigned long long)(du)->du_ident)
|
|
|
|
#if DISPATCH_MACHPORT_DEBUG
|
|
#ifndef MACH_PORT_TYPE_SPREQUEST
|
|
@@ -388,8 +392,10 @@ _dispatch_kevent_print_error(dispatch_kevent_t ke)
|
|
switch (ke->data) {
|
|
case 0:
|
|
return;
|
|
+#if DISPATCH_USE_KEVENT_QOS
|
|
case ERANGE: /* A broken QoS was passed to kevent_id() */
|
|
DISPATCH_INTERNAL_CRASH(ke->qos, "Invalid kevent priority");
|
|
+#endif
|
|
default:
|
|
// log the unexpected error
|
|
_dispatch_bug_kevent_client("kevent", _evfiltstr(ke->filter),
|
|
@@ -397,7 +403,7 @@ _dispatch_kevent_print_error(dispatch_kevent_t ke)
|
|
ke->flags & EV_DELETE ? "delete" :
|
|
ke->flags & EV_ADD ? "add" :
|
|
ke->flags & EV_ENABLE ? "enable" : "monitor",
|
|
- (int)ke->data, ke->ident, ke->udata, du);
|
|
+ (int)ke->data, ke->ident, (uint64_t)ke->udata, du);
|
|
}
|
|
}
|
|
|
|
@@ -528,11 +534,17 @@ _dispatch_kevent_merge_muxed(dispatch_kevent_t ke)
|
|
}
|
|
}
|
|
|
|
+#define DISPATCH_KEVENT_ERSATZ_EVFILT_USER_MASK 0xfffffe00
|
|
+
|
|
DISPATCH_NOINLINE
|
|
static void
|
|
_dispatch_kevent_drain(dispatch_kevent_t ke)
|
|
{
|
|
+#ifdef EVFILT_USER
|
|
if (ke->filter == EVFILT_USER) {
|
|
+#else
|
|
+ if (ke->filter == EVFILT_TIMER && ke->ident == DISPATCH_KEVENT_ERSATZ_EVFILT_USER_MASK) {
|
|
+#endif
|
|
_dispatch_kevent_mgr_debug("received", ke);
|
|
return;
|
|
}
|
|
@@ -579,10 +591,17 @@ static void
|
|
_dispatch_kq_create(intptr_t *fd_ptr)
|
|
{
|
|
static const dispatch_kevent_s kev = {
|
|
+#ifdef EVFILT_USER
|
|
.ident = 1,
|
|
.filter = EVFILT_USER,
|
|
.flags = EV_ADD|EV_CLEAR,
|
|
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
|
|
+#else
|
|
+ .ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_MASK,
|
|
+ .filter = EVFILT_TIMER,
|
|
+ .flags = EV_ADD|EV_DISABLE,
|
|
+ .data = 1,
|
|
+#endif
|
|
};
|
|
int kqfd;
|
|
|
|
@@ -591,7 +610,6 @@ _dispatch_kq_create(intptr_t *fd_ptr)
|
|
guardid_t guard = (uintptr_t)fd_ptr;
|
|
kqfd = guarded_kqueue_np(&guard, GUARD_CLOSE | GUARD_DUP);
|
|
#else
|
|
- (void)guard_ptr;
|
|
kqfd = kqueue();
|
|
#endif
|
|
if (kqfd == -1) {
|
|
@@ -727,6 +745,10 @@ retry:
|
|
(void)avail;
|
|
const struct timespec timeout_immediately = {}, *timeout = NULL;
|
|
if (flags & KEVENT_FLAG_IMMEDIATE) timeout = &timeout_immediately;
|
|
+#ifdef EVFILT_USER
|
|
+ const struct timespec timeout_1ms = {.tv_sec = 0, .tv_nsec = 1000000}
|
|
+ if (ke.ident == DISPATCH_KEVENT_ERSATZ_EVFILT_USER_MASK) timeout = &timeout_1ms;
|
|
+#endif
|
|
r = kevent(kqfd, ke, n, ke_out, n_out, timeout);
|
|
#endif
|
|
#if DISPATCH_USE_KEVENT_WORKLOOP
|
|
@@ -743,7 +765,7 @@ retry:
|
|
switch (err) {
|
|
case ENOMEM:
|
|
_dispatch_temporary_resource_shortage();
|
|
- /* FALLTHROUGH */
|
|
+ DISPATCH_FALLTHROUGH;
|
|
case EINTR:
|
|
goto retry;
|
|
case EBADF:
|
|
@@ -754,7 +776,7 @@ retry:
|
|
(flags & KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST)) {
|
|
return 0;
|
|
}
|
|
- /* FALLTHROUGH */
|
|
+ DISPATCH_FALLTHROUGH;
|
|
#endif // DISPATCH_USE_KEVENT_WORKLOOP
|
|
default:
|
|
DISPATCH_CLIENT_CRASH(err, "Unexpected error from kevent");
|
|
@@ -786,9 +808,15 @@ _dispatch_kq_drain(dispatch_wlh_t wlh, dispatch_kevent
|
|
|
|
#if DISPATCH_DEBUG
|
|
for (r = 0; r < n; r++) {
|
|
+#ifdef EVFILT_USER
|
|
if (ke[r].filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
|
|
_dispatch_kevent_debug_n(NULL, ke + r, r, n);
|
|
}
|
|
+#else
|
|
+ if (DISPATCH_MGR_QUEUE_DEBUG) {
|
|
+ _dispatch_kevent_debug_n(NULL, ke + r, r, n);
|
|
+ }
|
|
+#endif
|
|
}
|
|
#endif
|
|
|
|
@@ -860,7 +888,6 @@ _dispatch_kq_unote_set_kevent(dispatch_unote_t _du, di
|
|
du->du_priority),
|
|
#endif
|
|
};
|
|
- (void)pp; // if DISPATCH_USE_KEVENT_QOS == 0
|
|
}
|
|
|
|
DISPATCH_ALWAYS_INLINE
|
|
@@ -921,9 +948,13 @@ _dispatch_kq_deferred_update(dispatch_wlh_t wlh, dispa
|
|
ke->udata);
|
|
dispatch_kevent_t dk = _dispatch_kq_deferred_reuse_slot(wlh, ddi, slot);
|
|
*dk = *ke;
|
|
+#ifdef EVFILT_USER
|
|
if (ke->filter != EVFILT_USER) {
|
|
_dispatch_kevent_mgr_debug("deferred", ke);
|
|
}
|
|
+#else
|
|
+ _dispatch_kevent_mgr_debug("deferred", ke);
|
|
+#endif
|
|
} else {
|
|
_dispatch_kq_update_one(wlh, ke);
|
|
}
|
|
@@ -985,6 +1016,7 @@ _dispatch_sync_ipc_handoff_end(dispatch_wlh_t wlh, mac
|
|
}
|
|
#endif
|
|
|
|
+#if DISPATCH_HAVE_DIRECT_KNOTES
|
|
DISPATCH_NOINLINE
|
|
static bool
|
|
_dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du,
|
|
@@ -1055,6 +1087,7 @@ done:
|
|
dispatch_assume_zero(r);
|
|
return true;
|
|
}
|
|
+#endif
|
|
|
|
#pragma mark dispatch_muxnote_t
|
|
|
|
@@ -1283,6 +1316,7 @@ _dispatch_unote_unregister_direct(dispatch_unote_t du,
|
|
#pragma mark -
|
|
#pragma mark dispatch_event_loop
|
|
|
|
+#if DISPATCH_USE_KEVENT_WORKLOOP
|
|
enum {
|
|
DISPATCH_WORKLOOP_ASYNC,
|
|
DISPATCH_WORKLOOP_ASYNC_FROM_SYNC,
|
|
@@ -1316,6 +1350,7 @@ static char const * const _dispatch_workloop_actions[]
|
|
[DISPATCH_WORKLOOP_SYNC_WAKE] = "sync-wake",
|
|
[DISPATCH_WORKLOOP_SYNC_END] = "sync-end",
|
|
};
|
|
+#endif
|
|
|
|
void
|
|
_dispatch_event_loop_atfork_child(void)
|
|
@@ -1410,7 +1445,7 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke,
|
|
switch (which) {
|
|
case DISPATCH_WORKLOOP_ASYNC_FROM_SYNC:
|
|
fflags |= NOTE_WL_END_OWNERSHIP;
|
|
- /* FALLTHROUGH */
|
|
+ DISPATCH_FALLTHROUGH;
|
|
case DISPATCH_WORKLOOP_ASYNC:
|
|
case DISPATCH_WORKLOOP_ASYNC_DISCOVER_SYNC:
|
|
case DISPATCH_WORKLOOP_ASYNC_QOS_UPDATE:
|
|
@@ -1434,10 +1469,10 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke,
|
|
|
|
case DISPATCH_WORKLOOP_ASYNC_LEAVE_FROM_SYNC:
|
|
fflags |= NOTE_WL_END_OWNERSHIP;
|
|
- /* FALLTHROUGH */
|
|
+ DISPATCH_FALLTHROUGH;
|
|
case DISPATCH_WORKLOOP_ASYNC_LEAVE_FROM_TRANSFER:
|
|
fflags |= NOTE_WL_IGNORE_ESTALE;
|
|
- /* FALLTHROUGH */
|
|
+ DISPATCH_FALLTHROUGH;
|
|
case DISPATCH_WORKLOOP_ASYNC_LEAVE:
|
|
dispatch_assert(!_dq_state_is_enqueued_on_target(dq_state));
|
|
action = EV_ADD | EV_DELETE | EV_ENABLE;
|
|
@@ -1881,10 +1916,17 @@ _dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t
|
|
{
|
|
if (wlh == DISPATCH_WLH_MANAGER) {
|
|
dispatch_kevent_s ke = (dispatch_kevent_s){
|
|
+#ifdef EVFILT_USER
|
|
.ident = 1,
|
|
.filter = EVFILT_USER,
|
|
.fflags = NOTE_TRIGGER,
|
|
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
|
|
+#else
|
|
+ .ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_MASK,
|
|
+ .filter = EVFILT_TIMER,
|
|
+ .flags = EV_ADD|EV_ENABLE,
|
|
+ .data = 1
|
|
+#endif
|
|
};
|
|
return _dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke);
|
|
} else if (wlh && wlh != DISPATCH_WLH_ANON) {
|
|
@@ -2357,6 +2399,12 @@ _dispatch_event_loop_timer_arm(dispatch_timer_heap_t d
|
|
target += range.leeway;
|
|
range.leeway = 0;
|
|
}
|
|
+#if !NOTE_ABSOLUTE
|
|
+ target = range.delay;
|
|
+#if defined(__OpenBSD__)
|
|
+ target /= 1000000;
|
|
+#endif
|
|
+#endif
|
|
|
|
_dispatch_event_loop_timer_program(dth, tidx, target, range.leeway,
|
|
EV_ADD | EV_ENABLE);
|
|
@@ -2445,6 +2493,7 @@ const dispatch_source_type_s _dispatch_source_type_vno
|
|
.dst_merge_evt = _dispatch_source_merge_evt,
|
|
};
|
|
|
|
+#ifdef EVFILT_FS
|
|
const dispatch_source_type_s _dispatch_source_type_vfs = {
|
|
.dst_kind = "vfs",
|
|
.dst_filter = EVFILT_FS,
|
|
@@ -2477,6 +2526,7 @@ const dispatch_source_type_s _dispatch_source_type_vfs
|
|
.dst_create = _dispatch_unote_create_without_handle,
|
|
.dst_merge_evt = _dispatch_source_merge_evt,
|
|
};
|
|
+#endif
|
|
|
|
#ifdef EVFILT_SOCK
|
|
const dispatch_source_type_s _dispatch_source_type_sock = {
|