summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2004-10-09 23:55:36 (GMT)
committerTim Peters <tim.peters@gmail.com>2004-10-09 23:55:36 (GMT)
commit5c14e6498a9ca90f482d9d70c6df92d508aa8ff9 (patch)
tree5934222e7ac1c27c791e6dd84227655491f65abe /Python
parent2294bfc19d596e6c0d09799e66b07c58979e6889 (diff)
downloadcpython-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.c23
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 */