mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-39984: trip_signal() uses PyGILState_GetThisThreadState() (GH-19061)
bpo-37127, bpo-39984: * trip_signal() and Py_AddPendingCall() now get the current Python thread state using PyGILState_GetThisThreadState() rather than _PyRuntimeState_GetThreadState() to be able to get it even if the GIL is released. * _PyEval_SignalReceived() now expects tstate rather than ceval. * Remove ceval parameter of _PyEval_AddPendingCall(): ceval is now get from tstate parameter.
This commit is contained in:
parent
1c60567b9a
commit
8849e5962b
3 changed files with 19 additions and 13 deletions
|
@ -19,11 +19,9 @@ extern void _Py_FinishPendingCalls(PyThreadState *tstate);
|
||||||
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
|
extern void _PyEval_InitRuntimeState(struct _ceval_runtime_state *);
|
||||||
extern void _PyEval_InitState(struct _ceval_state *);
|
extern void _PyEval_InitState(struct _ceval_state *);
|
||||||
extern void _PyEval_FiniThreads(PyThreadState *tstate);
|
extern void _PyEval_FiniThreads(PyThreadState *tstate);
|
||||||
PyAPI_FUNC(void) _PyEval_SignalReceived(
|
PyAPI_FUNC(void) _PyEval_SignalReceived(PyThreadState *tstate);
|
||||||
struct _ceval_runtime_state *ceval);
|
|
||||||
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
PyAPI_FUNC(int) _PyEval_AddPendingCall(
|
||||||
PyThreadState *tstate,
|
PyThreadState *tstate,
|
||||||
struct _ceval_runtime_state *ceval,
|
|
||||||
int (*func)(void *),
|
int (*func)(void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyThreadState *tstate);
|
PyAPI_FUNC(void) _PyEval_SignalAsyncExc(PyThreadState *tstate);
|
||||||
|
|
|
@ -259,10 +259,14 @@ trip_signal(int sig_num)
|
||||||
cleared in PyErr_CheckSignals() before .tripped. */
|
cleared in PyErr_CheckSignals() before .tripped. */
|
||||||
_Py_atomic_store(&is_tripped, 1);
|
_Py_atomic_store(&is_tripped, 1);
|
||||||
|
|
||||||
|
/* Get the Python thread state using PyGILState API, since
|
||||||
|
_PyThreadState_GET() returns NULL if the GIL is released.
|
||||||
|
For example, signal.raise_signal() releases the GIL. */
|
||||||
|
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
||||||
|
assert(tstate != NULL);
|
||||||
|
|
||||||
/* Notify ceval.c */
|
/* Notify ceval.c */
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
_PyEval_SignalReceived(tstate);
|
||||||
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
|
|
||||||
_PyEval_SignalReceived(&runtime->ceval);
|
|
||||||
|
|
||||||
/* And then write to the wakeup fd *after* setting all the globals and
|
/* And then write to the wakeup fd *after* setting all the globals and
|
||||||
doing the _PyEval_SignalReceived. We used to write to the wakeup fd
|
doing the _PyEval_SignalReceived. We used to write to the wakeup fd
|
||||||
|
@ -302,7 +306,7 @@ trip_signal(int sig_num)
|
||||||
{
|
{
|
||||||
/* Py_AddPendingCall() isn't signal-safe, but we
|
/* Py_AddPendingCall() isn't signal-safe, but we
|
||||||
still use it for this exceptional case. */
|
still use it for this exceptional case. */
|
||||||
_PyEval_AddPendingCall(tstate, &runtime->ceval,
|
_PyEval_AddPendingCall(tstate,
|
||||||
report_wakeup_send_error,
|
report_wakeup_send_error,
|
||||||
(void *)(intptr_t) last_error);
|
(void *)(intptr_t) last_error);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +325,7 @@ trip_signal(int sig_num)
|
||||||
{
|
{
|
||||||
/* Py_AddPendingCall() isn't signal-safe, but we
|
/* Py_AddPendingCall() isn't signal-safe, but we
|
||||||
still use it for this exceptional case. */
|
still use it for this exceptional case. */
|
||||||
_PyEval_AddPendingCall(tstate, &runtime->ceval,
|
_PyEval_AddPendingCall(tstate,
|
||||||
report_wakeup_write_error,
|
report_wakeup_write_error,
|
||||||
(void *)(intptr_t)errno);
|
(void *)(intptr_t)errno);
|
||||||
}
|
}
|
||||||
|
|
|
@ -436,8 +436,9 @@ PyEval_RestoreThread(PyThreadState *tstate)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyEval_SignalReceived(struct _ceval_runtime_state *ceval)
|
_PyEval_SignalReceived(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
|
struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval;
|
||||||
/* bpo-30703: Function called when the C signal handler of Python gets a
|
/* bpo-30703: Function called when the C signal handler of Python gets a
|
||||||
signal. We cannot queue a callback using Py_AddPendingCall() since
|
signal. We cannot queue a callback using Py_AddPendingCall() since
|
||||||
that function is not async-signal-safe. */
|
that function is not async-signal-safe. */
|
||||||
|
@ -482,9 +483,9 @@ _pop_pending_call(struct _pending_calls *pending,
|
||||||
|
|
||||||
int
|
int
|
||||||
_PyEval_AddPendingCall(PyThreadState *tstate,
|
_PyEval_AddPendingCall(PyThreadState *tstate,
|
||||||
struct _ceval_runtime_state *ceval,
|
|
||||||
int (*func)(void *), void *arg)
|
int (*func)(void *), void *arg)
|
||||||
{
|
{
|
||||||
|
struct _ceval_runtime_state *ceval = &tstate->interp->runtime->ceval;
|
||||||
struct _pending_calls *pending = &ceval->pending;
|
struct _pending_calls *pending = &ceval->pending;
|
||||||
|
|
||||||
PyThread_acquire_lock(pending->lock, WAIT_LOCK);
|
PyThread_acquire_lock(pending->lock, WAIT_LOCK);
|
||||||
|
@ -511,9 +512,12 @@ _PyEval_AddPendingCall(PyThreadState *tstate,
|
||||||
int
|
int
|
||||||
Py_AddPendingCall(int (*func)(void *), void *arg)
|
Py_AddPendingCall(int (*func)(void *), void *arg)
|
||||||
{
|
{
|
||||||
_PyRuntimeState *runtime = &_PyRuntime;
|
/* Get the Python thread state using PyGILState API, since
|
||||||
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
|
_PyThreadState_GET() returns NULL if the GIL is released.
|
||||||
return _PyEval_AddPendingCall(tstate, &runtime->ceval, func, arg);
|
Py_AddPendingCall() doesn't require the caller to hold the GIL. */
|
||||||
|
PyThreadState *tstate = PyGILState_GetThisThreadState();
|
||||||
|
assert(tstate != NULL);
|
||||||
|
return _PyEval_AddPendingCall(tstate, func, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue