@@ -4084,6 +4084,7 @@ _dispatch_runloop_queue_get_handle(dispatch_queue_t dq)
4084
4084
#if TARGET_OS_MAC
4085
4085
return ((dispatch_runloop_handle_t )(uintptr_t )dq -> do_ctxt );
4086
4086
#elif defined(__linux__ )
4087
+ // decode: 0 is a valid fd, so offset by 1 to distinguish from NULL
4087
4088
return ((dispatch_runloop_handle_t )(uintptr_t )dq -> do_ctxt ) - 1 ;
4088
4089
#else
4089
4090
#error "runloop support not implemented on this platform"
@@ -4097,6 +4098,7 @@ _dispatch_runloop_queue_set_handle(dispatch_queue_t dq, dispatch_runloop_handle_
4097
4098
#if TARGET_OS_MAC
4098
4099
dq -> do_ctxt = (void * )(uintptr_t )handle ;
4099
4100
#elif defined(__linux__ )
4101
+ // encode: 0 is a valid fd, so offset by 1 to distinguish from NULL
4100
4102
dq -> do_ctxt = (void * )(uintptr_t )(handle + 1 );
4101
4103
#else
4102
4104
#error "runloop support not implemented on this platform"
@@ -4169,7 +4171,8 @@ _dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
4169
4171
}
4170
4172
4171
4173
#if TARGET_OS_MAC
4172
- kern_return_t kr = _dispatch_send_wakeup_runloop_thread (handle , 0 );
4174
+ mach_port_t mp = handle ;
4175
+ kern_return_t kr = _dispatch_send_wakeup_runloop_thread (mp , 0 );
4173
4176
switch (kr ) {
4174
4177
case MACH_SEND_TIMEOUT :
4175
4178
case MACH_SEND_TIMED_OUT :
@@ -5656,30 +5659,52 @@ _dispatch_runloop_queue_handle_init(void *ctxt)
5656
5659
_dispatch_fork_becomes_unsafe ();
5657
5660
5658
5661
#if TARGET_OS_MAC
5662
+ mach_port_t mp ;
5659
5663
kern_return_t kr ;
5660
- kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE , & handle );
5664
+ kr = mach_port_allocate (mach_task_self (), MACH_PORT_RIGHT_RECEIVE , & mp );
5661
5665
DISPATCH_VERIFY_MIG (kr );
5662
5666
(void )dispatch_assume_zero (kr );
5663
- kr = mach_port_insert_right (mach_task_self (), handle , handle ,
5667
+ kr = mach_port_insert_right (mach_task_self (), mp , mp ,
5664
5668
MACH_MSG_TYPE_MAKE_SEND );
5665
5669
DISPATCH_VERIFY_MIG (kr );
5666
5670
(void )dispatch_assume_zero (kr );
5667
5671
if (dq != & _dispatch_main_q ) {
5668
5672
struct mach_port_limits limits = {
5669
5673
.mpl_qlimit = 1 ,
5670
5674
};
5671
- kr = mach_port_set_attributes (mach_task_self (), handle ,
5675
+ kr = mach_port_set_attributes (mach_task_self (), mp ,
5672
5676
MACH_PORT_LIMITS_INFO , (mach_port_info_t )& limits ,
5673
5677
sizeof (limits ));
5674
5678
DISPATCH_VERIFY_MIG (kr );
5675
5679
(void )dispatch_assume_zero (kr );
5676
5680
}
5681
+ handle = mp ;
5677
5682
#elif defined(__linux__ )
5678
- handle = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK );
5683
+ int fd = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK );
5684
+ if (fd == -1 ) {
5685
+ int err = errno ;
5686
+ switch (err ) {
5687
+ case EMFILE :
5688
+ DISPATCH_CLIENT_CRASH (err , "eventfd() failure: "
5689
+ "process is out of file descriptors" );
5690
+ break ;
5691
+ case ENFILE :
5692
+ DISPATCH_CLIENT_CRASH (err , "eventfd() failure: "
5693
+ "system is out of file descriptors" );
5694
+ break ;
5695
+ case ENOMEM :
5696
+ DISPATCH_CLIENT_CRASH (err , "eventfd() failure: "
5697
+ "kernel is out of memory" );
5698
+ break ;
5699
+ default :
5700
+ DISPATCH_INTERNAL_CRASH (err , "eventfd() failure" );
5701
+ break ;
5702
+ }
5703
+ }
5704
+ handle = fd ;
5679
5705
#else
5680
5706
#error "runloop support not implemented on this platform"
5681
5707
#endif
5682
- (void )dispatch_assume (_dispatch_runloop_handle_is_valid (handle ));
5683
5708
_dispatch_runloop_queue_set_handle (dq , handle );
5684
5709
5685
5710
_dispatch_program_is_probably_callback_driven = true;
@@ -5694,7 +5719,8 @@ _dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq)
5694
5719
}
5695
5720
dq -> do_ctxt = NULL ;
5696
5721
#if TARGET_OS_MAC
5697
- kern_return_t kr = mach_port_deallocate (mach_task_self (), hand );
5722
+ mach_port_t mp = handle ;
5723
+ kern_return_t kr = mach_port_deallocate (mach_task_self (), mp );
5698
5724
DISPATCH_VERIFY_MIG (kr );
5699
5725
(void )dispatch_assume_zero (kr );
5700
5726
kr = mach_port_mod_refs (mach_task_self (), mp , MACH_PORT_RIGHT_RECEIVE , -1 );
@@ -5712,18 +5738,22 @@ _dispatch_runloop_queue_handle_dispose(dispatch_queue_t dq)
5712
5738
#pragma mark dispatch_main_queue
5713
5739
5714
5740
dispatch_runloop_handle_t
5715
- #if TARGET_OS_MAC
5716
- _dispatch_get_main_queue_port_4CF (void )
5717
- #else
5718
5741
_dispatch_get_main_queue_handle_4CF (void )
5719
- #endif
5720
5742
{
5721
5743
dispatch_queue_t dq = & _dispatch_main_q ;
5722
5744
dispatch_once_f (& _dispatch_main_q_handle_pred , dq ,
5723
5745
_dispatch_runloop_queue_handle_init );
5724
5746
return _dispatch_runloop_queue_get_handle (dq );
5725
5747
}
5726
5748
5749
+ #if TARGET_OS_MAC
5750
+ dispatch_runloop_handle_t
5751
+ _dispatch_get_main_queue_port_4CF (void )
5752
+ {
5753
+ return _dispatch_get_main_queue_handle_4CF ();
5754
+ }
5755
+ #endif
5756
+
5727
5757
static bool main_q_is_draining ;
5728
5758
5729
5759
// 6618342 Contact the team that owns the Instrument DTrace probe before
@@ -5736,11 +5766,7 @@ _dispatch_queue_set_mainq_drain_state(bool arg)
5736
5766
}
5737
5767
5738
5768
void
5739
- #if TARGET_OS_MAC
5740
- _dispatch_main_queue_callback_4CF (mach_msg_header_t * msg DISPATCH_UNUSED )
5741
- #else
5742
- _dispatch_main_queue_callback_4CF (void )
5743
- #endif
5769
+ _dispatch_main_queue_callback_4CF (void * ignored DISPATCH_UNUSED )
5744
5770
{
5745
5771
if (main_q_is_draining ) {
5746
5772
return ;
0 commit comments