@@ -121,6 +121,34 @@ current_tss_clear(_PyRuntimeState *runtime)
121121 }
122122}
123123
124+ #ifdef HAVE_FORK
125+ /* Reset the TSS key - called by PyOS_AfterFork_Child().
126+ * This should not be necessary, but some - buggy - pthread implementations
127+ * don't reset TSS upon fork(), see issue #10517.
128+ */
129+ static PyStatus
130+ current_tss_reinit (_PyRuntimeState * runtime )
131+ {
132+ if (!current_tss_initialized (runtime )) {
133+ return _PyStatus_OK ();
134+ }
135+ PyThreadState * tstate = current_tss_get (runtime );
136+
137+ current_tss_fini (runtime );
138+ PyStatus status = current_tss_init (runtime );
139+ if (_PyStatus_EXCEPTION (status )) {
140+ return status ;
141+ }
142+
143+ /* If the thread had an associated auto thread state, reassociate it with
144+ * the new key. */
145+ if (tstate && _current_tss_set (runtime , tstate ) != 0 ) {
146+ return _PyStatus_ERR ("failed to set autoTSSkey" );
147+ }
148+ return _PyStatus_OK ();
149+ }
150+ #endif
151+
124152
125153/* the global runtime */
126154
@@ -243,6 +271,13 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
243271 // Reset to _PyRuntimeState_INIT.
244272 memcpy (runtime , & initial , sizeof (* runtime ));
245273 }
274+
275+ PyStatus status = current_tss_init (runtime );
276+ if (_PyStatus_EXCEPTION (status )) {
277+ _PyRuntimeState_Fini (runtime );
278+ return status ;
279+ }
280+
246281 init_runtime (runtime , open_code_hook , open_code_userdata , audit_hook_head ,
247282 unicode_next_index , lock1 , lock2 , lock3 , lock4 );
248283
@@ -252,6 +287,10 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
252287void
253288_PyRuntimeState_Fini (_PyRuntimeState * runtime )
254289{
290+ if (current_tss_initialized (runtime )) {
291+ current_tss_fini (runtime );
292+ }
293+
255294 /* Force the allocator used by _PyRuntimeState_Init(). */
256295 PyMemAllocatorEx old_alloc ;
257296 _PyMem_SetDefaultAllocator (PYMEM_DOMAIN_RAW , & old_alloc );
@@ -304,6 +343,12 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
304343 return _PyStatus_ERR ("Failed to reinitialize runtime locks" );
305344
306345 }
346+
347+ PyStatus status = current_tss_reinit (runtime );
348+ if (_PyStatus_EXCEPTION (status )) {
349+ return status ;
350+ }
351+
307352 return _PyStatus_OK ();
308353}
309354#endif
@@ -978,6 +1023,7 @@ _PyThreadState_Init(PyThreadState *tstate)
9781023void
9791024_PyThreadState_SetCurrent (PyThreadState * tstate )
9801025{
1026+ assert (tstate != NULL );
9811027 _PyGILState_NoteThreadState (tstate );
9821028}
9831029
@@ -1614,19 +1660,33 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
16141660 Py_Initialize/Py_FinalizeEx
16151661*/
16161662PyStatus
1617- _PyGILState_Init (_PyRuntimeState * runtime )
1663+ _PyGILState_Init (PyInterpreterState * interp )
16181664{
1619- PyStatus status = current_tss_init (runtime );
1620- if (_PyStatus_EXCEPTION (status )) {
1621- return status ;
1665+ if (!_Py_IsMainInterpreter (interp )) {
1666+ /* Currently, PyGILState is shared by all interpreters. The main
1667+ * interpreter is responsible to initialize it. */
1668+ return _PyStatus_OK ();
16221669 }
1623- // PyThreadState_New() calls _PyGILState_NoteThreadState() which does
1624- // nothing before autoInterpreterState is set.
1670+ _PyRuntimeState * runtime = interp -> runtime ;
1671+ assert ( current_tss_get ( runtime ) == NULL );
16251672 assert (runtime -> gilstate .autoInterpreterState == NULL );
1673+ runtime -> gilstate .autoInterpreterState = interp ;
16261674 return _PyStatus_OK ();
16271675}
16281676
1677+ void
1678+ _PyGILState_Fini (PyInterpreterState * interp )
1679+ {
1680+ if (!_Py_IsMainInterpreter (interp )) {
1681+ /* Currently, PyGILState is shared by all interpreters. The main
1682+ * interpreter is responsible to initialize it. */
1683+ return ;
1684+ }
1685+ interp -> runtime -> gilstate .autoInterpreterState = NULL ;
1686+ }
1687+
16291688
1689+ // XXX Drop this.
16301690PyStatus
16311691_PyGILState_SetTstate (PyThreadState * tstate )
16321692{
@@ -1641,11 +1701,10 @@ _PyGILState_SetTstate(PyThreadState *tstate)
16411701 }
16421702 _PyRuntimeState * runtime = tstate -> interp -> runtime ;
16431703
1644- runtime -> gilstate .autoInterpreterState = tstate -> interp ;
1645- assert (current_tss_get (runtime ) == NULL );
1646- assert (tstate -> gilstate_counter == 0 );
1704+ assert ( runtime -> gilstate .autoInterpreterState == tstate -> interp ) ;
1705+ assert (current_tss_get (runtime ) == tstate );
1706+ assert (tstate -> gilstate_counter == 1 );
16471707
1648- _PyGILState_NoteThreadState (tstate );
16491708 return _PyStatus_OK ();
16501709}
16511710
@@ -1655,41 +1714,6 @@ _PyGILState_GetInterpreterStateUnsafe(void)
16551714 return _PyRuntime .gilstate .autoInterpreterState ;
16561715}
16571716
1658- void
1659- _PyGILState_Fini (PyInterpreterState * interp )
1660- {
1661- current_tss_fini (interp -> runtime );
1662- interp -> runtime -> gilstate .autoInterpreterState = NULL ;
1663- }
1664-
1665- #ifdef HAVE_FORK
1666- /* Reset the TSS key - called by PyOS_AfterFork_Child().
1667- * This should not be necessary, but some - buggy - pthread implementations
1668- * don't reset TSS upon fork(), see issue #10517.
1669- */
1670- PyStatus
1671- _PyGILState_Reinit (_PyRuntimeState * runtime )
1672- {
1673- if (!current_tss_initialized (runtime )) {
1674- return _PyStatus_OK ();
1675- }
1676- PyThreadState * tstate = current_tss_get (runtime );
1677-
1678- current_tss_fini (runtime );
1679- PyStatus status = current_tss_init (runtime );
1680- if (_PyStatus_EXCEPTION (status )) {
1681- return status ;
1682- }
1683-
1684- /* If the thread had an associated auto thread state, reassociate it with
1685- * the new key. */
1686- if (tstate && _current_tss_set (runtime , tstate ) != 0 ) {
1687- return _PyStatus_ERR ("failed to set autoTSSkey" );
1688- }
1689- return _PyStatus_OK ();
1690- }
1691- #endif
1692-
16931717/* When a thread state is created for a thread by some mechanism other than
16941718 PyGILState_Ensure, it's important that the GILState machinery knows about
16951719 it so it doesn't try to create another thread state for the thread (this is
@@ -1700,16 +1724,7 @@ _PyGILState_NoteThreadState(PyThreadState* tstate)
17001724{
17011725 assert (tstate != NULL );
17021726 _PyRuntimeState * runtime = tstate -> interp -> runtime ;
1703- /* If autoTSSkey isn't initialized, this must be the very first
1704- threadstate created in Py_Initialize(). Don't do anything for now
1705- (we'll be back here when _PyGILState_Init is called). */
1706- if (!current_tss_initialized (runtime )) {
1707- return ;
1708- }
1709- // XXX Drop this check?
1710- if (!runtime -> gilstate .autoInterpreterState ) {
1711- return ;
1712- }
1727+ assert (current_tss_initialized (runtime ));
17131728
17141729 /* Stick the thread state for this thread in thread specific storage.
17151730
0 commit comments