Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5c14e64

Browse files
committed
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.
1 parent 2294bfc commit 5c14e64

1 file changed

Lines changed: 15 additions & 8 deletions

File tree

Python/pystate.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -472,24 +472,31 @@ PyGILState_Release(PyGILState_STATE oldstate)
472472
assert(tcur->gilstate_counter >= 0); /* illegal counter value */
473473

474474
/* If we are about to destroy this thread-state, we must
475-
clear it while the lock is held, as destructors may run
476-
*/
475+
* clear it while the lock is held, as destructors may run.
476+
* In addition, we have to delete out TLS entry, which is keyed
477+
* by thread id, while the GIL is held: the thread calling us may
478+
* go away, and a new thread may be created with the same thread
479+
* id. If we don't delete our TLS until after the GIL is released,
480+
* that new thread may manage to insert a TLS value with the same
481+
* thread id as ours, and then we'd erroneously delete it.
482+
*/
477483
if (tcur->gilstate_counter == 0) {
478484
/* can't have been locked when we created it */
479485
assert(oldstate == PyGILState_UNLOCKED);
480486
PyThreadState_Clear(tcur);
487+
/* Delete this thread from our TLS */
488+
PyThread_delete_key_value(autoTLSkey);
481489
}
482490

483491
/* Release the lock if necessary */
484492
if (oldstate == PyGILState_UNLOCKED)
485493
PyEval_ReleaseThread(tcur);
486494

487-
/* Now complete destruction of the thread if necessary */
488-
if (tcur->gilstate_counter == 0) {
489-
/* Delete this thread from our TLS */
490-
PyThread_delete_key_value(autoTLSkey);
491-
/* Delete the thread-state */
495+
/* Now complete destruction of the thread if necessary. This
496+
* couldn't be done before PyEval_ReleaseThread() because
497+
* PyThreadState_Delete doesn't allow deleting the current thread.
498+
*/
499+
if (tcur->gilstate_counter == 0)
492500
PyThreadState_Delete(tcur);
493-
}
494501
}
495502
#endif /* WITH_THREAD */

0 commit comments

Comments
 (0)