This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author vstinner
Recipients JelleZijlstra, benjamin.peterson, corona10, remi.lapeyre, serhiy.storchaka, stutzbach, vstinner
Date 2020-06-01.15:23:52
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1591025032.31.0.535584139018.issue40826@roundup.psfhosted.org>
In-reply-to
Content
It seems like this issue was introduced by this change:

commit 728189884e0e128c4ffc57b785b04584d57a90c0
Author: Victor Stinner <vstinner@python.org>
Date:   Thu Mar 26 22:28:11 2020 +0100

    bpo-38644: Pass tstate explicitly in signalmodule.c (GH-19184)
    
    PyOS_InterruptOccurred() now checks _Py_ThreadCanHandleSignals()
    before checking if SIGINT is tripped.

 Include/internal/pycore_pyerrors.h |   2 +
 Modules/signalmodule.c             | 152 ++++++++++++++++++++++---------------
 Python/ceval.c                     |   4 +-
 3 files changed, 93 insertions(+), 65 deletions(-)

Before:
---
static inline int
_Py_IsMainInterpreter(PyThreadState* tstate)
{   
    /* Use directly _PyRuntime rather than tstate->interp->runtime, since
       this function is used in performance critical code path (ceval) */
    return (tstate->interp == _PyRuntime.interpreters.main);
}   

static inline int                          
_Py_ThreadCanHandleSignals(PyThreadState *tstate)
{        
    return (_Py_IsMainThread() && _Py_IsMainInterpreter(tstate));
}   
                    
static int                                 
thread_can_handle_signals(void)
{        
    PyThreadState *tstate = _PyThreadState_GET();              
    return _Py_ThreadCanHandleSignals(tstate);
}    

int
PyOS_InterruptOccurred(void)
{
    if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
        if (!thread_can_handle_signals()) {
            return 0;
        }
        _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
        return 1;
    }
    return 0;
}
---

After:
---                
static inline int 
_Py_IsMainInterpreter(PyThreadState* tstate)
{                               
    /* Use directly _PyRuntime rather than tstate->interp->runtime, since 
       this function is used in performance critical code path (ceval) */ 
    return (tstate->interp == _PyRuntime.interpreters.main);
}

static inline int                                                       
_Py_ThreadCanHandleSignals(PyThreadState *tstate)                          
{                                                                              
    return (_Py_IsMainThread() && _Py_IsMainInterpreter(tstate));
}

int
PyOS_InterruptOccurred(void)
{
    PyThreadState *tstate = _PyThreadState_GET();
    if (!_Py_ThreadCanHandleSignals(tstate)) {
        return 0;
    }

    if (!_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
        return 0;
    }

    _Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
    return 1;
}
---

The difference is that tstate->interp is now checked *before* checking if SIGINT signal is tripped.
History
Date User Action Args
2020-06-01 15:23:52vstinnersetrecipients: + vstinner, benjamin.peterson, stutzbach, serhiy.storchaka, JelleZijlstra, corona10, remi.lapeyre
2020-06-01 15:23:52vstinnersetmessageid: <1591025032.31.0.535584139018.issue40826@roundup.psfhosted.org>
2020-06-01 15:23:52vstinnerlinkissue40826 messages
2020-06-01 15:23:52vstinnercreate