Skip to content

Commit 13fa3c2

Browse files
committed
improve based on feedback from first round of review.
1 parent ea57ecb commit 13fa3c2

File tree

3 files changed

+87
-60
lines changed

3 files changed

+87
-60
lines changed

private/private.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,28 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
176176

177177
#if DISPATCH_COCOA_COMPAT
178178

179-
#if TARGET_OS_WIN32
180-
typedef HANDLE dispatch_handle_t;
179+
#if TARGET_OS_MAC
180+
typedef mach_port_t dispatch_runloop_handle_t;
181181
#elif defined(__linux__)
182-
typedef int dispatch_handle_t;
182+
typedef int dispatch_runloop_handle_t;
183+
#else
184+
#error
183185
#endif
184186

185187
#if TARGET_OS_MAC
186188
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
187189
DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
188-
mach_port_t
190+
dispatch_runloop_handle_t
189191
_dispatch_get_main_queue_port_4CF(void);
190192

191193
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
192194
DISPATCH_EXPORT DISPATCH_NOTHROW
193195
void
194196
_dispatch_main_queue_callback_4CF(mach_msg_header_t *_Null_unspecified msg);
195-
#elif (TARGET_OS_WIN32 || defined(__linux__))
197+
#else
196198
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)
197199
DISPATCH_EXPORT DISPATCH_NOTHROW
198-
dispatch_handle_t
200+
dispatch_runloop_handle_t
199201
_dispatch_get_main_queue_handle_4CF(void);
200202

201203
__OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_4_0)

src/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ DISPATCH_EXPORT DISPATCH_NOTHROW void dispatch_atfork_child(void);
251251
#include <sys/mman.h>
252252
#include <netinet/in.h>
253253
#endif
254+
#if defined(__linux__)
255+
#include <sys/eventfd.h>
256+
#endif
254257

255258
#ifdef __BLOCKS__
256259
#include <Block_private.h>

src/queue.c

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

26-
#if defined(__linux__)
27-
#include <sys/eventfd.h>
28-
#endif
29-
3026
#if (!HAVE_PTHREAD_WORKQUEUES || DISPATCH_DEBUG) && \
3127
!defined(DISPATCH_ENABLE_THREAD_POOL)
3228
#define DISPATCH_ENABLE_THREAD_POOL 1
@@ -4067,6 +4063,46 @@ _dispatch_queue_wakeup(dispatch_queue_t dq, pthread_priority_t pp,
40674063
}
40684064

40694065
#if DISPATCH_COCOA_COMPAT
4066+
4067+
DISPATCH_ALWAYS_INLINE
4068+
static inline bool
4069+
_dispatch_runloop_handle_is_valid(dispatch_runloop_handle_t handle)
4070+
{
4071+
#if TARGET_OS_MAC
4072+
return MACH_PORT_VALID(handle);
4073+
#elif defined(__linux__)
4074+
return handle >= 0;
4075+
#else
4076+
#error
4077+
#endif
4078+
}
4079+
4080+
DISPATCH_ALWAYS_INLINE
4081+
static inline dispatch_runloop_handle_t
4082+
_dispatch_runloop_queue_get_handle(dispatch_queue_t dq)
4083+
{
4084+
#if TARGET_OS_MAC
4085+
return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt);
4086+
#elif defined(__linux__)
4087+
return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt) - 1;
4088+
#else
4089+
#error
4090+
#endif
4091+
}
4092+
4093+
DISPATCH_ALWAYS_INLINE
4094+
static inline void
4095+
_dispatch_runloop_queue_set_handle(dispatch_queue_t dq, dispatch_runloop_handle_t handle)
4096+
{
4097+
#if TARGET_OS_MAC
4098+
dq->do_ctxt = (void *)(uintptr_t)handle;
4099+
#elif defined(__linux__)
4100+
dq->do_ctxt = (void *)(uintptr_t)(handle + 1);
4101+
#else
4102+
#error
4103+
#endif
4104+
}
4105+
40704106
void
40714107
_dispatch_runloop_queue_wakeup(dispatch_queue_t dq, pthread_priority_t pp,
40724108
dispatch_wakeup_flags_t flags)
@@ -4127,12 +4163,13 @@ _dispatch_root_queue_wakeup(dispatch_queue_t dq,
41274163
static inline void
41284164
_dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
41294165
{
4130-
#if TARGET_OS_MAC
4131-
mach_port_t mp = (mach_port_t)dq->do_ctxt;
4132-
if (!mp) {
4166+
dispatch_runloop_handle_t handle = _dispatch_runloop_queue_get_handle(dq);
4167+
if (!_dispatch_runloop_handle_is_valid(handle)) {
41334168
return;
41344169
}
4135-
kern_return_t kr = _dispatch_send_wakeup_runloop_thread(mp, 0);
4170+
4171+
#if TARGET_OS_MAC
4172+
kern_return_t kr = _dispatch_send_wakeup_runloop_thread(handle, 0);
41364173
switch (kr) {
41374174
case MACH_SEND_TIMEOUT:
41384175
case MACH_SEND_TIMED_OUT:
@@ -4143,15 +4180,13 @@ _dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
41434180
break;
41444181
}
41454182
#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-
}
4183+
int result;
4184+
do {
4185+
result = eventfd_write(handle, 1);
4186+
} while (result == -1 && errno == EINTR);
4187+
(void)dispatch_assume_zero(result);
4188+
#else
4189+
#error
41554190
#endif
41564191
}
41574192

@@ -5603,104 +5638,91 @@ _dispatch_runloop_root_queue_wakeup_4CF(dispatch_queue_t dq)
56035638
_dispatch_runloop_queue_wakeup(dq, 0, false);
56045639
}
56055640

