From 24906a0875c2d8441b94461520643c70a9c7d4ae Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sat, 12 Jan 2019 12:43:44 -0800 Subject: [PATCH 1/2] dispatch: add support for runloops on Windows This is used by the CoreFoundation port which is used by Foundation. Provide the functions so that we can build Foundation. The API change here matches the definition and declaration and has no impact on the ABI. --- private/private.h | 12 ++++++++---- src/CMakeLists.txt | 1 - src/queue.c | 26 ++++++++++++++++++++------ src/shims/generic_win_stubs.c | 24 ------------------------ 4 files changed, 28 insertions(+), 35 deletions(-) delete mode 100644 src/shims/generic_win_stubs.c diff --git a/private/private.h b/private/private.h index 7fba396e1..19ccccddb 100644 --- a/private/private.h +++ b/private/private.h @@ -182,7 +182,7 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit); #define DISPATCH_COCOA_COMPAT 0 #endif -#if DISPATCH_COCOA_COMPAT +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) #define DISPATCH_CF_SPI_VERSION 20160712 @@ -190,6 +190,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(_WIN32) +typedef void *dispatch_runloop_handle_t; #else #error "runloop support not implemented on this platform" #endif @@ -218,12 +220,14 @@ dispatch_queue_t _dispatch_runloop_root_queue_create_4CF(const char *_Nullable label, unsigned long flags); -#if TARGET_OS_MAC +#if TARGET_OS_MAC || defined(_WIN32) API_AVAILABLE(macos(10.9), ios(7.0)) DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW -mach_port_t +dispatch_runloop_handle_t _dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t queue); +#endif +#if TARGET_OS_MAC #ifdef __BLOCKS__ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT @@ -259,7 +263,7 @@ API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_EXPORT void (*_Nullable _dispatch_end_NSAutoReleasePool)(void *); -#endif /* DISPATCH_COCOA_COMPAT */ +#endif /* DISPATCH_COCOA_COMPAT || defined(_WIN32) */ API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) DISPATCH_EXPORT DISPATCH_NOTHROW diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4790ac6d9..4da1b3f15 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -63,7 +63,6 @@ if(WIN32) target_sources(dispatch PRIVATE shims/generic_sys_queue.h - shims/generic_win_stubs.c shims/generic_win_stubs.h shims/getprogname.c) endif() diff --git a/src/queue.c b/src/queue.c index b1b4458f9..adb1e1cca 100644 --- a/src/queue.c +++ b/src/queue.c @@ -93,10 +93,14 @@ _dispatch_worker_thread_thunk(LPVOID lpParameter); #endif #endif -#if DISPATCH_COCOA_COMPAT +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) static dispatch_once_t _dispatch_main_q_handle_pred; +#endif +#if DISPATCH_COCOA_COMPAT static void _dispatch_runloop_queue_poke(dispatch_queue_t dq, dispatch_qos_t qos, dispatch_wakeup_flags_t flags); +#endif +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) static void _dispatch_runloop_queue_handle_init(void *ctxt); static void _dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq); #endif @@ -4476,7 +4480,7 @@ _dispatch_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos, return _dispatch_queue_class_wakeup(dq, qos, flags, target); } -#if DISPATCH_COCOA_COMPAT +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) DISPATCH_ALWAYS_INLINE static inline bool _dispatch_runloop_handle_is_valid(dispatch_runloop_handle_t handle) @@ -4485,6 +4489,8 @@ _dispatch_runloop_handle_is_valid(dispatch_runloop_handle_t handle) return MACH_PORT_VALID(handle); #elif defined(__linux__) return handle >= 0; +#elif defined(_WIN32) + return handle != INVALID_HANDLE_VALUE; #else #error "runloop support not implemented on this platform" #endif @@ -4499,6 +4505,8 @@ _dispatch_runloop_queue_get_handle(dispatch_queue_t dq) #elif defined(__linux__) // decode: 0 is a valid fd, so offset by 1 to distinguish from NULL return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt) - 1; +#elif defined(_WIN32) + return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt); #else #error "runloop support not implemented on this platform" #endif @@ -4513,6 +4521,8 @@ _dispatch_runloop_queue_set_handle(dispatch_queue_t dq, dispatch_runloop_handle_ #elif defined(__linux__) // encode: 0 is a valid fd, so offset by 1 to distinguish from NULL dq->do_ctxt = (void *)(uintptr_t)(handle + 1); +#elif defined(_WIN32) + dq->do_ctxt = (void *)(uintptr_t)handle; #else #error "runloop support not implemented on this platform" #endif @@ -4527,7 +4537,7 @@ _dispatch_runloop_queue_reset_max_qos(dispatch_queue_class_t dqu) old_state = os_atomic_and_orig2o(dqu._dq, dq_state, ~clear_bits, relaxed); return _dq_state_max_qos(old_state); } -#endif // DISPATCH_COCOA_COMPAT +#endif void _dispatch_runloop_queue_wakeup(dispatch_queue_t dq, dispatch_qos_t qos, @@ -5112,7 +5122,7 @@ _dispatch_queue_serial_drain(dispatch_queue_t dq, dispatch_invoke_context_t dic, return _dispatch_queue_drain(dq, dic, flags, owned, true); } -#if DISPATCH_COCOA_COMPAT +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) DISPATCH_NOINLINE static void _dispatch_main_queue_update_priority_from_thread(void) @@ -6178,7 +6188,7 @@ _dispatch_network_root_queue_create_4NW(const char *label, static bool _dispatch_program_is_probably_callback_driven; -#if DISPATCH_COCOA_COMPAT +#if DISPATCH_COCOA_COMPAT || defined(_WIN32) dispatch_queue_t _dispatch_runloop_root_queue_create_4CF(const char *label, unsigned long flags) @@ -6242,7 +6252,7 @@ _dispatch_runloop_root_queue_wakeup_4CF(dispatch_queue_t dq) _dispatch_runloop_queue_wakeup(dq, 0, false); } -#if TARGET_OS_MAC +#if TARGET_OS_MAC || defined(_WIN32) dispatch_runloop_handle_t _dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t dq) { @@ -6305,6 +6315,8 @@ _dispatch_runloop_queue_handle_init(void *ctxt) } } handle = fd; +#elif defined(_WIN32) + handle = INVALID_HANDLE_VALUE; #else #error "runloop support not implemented on this platform" #endif @@ -6332,6 +6344,8 @@ _dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq) #elif defined(__linux__) int rc = close(handle); (void)dispatch_assume_zero(rc); +#elif defined(_WIN32) + CloseHandle(handle); #else #error "runloop support not implemented on this platform" #endif diff --git a/src/shims/generic_win_stubs.c b/src/shims/generic_win_stubs.c deleted file mode 100644 index 67b6f5134..000000000 --- a/src/shims/generic_win_stubs.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "internal.h" - -/* - * This file contains stubbed out functions we are using during - * the initial Windows port. When the port is complete, this file - * should be empty (and thus removed). - */ - -void -_dispatch_runloop_queue_dispose(dispatch_queue_t dq DISPATCH_UNUSED, - bool *allow_free DISPATCH_UNUSED) -{ - WIN_PORT_ERROR(); -} - -void -_dispatch_runloop_queue_xref_dispose(dispatch_queue_t dq DISPATCH_UNUSED) -{ - WIN_PORT_ERROR(); -} - -/* - * Stubbed out static data - */ From 85d08fa967d6b821769993ea9421b541c2325c36 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Sat, 12 Jan 2019 12:59:37 -0800 Subject: [PATCH 2/2] swift: export the `objc_retainAutoReleaseReturnValue` Export the stub that we provide for swift programs on Windows. This is used by CoreFoundation and thus is needed for the Foundation port on Windows. --- src/swift/DispatchStubs.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/swift/DispatchStubs.cc b/src/swift/DispatchStubs.cc index 594f66648..0625cc91f 100644 --- a/src/swift/DispatchStubs.cc +++ b/src/swift/DispatchStubs.cc @@ -13,7 +13,11 @@ #include #include +#if defined(__ELF__) || defined(__MACH__) || defined(__WASM__) #define DISPATCH_RUNTIME_STDLIB_INTERFACE __attribute__((__visibility__("default"))) +#else +#define DISPATCH_RUNTIME_STDLIB_INTERFACE __declspec(dllexport) +#endif #if USE_OBJC @protocol OS_dispatch_source; @@ -54,6 +58,7 @@ static void _dispatch_overlay_constructor() { #endif /* USE_OBJC */ #if !USE_OBJC +DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" void * objc_retainAutoreleasedReturnValue(void *obj); #endif