@@ -426,6 +426,7 @@ pthread_mutex_t in_signal_lock; // shared with jl_delete_thread
426426static bt_context_t * signal_context ; // protected by in_signal_lock
427427static int exit_signal_cond = -1 ;
428428static int signal_caught_cond = -1 ;
429+ static int signals_inflight = 0 ;
429430
430431int jl_thread_suspend_and_get_state (int tid , int timeout , bt_context_t * ctx )
431432{
@@ -438,7 +439,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
438439 pthread_mutex_unlock (& in_signal_lock );
439440 return 0 ;
440441 }
441- if ( jl_atomic_load ( & ptls2 -> signal_request ) != 0 ) {
442+ while ( signals_inflight ) {
442443 // something is wrong, or there is already a usr2 in flight elsewhere
443444 // try to wait for it to finish or wait for timeout
444445 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)
450451 pthread_mutex_unlock (& in_signal_lock );
451452 return 0 ;
452453 }
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 ) {
464454 // consume it before continuing
465455 eventfd_t got ;
466456 do {
467457 err = read (signal_caught_cond , & got , sizeof (eventfd_t ));
468458 } while (err == -1 && errno == EINTR );
469459 if (err != sizeof (eventfd_t )) abort ();
470- assert (got == 1 ); (void ) got ;
460+ assert (signals_inflight >= got );
461+ signals_inflight -= got ;
471462 }
463+ signals_inflight ++ ;
472464 sig_atomic_t request = jl_atomic_exchange (& ptls2 -> signal_request , 1 );
473465 assert (request == 0 || request == -1 );
474466 request = 1 ;
@@ -485,6 +477,7 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
485477 if (err == -1 ) {
486478 // not ready after timeout: try to cancel this request
487479 if (jl_atomic_cmpswap (& ptls2 -> signal_request , & request , 0 )) {
480+ signals_inflight -- ;
488481 pthread_mutex_unlock (& in_signal_lock );
489482 return 0 ;
490483 }
@@ -494,7 +487,9 @@ int jl_thread_suspend_and_get_state(int tid, int timeout, bt_context_t *ctx)
494487 err = read (signal_caught_cond , & got , sizeof (eventfd_t ));
495488 } while (err == -1 && errno == EINTR );
496489 if (err != sizeof (eventfd_t )) abort ();
497- assert (got == 1 ); (void ) got ;
490+ assert (signals_inflight >= got );
491+ signals_inflight -= got ;
492+ signals_inflight ++ ;
498493 // Now the other thread is waiting on exit_signal_cond (verify that here by
499494 // checking it is 0, and add an acquire barrier for good measure)
500495 request = jl_atomic_load_acquire (& ptls2 -> signal_request );
@@ -521,6 +516,7 @@ static void jl_try_deliver_sigint(void)
521516 jl_safepoint_enable_sigint ();
522517 jl_wake_libuv ();
523518 pthread_mutex_lock (& in_signal_lock );
519+ signals_inflight ++ ;
524520 jl_atomic_store_release (& ptls2 -> signal_request , 2 );
525521 // This also makes sure `sleep` is aborted.
526522 pthread_kill (ptls2 -> system_id , SIGUSR2 );
0 commit comments