-
Notifications
You must be signed in to change notification settings - Fork 470
Support OpenBSD. #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support OpenBSD. #559
Changes from all commits
1483bf0
99fce10
d37d2fa
fff4945
413ed24
3d7728e
05e05e9
18ffbd6
c4814ec
ce4ef87
937f309
207ed9e
f0f7799
04ab2a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -177,7 +177,7 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit); | |
|
||
#if TARGET_OS_MAC | ||
#define DISPATCH_COCOA_COMPAT 1 | ||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32) | ||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_WIN32) | ||
#define DISPATCH_COCOA_COMPAT 1 | ||
#else | ||
#define DISPATCH_COCOA_COMPAT 0 | ||
|
@@ -191,6 +191,8 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit); | |
typedef mach_port_t dispatch_runloop_handle_t; | ||
#elif defined(__linux__) || defined(__FreeBSD__) | ||
typedef int dispatch_runloop_handle_t; | ||
#elif defined(__unix__) && !defined(__linux__) && !defined(__FreeBSD__) | ||
typedef uint64_t dispatch_runloop_handle_t; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels a bit ... worrisome to me. If this ever gets re-ordered, we will have a subtle way to change the semantics. Currently There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The runloop implementation is POSIX-portable, it just uses pipe2; it is not OpenBSD-specific, hence the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding the conditional twice here is a little kludgy but I don't know if we want to refactor that further right now. |
||
#elif defined(_WIN32) | ||
typedef void *dispatch_runloop_handle_t; | ||
#else | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -792,7 +792,7 @@ static void | |
_dispatch_timer_unote_disarm(dispatch_timer_source_refs_t dt, | ||
dispatch_timer_heap_t dth) | ||
{ | ||
uint32_t tidx = dt->du_ident; | ||
uint32_t tidx = (uint32_t)dt->du_ident; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to worry about truncation? IIRC, a timer on Windows would be a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Casting here just suppresses the error. I don't think there is actually a problem here on looking how du_ident is used in this module; the 32-bit assumption is baked a little hard in the timer code and disentangling that should be handled separately. |
||
|
||
dispatch_assert(_dispatch_unote_armed(dt)); | ||
_dispatch_timer_heap_remove(&dth[tidx], dt); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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_kevent_s *kev, | |
|
||
#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,16 +392,18 @@ _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), | ||
!ke->udata ? NULL : | ||
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); | ||
compnerd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
|
@@ -528,11 +534,22 @@ _dispatch_kevent_merge_muxed(dispatch_kevent_t ke) | |
} | ||
} | ||
|
||
/* | ||
* If the kevent implementation doesn't support EVFILT_USER for | ||
* signaling, then we use EVFILT_TIMER with EV_ONESHOT with this ident | ||
* to make do. | ||
*/ | ||
#define DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT (~0ull << 9) | ||
|
||
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_IDENT) { | ||
#endif | ||
_dispatch_kevent_mgr_debug("received", ke); | ||
return; | ||
} | ||
|
@@ -579,10 +596,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_IDENT, | ||
.filter = EVFILT_TIMER, | ||
.flags = EV_ADD|EV_DISABLE|EV_ONESHOT, | ||
.data = 1, | ||
#endif | ||
}; | ||
int kqfd; | ||
|
||
|
@@ -591,7 +615,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) { | ||
|
@@ -743,7 +766,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n, | |
switch (err) { | ||
case ENOMEM: | ||
_dispatch_temporary_resource_shortage(); | ||
/* FALLTHROUGH */ | ||
DISPATCH_FALLTHROUGH; | ||
case EINTR: | ||
goto retry; | ||
case EBADF: | ||
|
@@ -754,7 +777,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n, | |
(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 +809,15 @@ _dispatch_kq_drain(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n, | |
|
||
#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 +889,6 @@ _dispatch_kq_unote_set_kevent(dispatch_unote_t _du, dispatch_kevent_t dk, | |
du->du_priority), | ||
#endif | ||
}; | ||
(void)pp; // if DISPATCH_USE_KEVENT_QOS == 0 | ||
} | ||
|
||
DISPATCH_ALWAYS_INLINE | ||
|
@@ -921,9 +949,13 @@ _dispatch_kq_deferred_update(dispatch_wlh_t wlh, dispatch_kevent_t ke) | |
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 +1017,7 @@ _dispatch_sync_ipc_handoff_end(dispatch_wlh_t wlh, mach_port_t port) | |
} | ||
#endif | ||
|
||
#if DISPATCH_HAVE_DIRECT_KNOTES | ||
DISPATCH_NOINLINE | ||
static bool | ||
_dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du, | ||
|
@@ -1055,6 +1088,7 @@ _dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du, | |
dispatch_assume_zero(r); | ||
return true; | ||
} | ||
#endif | ||
|
||
#pragma mark dispatch_muxnote_t | ||
|
||
|
@@ -1283,6 +1317,7 @@ _dispatch_unote_unregister_direct(dispatch_unote_t du, uint32_t flags) | |
#pragma mark - | ||
#pragma mark dispatch_event_loop | ||
|
||
#if DISPATCH_USE_KEVENT_WORKLOOP | ||
enum { | ||
DISPATCH_WORKLOOP_ASYNC, | ||
DISPATCH_WORKLOOP_ASYNC_FROM_SYNC, | ||
|
@@ -1316,6 +1351,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 +1446,7 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke, int which, | |
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 +1470,10 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke, int which, | |
|
||
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 +1917,17 @@ _dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t dq_state, uint32_t flags) | |
{ | ||
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_IDENT, | ||
.filter = EVFILT_TIMER, | ||
.flags = EV_ADD|EV_ENABLE|EV_ONESHOT, | ||
.data = 1 | ||
#endif | ||
}; | ||
return _dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke); | ||
} else if (wlh && wlh != DISPATCH_WLH_ANON) { | ||
|
@@ -2357,6 +2400,12 @@ _dispatch_event_loop_timer_arm(dispatch_timer_heap_t dth, uint32_t tidx, | |
target += range.leeway; | ||
range.leeway = 0; | ||
} | ||
#if !NOTE_ABSOLUTE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This won't be defined on all platforms (e.g. Windows). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but Windows is using src/event/event_windows.c. This entire file gets #ifdef'd out on Windows. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But, you can use the kevent backend on Windows with libkqueue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay, I've just changed this to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually -- that is wrong. NOTE_ABSOLUTE is defined in event_kevent.h, and is set to 0 if it is undefined. I'm going to go back to |
||
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 +2494,7 @@ const dispatch_source_type_s _dispatch_source_type_vnode = { | |
.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 +2527,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 = { | ||
|
Uh oh!
There was an error while loading. Please reload this page.