1 Commits
Author SHA1 Message Date
Sumi JeongandJeong, YunWon 9d9fc27082 _queue: check for pending signals during blocking get() (#8252)
* _queue: check for pending signals during blocking get()

Semaphore::acquire() waited on the condvar in a single uninterrupted call,
so a Python-level signal handler never ran until the wait itself returned.
check_signals() is only invoked from the bytecode dispatch loop, and this
native wait never passed through it -- CPython chunks its equivalent
blocking wait for the same reason.

Cap each wait at a short interval and call check_signals() between chunks,
only giving up once the caller's real deadline has actually elapsed. The
mutex guard must be dropped before check_signals() runs: a signal handler
that calls back into the same queue on the same thread would otherwise try
to relock a mutex it's still holding and deadlock against itself.

Add a regression snippet that arms a SIGALRM well before a helper thread
unblocks the queue, and asserts the handler ran near the alarm instead of
only once get() returned.

Refs #8250
Assisted-by: Claude

* _queue: correct SIGNAL_CHECK_INTERVAL doc comment

The old comment claimed this mirrors CPython's PyThread_acquire_lock_timed,
but CPython doesn't chunk its wait either -- it makes one sem_timedwait call
and relies on the OS reporting EINTR. parking_lot's Condvar has no equivalent
signal to surface, so polling is a workaround for that gap, not a mirror of
CPython's approach.

Assisted-by: Claude

* Apply suggestions from code review

Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>

* _queue: fix comment indentation (cargo fmt)

Assisted-by: Claude

---------

Co-authored-by: Jeong, YunWon <69878+youknowone@users.noreply.github.com>
2026-07-16 17:39:48 +09:00