23
23
#include "protocol.h"
24
24
#endif
25
25
26
- #if defined(__linux__ )
27
- #include <sys/eventfd.h>
28
- #endif
29
-
30
26
#if (!HAVE_PTHREAD_WORKQUEUES || DISPATCH_DEBUG ) && \
31
27
!defined(DISPATCH_ENABLE_THREAD_POOL )
32
28
#define DISPATCH_ENABLE_THREAD_POOL 1
@@ -4067,6 +4063,46 @@ _dispatch_queue_wakeup(dispatch_queue_t dq, pthread_priority_t pp,
4067
4063
}
4068
4064
4069
4065
#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
+
4070
4106
void
4071
4107
_dispatch_runloop_queue_wakeup (dispatch_queue_t dq , pthread_priority_t pp ,
4072
4108
dispatch_wakeup_flags_t flags )
@@ -4127,12 +4163,13 @@ _dispatch_root_queue_wakeup(dispatch_queue_t dq,
4127
4163
static inline void
4128
4164
_dispatch_runloop_queue_class_poke (dispatch_queue_t dq )
4129
4165
{
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 )) {
4133
4168
return ;
4134
4169
}
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 );
4136
4173
switch (kr ) {
4137
4174
case MACH_SEND_TIMEOUT :
4138
4175
case MACH_SEND_TIMED_OUT :
@@ -4143,15 +4180,13 @@ _dispatch_runloop_queue_class_poke(dispatch_queue_t dq)
4143
4180
break ;
4144
4181
}
4145
4182
#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
4155
4190
#endif
4156
4191
}
4157
4192
@@ -5603,104 +5638,91 @@ _dispatch_runloop_root_queue_wakeup_4CF(dispatch_queue_t dq)
5603
5638
_dispatch_runloop_queue_wakeup (dq , 0 , false);
5604
5639
}
5605
5640
5606
- mach_port_t
5641
+ dispatch_runloop_handle_t
5607
5642
_dispatch_runloop_root_queue_get_port_4CF (dispatch_queue_t dq )
5608
5643
{
5609
5644
if (slowpath (dq -> do_vtable != DISPATCH_VTABLE (queue_runloop ))) {
5610
5645
DISPATCH_CLIENT_CRASH (dq -> do_vtable , "Not a runloop queue" );
5611
5646
}
5612
- return ( mach_port_t ) dq -> do_ctxt ;
5647
+ return _dispatch_runloop_queue_get_handle ( dq ) ;
5613
5648
}
5614
5649
5615
5650
static void
5616
5651
_dispatch_runloop_queue_handle_init (void * ctxt )
5617
5652
{
5618
5653
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 ;
5623
5655
5624
5656
_dispatch_fork_becomes_unsafe ();
5625
-
5657
+
5626
5658
#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 );
5628
5661
DISPATCH_VERIFY_MIG (kr );
5629
5662
(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 ,
5631
5664
MACH_MSG_TYPE_MAKE_SEND );
5632
5665
DISPATCH_VERIFY_MIG (kr );
5633
5666
(void )dispatch_assume_zero (kr );
5634
5667
if (dq != & _dispatch_main_q ) {
5635
5668
struct mach_port_limits limits = {
5636
5669
.mpl_qlimit = 1 ,
5637
5670
};
5638
- kr = mach_port_set_attributes (mach_task_self (), mp ,
5671
+ kr = mach_port_set_attributes (mach_task_self (), handle ,
5639
5672
MACH_PORT_LIMITS_INFO , (mach_port_info_t )& limits ,
5640
5673
sizeof (limits ));
5641
5674
DISPATCH_VERIFY_MIG (kr );
5642
5675
(void )dispatch_assume_zero (kr );
5643
5676
}
5644
- dq -> do_ctxt = (void * )(uintptr_t )mp ;
5645
5677
#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 );
5649
5679
#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 );
5652
5684
5653
5685
_dispatch_program_is_probably_callback_driven = true;
5654
5686
}
5655
5687
5656
5688
static void
5657
5689
_dispatch_runloop_queue_handle_dispose (dispatch_queue_t dq )
5658
5690
{
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 )) {
5662
5693
return ;
5663
5694
}
5664
5695
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 );
5666
5698
DISPATCH_VERIFY_MIG (kr );
5667
5699
(void )dispatch_assume_zero (kr );
5668
5700
kr = mach_port_mod_refs (mach_task_self (), mp , MACH_PORT_RIGHT_RECEIVE , -1 );
5669
5701
DISPATCH_VERIFY_MIG (kr );
5670
5702
(void )dispatch_assume_zero (kr );
5671
5703
#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 );
5678
5705
(void )dispatch_assume_zero (rc );
5706
+ #else
5707
+ #error
5679
5708
#endif
5680
5709
}
5681
5710
5682
5711
#pragma mark -
5683
5712
#pragma mark dispatch_main_queue
5684
5713
5714
+ dispatch_runloop_handle_t
5685
5715
#if TARGET_OS_MAC
5686
- mach_port_t
5687
5716
_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
- }
5694
5717
#else
5695
- dispatch_handle_t
5696
5718
_dispatch_get_main_queue_handle_4CF (void )
5719
+ #endif
5697
5720
{
5698
5721
dispatch_queue_t dq = & _dispatch_main_q ;
5699
5722
dispatch_once_f (& _dispatch_main_q_handle_pred , dq ,
5700
5723
_dispatch_runloop_queue_handle_init );
5701
- return ( dispatch_handle_t ) dq -> do_ctxt ;
5724
+ return _dispatch_runloop_queue_get_handle ( dq ) ;
5702
5725
}
5703
- #endif
5704
5726
5705
5727
static bool main_q_is_draining ;
5706
5728
@@ -5717,7 +5739,7 @@ void
5717
5739
#if TARGET_OS_MAC
5718
5740
_dispatch_main_queue_callback_4CF (mach_msg_header_t * msg DISPATCH_UNUSED )
5719
5741
#else
5720
- _dispatch_main_queue_callback_4CF ()
5742
+ _dispatch_main_queue_callback_4CF (void )
5721
5743
#endif
5722
5744
{
5723
5745
if (main_q_is_draining ) {
0 commit comments