Skip to content

Commit ea57ecb

Browse files
committed
first cut at updating CF runloop changes for linux
1 parent 2dbf83c commit ea57ecb

File tree

3 files changed

+84
-33
lines changed

3 files changed

+84
-33
lines changed

private/private.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,22 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
166166
* SPI for CoreFoundation/Foundation ONLY
167167
*/
168168

169-
#define DISPATCH_COCOA_COMPAT (TARGET_OS_MAC || TARGET_OS_WIN32)
169+
#if (TARGET_OS_MAC || TARGET_OS_WIN32)
170+
#define DISPATCH_COCOA_COMPAT 1
171+
#elif defined(__linux__)
172+
#define DISPATCH_COCOA_COMPAT 1
173+
#else
174+
#define DISPATCH_COCOA_COMPAT 0
175+
#endif
170176

171177
#if DISPATCH_COCOA_COMPAT
172178

179+
#if TARGET_OS_WIN32
180+
typedef HANDLE dispatch_handle_t;
181+
#elif defined(__linux__)
182+
typedef int dispatch_handle_t;
183+
#endif
184+
173185
#if TARGET_OS_MAC
174186
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
175187
DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
@@ -180,17 +192,17 @@ __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
180192
DISPATCH_EXPORT DISPATCH_NOTHROW
181193
void
182194
_dispatch_main_queue_callback_4CF(mach_msg_header_t *_Null_unspecified msg);
183-
#elif TARGET_OS_WIN32
195+
#elif (TARGET_OS_WIN32 || defined(__linux__))
184196
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
185197
DISPATCH_EXPORT DISPATCH_NOTHROW
186-
HANDLE
198+
dispatch_handle_t
187199
_dispatch_get_main_queue_handle_4CF(void);
188200

189201
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
190202
DISPATCH_EXPORT DISPATCH_NOTHROW
191203
void
192204
_dispatch_main_queue_callback_4CF(void);
193-
#endif // TARGET_OS_WIN32
205+
#endif
194206

195207
__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0)
196208
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT

src/queue.c

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "protocol.h"
2424
#endif
2525

26+
#if defined(__linux__)
27+
#include <sys/eventfd.h>
28+
#endif
29+
2630
#if (!HAVE_PTHREAD_WORKQUEUES || DISPATCH_DEBUG) && \
2731
!defined(DISPATCH_ENABLE_THREAD_POOL)
2832
#define DISPATCH_ENABLE_THREAD_POOL 1
@@ -74,11 +78,11 @@ static int _dispatch_pthread_sigmask(int how, sigset_t *set, sigset_t *oset);
7478
#endif
7579

7680
#if DISPATCH_COCOA_COMPAT
77-
static dispatch_once_t _dispatch_main_q_port_pred;
81+
static dispatch_once_t _dispatch_main_q_handle_pred;
7882
static void _dispatch_runloop_queue_poke(dispatch_queue_t dq,
7983
pthread_priority_t pp, dispatch_wakeup_flags_t flags);
80-
static void _dispatch_runloop_queue_port_init(void *ctxt);
81-
static void _dispatch_runloop_queue_port_dispose(dispatch_queue_t dq);
84+
static void _dispatch_runloop_queue_handle_init(void *ctxt);
85+
static void _dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq);
8286
#endif
8387

8488
static void _dispatch_root_queues_init_once(void *context);
@@ -4090,13 +4094,6 @@ _dispatch_runloop_queue_wakeup(dispatch_queue_t dq, pthread_priority_t pp,
40904094
return _dispatch_release_tailcall(dq);
40914095
}
40924096
}
4093-
#else
4094-
void
4095-
_dispatch_runloop_queue_wakeup(dispatch_queue_t dq, pthread_priority_t pp,
4096-
dispatch_wakeup_flags_t flags)
4097-
{
4098-
LINUX_PORT_ERROR();
4099-
}
41004097
#endif
41014098

