@@ -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