bpo-40010: Optimize signal handling in multithreaded applications (GH-19067)

If a thread different than the main thread gets a signal, the
bytecode evaluation loop is no longer interrupted at each bytecode
instruction to check for pending signals which cannot be handled.
Only the main thread of the main interpreter can handle signals.

Previously, the bytecode evaluation loop was interrupted at each
instruction until the main thread handles signals.

Changes:

* COMPUTE_EVAL_BREAKER() and SIGNAL_PENDING_SIGNALS() no longer set
  eval_breaker to 1 if the current thread cannot handle signals.
* take_gil() now always recomputes eval_breaker.
This commit is contained in:
Victor Stinner 2020-03-19 17:40:12 +01:00 committed by GitHub
parent 77248a2889
commit 5a3a71dddb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 4 deletions

View file

@ -280,9 +280,18 @@ _ready:
COND_SIGNAL(gil->switch_cond);
MUTEX_UNLOCK(gil->switch_mutex);
#endif
if (_Py_atomic_load_relaxed(&ceval->gil_drop_request)) {
RESET_GIL_DROP_REQUEST(ceval, ceval2);
}
else {
/* bpo-40010: eval_breaker should be recomputed to be set to 1 if there
a pending signal: signal received by another thread which cannot
handle signals.
Note: RESET_GIL_DROP_REQUEST() calls COMPUTE_EVAL_BREAKER(). */
COMPUTE_EVAL_BREAKER(ceval, ceval2);
}
int must_exit = tstate_must_exit(tstate);