diff options
author | Tim Peters <tim.peters@gmail.com> | 2004-10-09 23:55:36 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2004-10-09 23:55:36 (GMT) |
commit | 5c14e6498a9ca90f482d9d70c6df92d508aa8ff9 (patch) | |
tree | 5934222e7ac1c27c791e6dd84227655491f65abe /Python | |
parent | 2294bfc19d596e6c0d09799e66b07c58979e6889 (diff) | |
download | cpython-5c14e6498a9ca90f482d9d70c6df92d508aa8ff9.zip cpython-5c14e6498a9ca90f482d9d70c6df92d508aa8ff9.tar.gz cpython-5c14e6498a9ca90f482d9d70c6df92d508aa8ff9.tar.bz2 |
PyGILState_Release(): If we need to delete the TLS entry for this thread,
that must be done under protection of the GIL, for reasons explained in
new comments.
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pystate.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index ba9be97..703ce48 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -472,24 +472,31 @@ PyGILState_Release(PyGILState_STATE oldstate) assert(tcur->gilstate_counter >= 0); /* illegal counter value */ /* If we are about to destroy this thread-state, we must - clear it while the lock is held, as destructors may run - */ + * clear it while the lock is held, as destructors may run. + * In addition, we have to delete out TLS entry, which is keyed + * by thread id, while the GIL is held: the thread calling us may + * go away, and a new thread may be created with the same thread + * id. If we don't delete our TLS until after the GIL is released, + * that new thread may manage to insert a TLS value with the same + * thread id as ours, and then we'd erroneously delete it. + */ if (tcur->gilstate_counter == 0) { /* can't have been locked when we created it */ assert(oldstate == PyGILState_UNLOCKED); PyThreadState_Clear(tcur); + /* Delete this thread from our TLS */ + PyThread_delete_key_value(autoTLSkey); } /* Release the lock if necessary */ if (oldstate == PyGILState_UNLOCKED) PyEval_ReleaseThread(tcur); - /* Now complete destruction of the thread if necessary */ - if (tcur->gilstate_counter == 0) { - /* Delete this thread from our TLS */ - PyThread_delete_key_value(autoTLSkey); - /* Delete the thread-state */ + /* Now complete destruction of the thread if necessary. This + * couldn't be done before PyEval_ReleaseThread() because + * PyThreadState_Delete doesn't allow deleting the current thread. + */ + if (tcur->gilstate_counter == 0) PyThreadState_Delete(tcur); - } } #endif /* WITH_THREAD */ |