@@ -426,6 +426,7 @@ pthread_mutex_t in_signal_lock; // shared with jl_delete_thread
426
426
static bt_context_t * signal_context ; // protected by in_signal_lock
427
427
static int exit_signal_cond = -1 ;
428
428
static int signal_caught_cond = -1 ;
429
+ static int signals_inflight = 0 ;
429
430
430
431
int jl_thread_suspend_and_get_state (int tid , int timeout , bt_context_t * ctx )
431
432
{
@@ -438,7 +439,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
438
439
pthread_mutex_unlock (& in_signal_lock );
439
440
return 0 ;
440
441
}
441
- if ( jl_atomic_load ( & ptls2 -> signal_request ) != 0 ) {
442
+ while ( signals_inflight ) {
442
443
// something is wrong, or there is already a usr2 in flight elsewhere
443
444
// try to wait for it to finish or wait for timeout
444
445
struct pollfd event = {signal_caught_cond , POLLIN , 0 };
@@ -450,25 +451,16 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
450
451
pthread_mutex_unlock (& in_signal_lock );
451
452
return 0 ;
452
453
}
453
- }
454
- // check for any stale signal_caught_cond events
455
- struct pollfd event = {signal_caught_cond , POLLIN , 0 };
456
- do {
457
- err = poll (& event , 1 , 0 );
458
- } while (err == -1 && errno == EINTR );
459
- if (err == -1 ) {
460
- pthread_mutex_unlock (& in_signal_lock );
461
- return 0 ;
462
- }
463
- if ((event .revents & POLLIN ) != 0 ) {
464
454
// consume it before continuing
465
455
eventfd_t got ;
466
456
do {
467
457
err = read (signal_caught_cond , & got , sizeof (eventfd_t ));
468
458
} while (err == -1 && errno == EINTR );
469
459
if (err != sizeof (eventfd_t )) abort ();
470
- assert (got == 1 ); (void ) got ;
460
+ assert (signals_inflight >= got );
461
+ signals_inflight -= got ;
471
462
}
463
+ signals_inflight ++ ;
472
464
sig_atomic_t request = jl_atomic_exchange (& ptls2 -> signal_request , 1 );
473
465
assert (request == 0 || request == -1 );
474
466
request = 1 ;
@@ -485,6 +477,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
485
477
if (err == -1 ) {
486
478
// not ready after timeout: try to cancel this request
487
479
if (jl_atomic_cmpswap (& ptls2 -> signal_request , & request , 0 )) {
480
+ signals_inflight -- ;
488
481
pthread_mutex_unlock (& in_signal_lock );
489
482
return 0 ;
490
483
}
@@ -494,7 +487,9 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
494
487
err = read (signal_caught_cond , & got , sizeof (eventfd_t ));
495
488
} while (err == -1 && errno == EINTR );
496
489
if (err != sizeof (eventfd_t )) abort ();
497
- assert (got == 1 ); (void ) got ;
490
+ assert (signals_inflight >= got );
491
+ signals_inflight -= got ;
492
+ signals_inflight ++ ;
498
493
// Now the other thread is waiting on exit_signal_cond (verify that here by
499
494
// checking it is 0, and add an acquire barrier for good measure)
500
495
request = jl_atomic_load_acquire (& ptls2 -> signal_request );
@@ -521,6 +516,7 @@ static void jl_try_deliver_sigint(void)
521
516
jl_safepoint_enable_sigint ();
522
517
jl_wake_libuv ();
523
518
pthread_mutex_lock (& in_signal_lock );
519
+ signals_inflight ++ ;
524
520
jl_atomic_store_release (& ptls2 -> signal_request , 2 );
525
521
// This also makes sure `sleep` is aborted.
526
522
pthread_kill (ptls2 -> system_id , SIGUSR2 );
0 commit comments