@@ -75,12 +75,18 @@ static void *_dispatch_worker_thread(void *context);
75
75
static int _dispatch_pthread_sigmask (int how , sigset_t * set , sigset_t * oset );
76
76
#endif
77
77
78
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
79
+ static dispatch_queue_t _dispatch_main_queue_wakeup (void );
78
80
#if DISPATCH_COCOA_COMPAT
79
81
static dispatch_once_t _dispatch_main_q_port_pred ;
80
- static dispatch_queue_t _dispatch_main_queue_wakeup (void );
81
82
unsigned long _dispatch_runloop_queue_wakeup (dispatch_queue_t dq );
82
83
static void _dispatch_runloop_queue_port_init (void * ctxt );
83
84
static void _dispatch_runloop_queue_port_dispose (dispatch_queue_t dq );
85
+ #elif DISPATCH_LINUX_COMPAT
86
+ static dispatch_once_t _dispatch_main_q_eventfd_pred ;
87
+ static void _dispatch_main_q_eventfd_init (void * ctxt );
88
+ static int main_q_eventfd = -1 ;
89
+ #endif
84
90
#endif
85
91
86
92
static void _dispatch_root_queues_init (void * context );
@@ -3466,6 +3472,7 @@ _dispatch_wakeup(dispatch_object_t dou)
3466
3472
// probe does
3467
3473
}
3468
3474
3475
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
3469
3476
#if DISPATCH_COCOA_COMPAT
3470
3477
static inline void
3471
3478
_dispatch_runloop_queue_wakeup_thread (dispatch_queue_t dq )
@@ -3493,6 +3500,7 @@ _dispatch_runloop_queue_wakeup(dispatch_queue_t dq)
3493
3500
_dispatch_runloop_queue_wakeup_thread (dq );
3494
3501
return false;
3495
3502
}
3503
+ #endif
3496
3504
3497
3505
DISPATCH_NOINLINE
3498
3506
static dispatch_queue_t
@@ -3502,9 +3510,21 @@ _dispatch_main_queue_wakeup(void)
3502
3510
if (!dq -> dq_is_thread_bound ) {
3503
3511
return NULL ;
3504
3512
}
3513
+ #if DISPATCH_COCOA_COMPAT
3505
3514
dispatch_once_f (& _dispatch_main_q_port_pred , dq ,
3506
3515
_dispatch_runloop_queue_port_init );
3507
3516
_dispatch_runloop_queue_wakeup_thread (dq );
3517
+ #elif DISPATCH_LINUX_COMPAT
3518
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , dq ,
3519
+ _dispatch_main_q_eventfd_init );
3520
+ if (main_q_eventfd != -1 ) {
3521
+ int result ;
3522
+ do {
3523
+ result = eventfd_write (main_q_eventfd , 1 );
3524
+ } while (result == -1 && errno == EINTR );
3525
+ (void )dispatch_assume_zero (result );
3526
+ }
3527
+ #endif
3508
3528
return NULL ;
3509
3529
}
3510
3530
#endif
@@ -3752,7 +3772,7 @@ _dispatch_queue_drain(dispatch_object_t dou)
3752
3772
return sema ;
3753
3773
}
3754
3774
3755
- #if DISPATCH_COCOA_COMPAT
3775
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
3756
3776
static void
3757
3777
_dispatch_main_queue_drain (void )
3758
3778
{
@@ -3803,6 +3823,7 @@ _dispatch_main_queue_drain(void)
3803
3823
_dispatch_force_cache_cleanup ();
3804
3824
}
3805
3825
3826
+ #if DISPATCH_COCOA_COMPAT
3806
3827
static bool
3807
3828
_dispatch_runloop_queue_drain_one (dispatch_queue_t dq )
3808
3829
{
@@ -3831,6 +3852,7 @@ _dispatch_runloop_queue_drain_one(dispatch_queue_t dq)
3831
3852
return next_dc ;
3832
3853
}
3833
3854
#endif
3855
+ #endif
3834
3856
3835
3857
DISPATCH_ALWAYS_INLINE_NDEBUG
3836
3858
static inline _dispatch_thread_semaphore_t
@@ -4485,10 +4507,24 @@ _dispatch_runloop_queue_port_dispose(dispatch_queue_t dq)
4485
4507
DISPATCH_VERIFY_MIG (kr );
4486
4508
(void )dispatch_assume_zero (kr );
4487
4509
}
4510
+ #endif
4488
4511
4489
4512
#pragma mark -
4490
4513
#pragma mark dispatch_main_queue
4491
4514
4515
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
4516
+ static bool main_q_is_draining ;
4517
+
4518
+ // 6618342 Contact the team that owns the Instrument DTrace probe before
4519
+ // renaming this symbol
4520
+ DISPATCH_NOINLINE
4521
+ static void
4522
+ _dispatch_queue_set_mainq_drain_state (bool arg )
4523
+ {
4524
+ main_q_is_draining = arg ;
4525
+ }
4526
+
4527
+ #if DISPATCH_COCOA_COMPAT
4492
4528
mach_port_t
4493
4529
_dispatch_get_main_queue_port_4CF (void )
4494
4530
{
@@ -4498,20 +4534,34 @@ _dispatch_get_main_queue_port_4CF(void)
4498
4534
return (mach_port_t )dq -> do_ctxt ;
4499
4535
}
4500
4536
4501
- static bool main_q_is_draining ;
4537
+ void
4538
+ _dispatch_main_queue_callback_4CF (mach_msg_header_t * msg DISPATCH_UNUSED )
4539
+ {
4540
+ if (main_q_is_draining ) {
4541
+ return ;
4542
+ }
4543
+ _dispatch_queue_set_mainq_drain_state (true);
4544
+ _dispatch_main_queue_drain ();
4545
+ _dispatch_queue_set_mainq_drain_state (false);
4546
+ }
4502
4547
4503
- // 6618342 Contact the team that owns the Instrument DTrace probe before
4504
- // renaming this symbol
4505
- DISPATCH_NOINLINE
4506
- static void
4507
- _dispatch_queue_set_mainq_drain_state (bool arg )
4548
+ #elif DISPATCH_LINUX_COMPAT
4549
+ int
4550
+ dispatch_get_main_queue_eventfd_4CF ()
4508
4551
{
4509
- main_q_is_draining = arg ;
4552
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , NULL ,
4553
+ _dispatch_main_q_eventfd_init );
4554
+ return main_q_eventfd ;
4510
4555
}
4511
4556
4512
4557
void
4513
- _dispatch_main_queue_callback_4CF ( mach_msg_header_t * msg DISPATCH_UNUSED )
4558
+ dispatch_main_queue_drain_4CF ( )
4514
4559
{
4560
+ if (!pthread_main_np ()) {
4561
+ DISPATCH_CLIENT_CRASH ("dispatch_main_queue_drain_np() must be called on "
4562
+ "the main thread" );
4563
+ }
4564
+
4515
4565
if (main_q_is_draining ) {
4516
4566
return ;
4517
4567
}
@@ -4520,6 +4570,15 @@ _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg DISPATCH_UNUSED)
4520
4570
_dispatch_queue_set_mainq_drain_state (false);
4521
4571
}
4522
4572
4573
+ static
4574
+ void _dispatch_main_q_eventfd_init (void * ctxt DISPATCH_UNUSED )
4575
+ {
4576
+ _dispatch_safe_fork = false;
4577
+ main_q_eventfd = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK );
4578
+ (void )dispatch_assume (main_q_eventfd != -1 );
4579
+ _dispatch_program_is_probably_callback_driven = true;
4580
+ }
4581
+ #endif
4523
4582
#endif
4524
4583
4525
4584
void
@@ -4585,6 +4644,15 @@ _dispatch_queue_cleanup2(void)
4585
4644
dispatch_once_f (& _dispatch_main_q_port_pred , dq ,
4586
4645
_dispatch_runloop_queue_port_init );
4587
4646
_dispatch_runloop_queue_port_dispose (dq );
4647
+ #elif DISPATCH_LINUX_COMPAT
4648
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , NULL ,
4649
+ _dispatch_main_q_eventfd_init );
4650
+ int fd = main_q_eventfd ;
4651
+ main_q_eventfd = -1 ;
4652
+
4653
+ if (fd != -1 ) {
4654
+ close (fd );
4655
+ }
4588
4656
#endif
4589
4657
}
4590
4658
0 commit comments