@@ -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 );
@@ -3468,6 +3474,7 @@ _dispatch_wakeup(dispatch_object_t dou)
3468
3474
// probe does
3469
3475
}
3470
3476
3477
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
3471
3478
#if DISPATCH_COCOA_COMPAT
3472
3479
static inline void
3473
3480
_dispatch_runloop_queue_wakeup_thread (dispatch_queue_t dq )
@@ -3495,6 +3502,7 @@ _dispatch_runloop_queue_wakeup(dispatch_queue_t dq)
3495
3502
_dispatch_runloop_queue_wakeup_thread (dq );
3496
3503
return false;
3497
3504
}
3505
+ #endif
3498
3506
3499
3507
DISPATCH_NOINLINE
3500
3508
static dispatch_queue_t
@@ -3504,9 +3512,21 @@ _dispatch_main_queue_wakeup(void)
3504
3512
if (!dq -> dq_is_thread_bound ) {
3505
3513
return NULL ;
3506
3514
}
3515
+ #if DISPATCH_COCOA_COMPAT
3507
3516
dispatch_once_f (& _dispatch_main_q_port_pred , dq ,
3508
3517
_dispatch_runloop_queue_port_init );
3509
3518
_dispatch_runloop_queue_wakeup_thread (dq );
3519
+ #elif DISPATCH_LINUX_COMPAT
3520
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , dq ,
3521
+ _dispatch_main_q_eventfd_init );
3522
+ if (main_q_eventfd != -1 ) {
3523
+ int result ;
3524
+ do {
3525
+ result = eventfd_write (main_q_eventfd , 1 );
3526
+ } while (result == -1 && errno == EINTR );
3527
+ (void )dispatch_assume_zero (result );
3528
+ }
3529
+ #endif
3510
3530
return NULL ;
3511
3531
}
3512
3532
#endif
@@ -3754,7 +3774,7 @@ _dispatch_queue_drain(dispatch_object_t dou)
3754
3774
return sema ;
3755
3775
}
3756
3776
3757
- #if DISPATCH_COCOA_COMPAT
3777
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
3758
3778
static void
3759
3779
_dispatch_main_queue_drain (void )
3760
3780
{
@@ -3805,6 +3825,7 @@ _dispatch_main_queue_drain(void)
3805
3825
_dispatch_force_cache_cleanup ();
3806
3826
}
3807
3827
3828
+ #if DISPATCH_COCOA_COMPAT
3808
3829
static bool
3809
3830
_dispatch_runloop_queue_drain_one (dispatch_queue_t dq )
3810
3831
{
@@ -3833,6 +3854,7 @@ _dispatch_runloop_queue_drain_one(dispatch_queue_t dq)
3833
3854
return next_dc ;
3834
3855
}
3835
3856
#endif
3857
+ #endif
3836
3858
3837
3859
DISPATCH_ALWAYS_INLINE_NDEBUG
3838
3860
static inline _dispatch_thread_semaphore_t
@@ -4487,10 +4509,24 @@ _dispatch_runloop_queue_port_dispose(dispatch_queue_t dq)
4487
4509
DISPATCH_VERIFY_MIG (kr );
4488
4510
(void )dispatch_assume_zero (kr );
4489
4511
}
4512
+ #endif
4490
4513
4491
4514
#pragma mark -
4492
4515
#pragma mark dispatch_main_queue
4493
4516
4517
+ #if DISPATCH_ENABLE_RUNLOOP_SUPPORT
4518
+ static bool main_q_is_draining ;
4519
+
4520
+ // 6618342 Contact the team that owns the Instrument DTrace probe before
4521
+ // renaming this symbol
4522
+ DISPATCH_NOINLINE
4523
+ static void
4524
+ _dispatch_queue_set_mainq_drain_state (bool arg )
4525
+ {
4526
+ main_q_is_draining = arg ;
4527
+ }
4528
+
4529
+ #if DISPATCH_COCOA_COMPAT
4494
4530
mach_port_t
4495
4531
_dispatch_get_main_queue_port_4CF (void )
4496
4532
{
@@ -4500,20 +4536,34 @@ _dispatch_get_main_queue_port_4CF(void)
4500
4536
return (mach_port_t )dq -> do_ctxt ;
4501
4537
}
4502
4538
4503
- static bool main_q_is_draining ;
4539
+ void
4540
+ _dispatch_main_queue_callback_4CF (mach_msg_header_t * msg DISPATCH_UNUSED )
4541
+ {
4542
+ if (main_q_is_draining ) {
4543
+ return ;
4544
+ }
4545
+ _dispatch_queue_set_mainq_drain_state (true);
4546
+ _dispatch_main_queue_drain ();
4547
+ _dispatch_queue_set_mainq_drain_state (false);
4548
+ }
4504
4549
4505
- // 6618342 Contact the team that owns the Instrument DTrace probe before
4506
- // renaming this symbol
4507
- DISPATCH_NOINLINE
4508
- static void
4509
- _dispatch_queue_set_mainq_drain_state (bool arg )
4550
+ #elif DISPATCH_LINUX_COMPAT
4551
+ int
4552
+ dispatch_get_main_queue_eventfd_4CF ()
4510
4553
{
4511
- main_q_is_draining = arg ;
4554
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , NULL ,
4555
+ _dispatch_main_q_eventfd_init );
4556
+ return main_q_eventfd ;
4512
4557
}
4513
4558
4514
4559
void
4515
- _dispatch_main_queue_callback_4CF ( mach_msg_header_t * msg DISPATCH_UNUSED )
4560
+ dispatch_main_queue_drain_4CF ( )
4516
4561
{
4562
+ if (!pthread_main_np ()) {
4563
+ DISPATCH_CLIENT_CRASH ("dispatch_main_queue_drain_np() must be called on "
4564
+ "the main thread" );
4565
+ }
4566
+
4517
4567
if (main_q_is_draining ) {
4518
4568
return ;
4519
4569
}
@@ -4522,6 +4572,15 @@ _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg DISPATCH_UNUSED)
4522
4572
_dispatch_queue_set_mainq_drain_state (false);
4523
4573
}
4524
4574
4575
+ static
4576
+ void _dispatch_main_q_eventfd_init (void * ctxt DISPATCH_UNUSED )
4577
+ {
4578
+ _dispatch_safe_fork = false;
4579
+ main_q_eventfd = eventfd (0 , EFD_CLOEXEC | EFD_NONBLOCK );
4580
+ (void )dispatch_assume (main_q_eventfd != -1 );
4581
+ _dispatch_program_is_probably_callback_driven = true;
4582
+ }
4583
+ #endif
4525
4584
#endif
4526
4585
4527
4586
void
@@ -4587,6 +4646,15 @@ _dispatch_queue_cleanup2(void)
4587
4646
dispatch_once_f (& _dispatch_main_q_port_pred , dq ,
4588
4647
_dispatch_runloop_queue_port_init );
4589
4648
_dispatch_runloop_queue_port_dispose (dq );
4649
+ #elif DISPATCH_LINUX_COMPAT
4650
+ dispatch_once_f (& _dispatch_main_q_eventfd_pred , NULL ,
4651
+ _dispatch_main_q_eventfd_init );
4652
+ int fd = main_q_eventfd ;
4653
+ main_q_eventfd = -1 ;
4654
+
4655
+ if (fd != -1 ) {
4656
+ close (fd );
4657
+ }
4590
4658
#endif
4591
4659
}
4592
4660
0 commit comments