5606-
mach_port_t
5641+
dispatch_runloop_handle_t
56075642
_dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t dq)
56085643
{
56095644
if (slowpath(dq->do_vtable != DISPATCH_VTABLE(queue_runloop))) {
56105645
DISPATCH_CLIENT_CRASH(dq->do_vtable, "Not a runloop queue");
56115646
}
5612-
return (mach_port_t)dq->do_ctxt;
5647+
return _dispatch_runloop_queue_get_handle(dq);
56135648
}
56145649

56155650
static void
56165651
_dispatch_runloop_queue_handle_init(void *ctxt)
56175652
{
56185653
dispatch_queue_t dq = (dispatch_queue_t)ctxt;
5619-
#if TARGET_OS_MAC
5620-
mach_port_t mp;
5621-
kern_return_t kr;
5622-
#endif
5654+
dispatch_runloop_handle_t handle;
56235655

56245656
_dispatch_fork_becomes_unsafe();
5625-
5657+
56265658
#if TARGET_OS_MAC
5627-
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
5659+
kern_return_t kr;
5660+
kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &handle);
56285661
DISPATCH_VERIFY_MIG(kr);
56295662
(void)dispatch_assume_zero(kr);
5630-
kr = mach_port_insert_right(mach_task_self(), mp, mp,
5663+
kr = mach_port_insert_right(mach_task_self(), handle, handle,
56315664
MACH_MSG_TYPE_MAKE_SEND);
56325665
DISPATCH_VERIFY_MIG(kr);
56335666
(void)dispatch_assume_zero(kr);
56345667
if (dq != &_dispatch_main_q) {
56355668
struct mach_port_limits limits = {
56365669
.mpl_qlimit = 1,
56375670
};
5638-
kr = mach_port_set_attributes(mach_task_self(), mp,
5671+
kr = mach_port_set_attributes(mach_task_self(), handle,
56395672
MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits,
56405673
sizeof(limits));
56415674
DISPATCH_VERIFY_MIG(kr);
56425675
(void)dispatch_assume_zero(kr);
56435676
}
5644-
dq->do_ctxt = (void*)(uintptr_t)mp;
56455677
#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;
5678+
handle = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
56495679
#else
5650-
#error "not implemented for this platform"
5651-
#endif
5680+
#error
5681+
#endif
5682+
(void)dispatch_assume(_dispatch_runloop_handle_is_valid(handle));
5683+
_dispatch_runloop_queue_set_handle(dq, handle);
56525684

56535685
_dispatch_program_is_probably_callback_driven = true;
56545686
}
56555687

56565688
static void
56575689
_dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq)
56585690
{
5659-
#if TARGET_OS_MAC
5660-
mach_port_t mp = (mach_port_t)dq->do_ctxt;
5661-
if (!mp) {
5691+
dispatch_runloop_handle_t handle = _dispatch_runloop_queue_get_handle(dq);
5692+
if (!_dispatch_runloop_handle_is_valid(handle)) {
56625693
return;
56635694
}
56645695
dq->do_ctxt = NULL;
5665-
kern_return_t kr = mach_port_deallocate(mach_task_self(), mp);
5696+
#if TARGET_OS_MAC
5697+
kern_return_t kr = mach_port_deallocate(mach_task_self(), hand);
56665698
DISPATCH_VERIFY_MIG(kr);
56675699
(void)dispatch_assume_zero(kr);
56685700
kr = mach_port_mod_refs(mach_task_self(), mp, MACH_PORT_RIGHT_RECEIVE, -1);
56695701
DISPATCH_VERIFY_MIG(kr);
56705702
(void)dispatch_assume_zero(kr);
56715703
#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);
5704+
int rc = close(handle);
56785705
(void)dispatch_assume_zero(rc);
5706+
#else
5707+
#error
56795708
#endif
56805709
}
56815710

56825711
#pragma mark -
56835712
#pragma mark dispatch_main_queue
56845713

5714+
dispatch_runloop_handle_t
56855715
#if TARGET_OS_MAC
5686-
mach_port_t
56875716
_dispatch_get_main_queue_port_4CF(void)
5688-
{
5689-
dispatch_queue_t dq = &_dispatch_main_q;
5690-
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
5691-
_dispatch_runloop_queue_handle_init);
5692-
return (mach_port_t)dq->do_ctxt;
5693-
}
56945717
#else
5695-
dispatch_handle_t
56965718
_dispatch_get_main_queue_handle_4CF(void)
5719+
#endif
56975720
{
56985721
dispatch_queue_t dq = &_dispatch_main_q;
56995722
dispatch_once_f(&_dispatch_main_q_handle_pred, dq,
57005723
_dispatch_runloop_queue_handle_init);
5701-
return (dispatch_handle_t)dq->do_ctxt;
5724+
return _dispatch_runloop_queue_get_handle(dq);
57025725
}
5703-
#endif
57045726

57055727
static bool main_q_is_draining;
57065728

@@ -5717,7 +5739,7 @@ void
57175739
#if TARGET_OS_MAC
57185740
_dispatch_main_queue_callback_4CF(mach_msg_header_t *msg DISPATCH_UNUSED)
57195741
#else
5720-
_dispatch_main_queue_callback_4CF()
5742+
_dispatch_main_queue_callback_4CF(void)
57215743
#endif
57225744
{
57235745
if (main_q_is_draining) {

0 commit comments

Comments
 (0)