Skip to content

Commit 7bdf5a4

Browse files
Initialize autoTSSkey earlier.
1 parent 4af2ecb commit 7bdf5a4

File tree

5 files changed

+81
-73
lines changed

5 files changed

+81
-73
lines changed

Include/internal/pycore_pylifecycle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ extern void _PyThread_FiniType(PyInterpreterState *interp);
6969
extern void _Py_Deepfreeze_Fini(void);
7070
extern void _PyArg_Fini(void);
7171

72-
extern PyStatus _PyGILState_Init(_PyRuntimeState *runtime);
72+
extern PyStatus _PyGILState_Init(PyInterpreterState *interp);
7373
extern PyStatus _PyGILState_SetTstate(PyThreadState *tstate);
7474
extern void _PyGILState_Fini(PyInterpreterState *interp);
7575

Include/internal/pycore_pystate.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ PyAPI_FUNC(PyStatus) _PyInterpreterState_Enable(_PyRuntimeState *runtime);
149149

150150
#ifdef HAVE_FORK
151151
extern PyStatus _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime);
152-
extern PyStatus _PyGILState_Reinit(_PyRuntimeState *runtime);
153152
extern void _PySignal_AfterFork(void);
154153
#endif
155154

Modules/posixmodule.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ PyOS_AfterFork_Child(void)
587587
PyStatus status;
588588
_PyRuntimeState *runtime = &_PyRuntime;
589589

590-
status = _PyGILState_Reinit(runtime);
590+
status = _PyRuntimeState_ReInitThreads(runtime);
591591
if (_PyStatus_EXCEPTION(status)) {
592592
goto fatal_error;
593593
}
@@ -611,11 +611,6 @@ PyOS_AfterFork_Child(void)
611611

612612
_PySignal_AfterFork();
613613

614-
status = _PyRuntimeState_ReInitThreads(runtime);
615-
if (_PyStatus_EXCEPTION(status)) {
616-
goto fatal_error;
617-
}
618-
619614
status = _PyInterpreterState_DeleteExceptMain(runtime);
620615
if (_PyStatus_EXCEPTION(status)) {
621616
goto fatal_error;

Python/pylifecycle.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -675,12 +675,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
675675
const PyConfig *src_config,
676676
PyThreadState **tstate_p)
677677
{
678-
/* Auto-thread-state API */
679-
PyStatus status = _PyGILState_Init(runtime);
680-
if (_PyStatus_EXCEPTION(status)) {
681-
return status;
682-
}
683-
678+
PyStatus status;
684679
PyInterpreterState *interp = PyInterpreterState_New();
685680
if (interp == NULL) {
686681
return _PyStatus_ERR("can't make main interpreter");
@@ -692,6 +687,12 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
692687
return status;
693688
}
694689

690+
/* Auto-thread-state API */
691+
status = _PyGILState_Init(interp);
692+
if (_PyStatus_EXCEPTION(status)) {
693+
return status;
694+
}
695+
695696
const _PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
696697
init_interp_settings(interp, &config);
697698

@@ -1795,10 +1796,8 @@ finalize_interp_clear(PyThreadState *tstate)
17951796
static void
17961797
finalize_interp_delete(PyInterpreterState *interp)
17971798
{
1798-
if (_Py_IsMainInterpreter(interp)) {
1799-
/* Cleanup auto-thread-state */
1800-
_PyGILState_Fini(interp);
1801-
}
1799+
/* Cleanup auto-thread-state */
1800+
_PyGILState_Fini(interp);
18021801

18031802
/* We can't call _PyEval_FiniGIL() here because destroying the GIL lock can
18041803
fail when it is being awaited by another running daemon thread (see

Python/pystate.c

Lines changed: 70 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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)
252287
void
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)
9781023
void
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
*/
16161662
PyStatus
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.
16301690
PyStatus
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

Comments
 (0)