summaryrefslogtreecommitdiff
path: root/Python
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-02-01 02:30:25 +0100
committerGitHub <noreply@github.com>2020-02-01 02:30:25 +0100
commit4d96b4635aeff1b8ad41d41422ce808ce0b971c8 (patch)
tree841398922264fff5b99548bee68ff70884554040 /Python
parent7dc140126e918cc7c6e65aea321b7255f0020798 (diff)
downloadcpython-git-4d96b4635aeff1b8ad41d41422ce808ce0b971c8.tar.gz
bpo-39511: PyThreadState_Clear() calls on_delete (GH-18296)
PyThreadState.on_delete is a callback used to notify Python when a thread completes. _thread._set_sentinel() function creates a lock which is released when the thread completes. It sets on_delete callback to the internal release_sentinel() function. This lock is known as Threading._tstate_lock in the threading module. The release_sentinel() function uses the Python C API. The problem is that on_delete is called late in the Python finalization, when the C API is no longer fully working. The PyThreadState_Clear() function now calls the PyThreadState.on_delete callback. Previously, that happened in PyThreadState_Delete(). The release_sentinel() function is now called when the C API is still fully working.
Diffstat (limited to 'Python')
-rw-r--r--Python/pystate.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/Python/pystate.c b/Python/pystate.c
index d792380de4..ebc17ea5a7 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -806,6 +806,10 @@ PyThreadState_Clear(PyThreadState *tstate)
Py_CLEAR(tstate->async_gen_finalizer);
Py_CLEAR(tstate->context);
+
+ if (tstate->on_delete != NULL) {
+ tstate->on_delete(tstate->on_delete_data);
+ }
}
@@ -830,9 +834,7 @@ tstate_delete_common(PyThreadState *tstate,
if (tstate->next)
tstate->next->prev = tstate->prev;
HEAD_UNLOCK(runtime);
- if (tstate->on_delete != NULL) {
- tstate->on_delete(tstate->on_delete_data);
- }
+
PyMem_RawFree(tstate);
if (gilstate->autoInterpreterState &&