41024099
void
@@ -4130,6 +4127,7 @@ _dispatch_root_queue_wakeup(dispatch_queue_t dq,
41304127
static inline void
41314128
_dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
41324129
{
4130+
#if TARGET_OS_MAC
41334131
mach_port_t mp = (mach_port_t)dq->do_ctxt;
41344132
if (!mp) {
41354133
return;
@@ -4144,6 +4142,17 @@ _dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
41444142
(void)dispatch_assume_zero(kr);
41454143
break;
41464144
}
4145+
#elif defined(__linux__)
4146+
int efd = (int)dq->do_ctxt;
4147+
4148+
if (efd != 0) {
4149+
int result;
4150+
do {
4151+
result = eventfd_write(efd, 1);
4152+
} while (result == -1 && errno == EINTR);
4153+
(void)dispatch_assume_zero(result);
4154+
}
4155+
#endif
41474156
}
41484157

41494158
DISPATCH_NOINLINE
@@ -4158,8 +4167,8 @@ _dispatch_runloop_queue_poke(dispatch_queue_t dq,
41584167
// or in _dispatch_queue_cleanup2() for the main thread.
41594168

41604169
if (dq == &_dispatch_main_q) {
4161-
dispatch_once_f(&_dispatch_main_q_port_pred, dq,
4162-
_dispatch_runloop_queue_port_init);
4170+
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
4171+
_dispatch_runloop_queue_handle_init);
41634172
}
41644173
_dispatch_queue_override_priority(dq, /* inout */ &pp, /* inout */ &flags);
41654174
if (flags & DISPATCH_WAKEUP_OVERRIDING) {
@@ -4501,8 +4510,8 @@ _dispatch_main_queue_drain(void)
45014510
" from the wrong thread");
45024511
}
45034512

4504-
dispatch_once_f(&_dispatch_main_q_port_pred, dq,
4505-
_dispatch_runloop_queue_port_init);
4513+
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
4514+
_dispatch_runloop_queue_handle_init);
45064515

45074516
_dispatch_perfmon_start();
45084517
// <rdar://problem/23256682> hide the frame chaining when CFRunLoop
@@ -5547,7 +5556,7 @@ _dispatch_runloop_root_queue_create_4CF(const char *label, unsigned long flags)
55475556
_dispatch_queue_init(dq, DQF_THREAD_BOUND | DQF_CANNOT_TRYSYNC, 1, false);
55485557
dq->do_targetq = _dispatch_get_root_queue(_DISPATCH_QOS_CLASS_DEFAULT,true);
55495558
dq->dq_label = label ? label : "runloop-queue"; // no-copy contract
5550-
_dispatch_runloop_queue_port_init(dq);
5559+
_dispatch_runloop_queue_handle_init(dq);
55515560
_dispatch_queue_set_bound_thread(dq);
55525561
_dispatch_object_debug(dq, "%s", __func__);
55535562
return _dispatch_introspection_queue_create(dq);
@@ -5569,7 +5578,7 @@ _dispatch_runloop_queue_dispose(dispatch_queue_t dq)
55695578
{
55705579
_dispatch_object_debug(dq, "%s", __func__);
55715580
_dispatch_introspection_queue_dispose(dq);
5572-
_dispatch_runloop_queue_port_dispose(dq);
5581+
_dispatch_runloop_queue_handle_dispose(dq);
55735582
_dispatch_queue_destroy(dq);
55745583
}
55755584

@@ -5604,13 +5613,17 @@ _dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t dq)
56045613
}
56055614

56065615
static void
5607-
_dispatch_runloop_queue_port_init(void *ctxt)
5616+
_dispatch_runloop_queue_handle_init(void *ctxt)
56085617
{
56095618
dispatch_queue_t dq = (dispatch_queue_t)ctxt;
5619+
#if TARGET_OS_MAC
56105620
mach_port_t mp;
56115621
kern_return_t kr;
5622+
#endif
56125623

56135624
_dispatch_fork_becomes_unsafe();
5625+
5626+
#if TARGET_OS_MAC
56145627
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
56155628
DISPATCH_VERIFY_MIG(kr);
56165629
(void)dispatch_assume_zero(kr);
@@ -5629,13 +5642,21 @@ _dispatch_runloop_queue_port_init(void *ctxt)
56295642
(void)dispatch_assume_zero(kr);
56305643
}
56315644
dq->do_ctxt = (void*)(uintptr_t)mp;
5645+
#elif defined(__linux__)
5646+
int efd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
5647+
(void)dispatch_assume(efd != 0);
5648+
dq->do_ctxt = (void*)(uintptr_t)efd;
5649+
#else
5650+
#error "not implemented for this platform"
5651+
#endif
56325652

56335653
_dispatch_program_is_probably_callback_driven = true;
56345654
}
56355655

56365656
static void
5637-
_dispatch_runloop_queue_port_dispose(dispatch_queue_t dq)
5657+
_dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq)
56385658
{
5659+
#if TARGET_OS_MAC
56395660
mach_port_t mp = (mach_port_t)dq->do_ctxt;
56405661
if (!mp) {
56415662
return;
@@ -5647,19 +5668,39 @@ _dispatch_runloop_queue_port_dispose(dispatch_queue_t dq)
56475668
kr = mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1);
56485669
DISPATCH_VERIFY_MIG(kr);
56495670
(void)dispatch_assume_zero(kr);
5671+
#elif defined(__linux__)
5672+
int efd = (int)dq->do_ctxt;
5673+
if (!efd) {
5674+
return;
5675+
}
5676+
dq->do_ctxt = NULL;
5677+
int rc = close(efd);
5678+
(void)dispatch_assume_zero(rc);
5679+
#endif
56505680
}
56515681

56525682
#pragma mark -
56535683
#pragma mark dispatch_main_queue
56545684

5685+
#if TARGET_OS_MAC
56555686
mach_port_t
56565687
_dispatch_get_main_queue_port_4CF(void)
56575688
{
56585689
dispatch_queue_t dq = &_dispatch_main_q;
5659-
dispatch_once_f(&_dispatch_main_q_port_pred, dq,
5660-
_dispatch_runloop_queue_port_init);
5690+
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
5691+
_dispatch_runloop_queue_handle_init);
56615692
return (mach_port_t)dq->do_ctxt;
56625693
}
5694+
#else
5695+
dispatch_handle_t
5696+
_dispatch_get_main_queue_handle_4CF(void)
5697+
{
5698+
dispatch_queue_t dq = &_dispatch_main_q;
5699+
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
5700+
_dispatch_runloop_queue_handle_init);
5701+
return (dispatch_handle_t)dq->do_ctxt;
5702+
}
5703+
#endif
56635704

56645705
static bool main_q_is_draining;
56655706

@@ -5673,7 +5714,11 @@ _dispatch_queue_set_mainq_drain_state(bool arg)
56735714
}
56745715

56755716
void
5717+
#if TARGET_OS_MAC
56765718
_dispatch_main_queue_callback_4CF(mach_msg_header_t *msg DISPATCH_UNUSED)
5719+
#else
5720+
_dispatch_main_queue_callback_4CF()
5721+
#endif
56775722
{
56785723
if (main_q_is_draining) {
56795724
return;
@@ -5798,9 +5843,9 @@ _dispatch_queue_cleanup2(void)
57985843
#endif
57995844

58005845
#if DISPATCH_COCOA_COMPAT
5801-
dispatch_once_f(&_dispatch_main_q_port_pred, dq,
5802-
_dispatch_runloop_queue_port_init);
5803-
_dispatch_runloop_queue_port_dispose(dq);
5846+
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
5847+
_dispatch_runloop_queue_handle_init);
5848+
_dispatch_runloop_queue_handle_dispose(dq);
58045849
#endif
58055850
}
58065851

src/shims/linux_stubs.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@
3333
#undef LINUX_PORT_ERROR
3434
#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); abort(); } while (0)
3535

36-
unsigned long _dispatch_runloop_queue_probe(dispatch_queue_t dq) {
37-
LINUX_PORT_ERROR();
38-
}
39-
void _dispatch_runloop_queue_xref_dispose() { LINUX_PORT_ERROR(); }
40-
41-
void _dispatch_runloop_queue_dispose() { LINUX_PORT_ERROR(); }
4236

4337
/*
4438
* Stubbed out static data

0 commit comments

Comments
 (0)