@@ -46,6 +46,10 @@ static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_st
46
46
static void _PyThreadState_Delete (PyThreadState * tstate , int check_current );
47
47
48
48
49
+ /* We use "initial" if the runtime gets re-used
50
+ (e.g. Py_Finalize() followed by Py_Initialize(). */
51
+ static const _PyRuntimeState initial = _PyRuntimeState_INIT ;
52
+
49
53
static int
50
54
alloc_for_runtime (PyThread_type_lock * plock1 , PyThread_type_lock * plock2 ,
51
55
PyThread_type_lock * plock3 )
@@ -91,9 +95,12 @@ init_runtime(_PyRuntimeState *runtime,
91
95
PyThread_type_lock xidregistry_mutex )
92
96
{
93
97
if (runtime -> _initialized ) {
94
- _PyRuntimeState_reset (runtime );
95
- assert (!runtime -> initialized );
98
+ Py_FatalError ("runtime already initialized" );
96
99
}
100
+ assert (!runtime -> preinitializing &&
101
+ !runtime -> preinitialized &&
102
+ !runtime -> core_initialized &&
103
+ !runtime -> initialized );
97
104
98
105
runtime -> open_code_hook = open_code_hook ;
99
106
runtime -> open_code_userdata = open_code_userdata ;
@@ -144,6 +151,11 @@ _PyRuntimeState_Init(_PyRuntimeState *runtime)
144
151
return _PyStatus_NO_MEMORY ();
145
152
}
146
153
154
+ if (runtime -> _initialized ) {
155
+ // Py_Initialize() must be running again.
156
+ // Reset to _PyRuntimeState_INIT.
157
+ memcpy (runtime , & initial , sizeof (* runtime ));
158
+ }
147
159
init_runtime (runtime , open_code_hook , open_code_userdata , audit_hook_head ,
148
160
unicode_next_index , lock1 , lock2 , lock3 );
149
161
@@ -250,13 +262,15 @@ alloc_interpreter(void)
250
262
static void
251
263
free_interpreter (PyInterpreterState * interp )
252
264
{
253
- PyMem_RawFree (interp );
265
+ if (!interp -> _static ) {
266
+ PyMem_RawFree (interp );
267
+ }
254
268
}
255
269
256
270
/* Get the interpreter state to a minimal consistent state.
257
271
Further init happens in pylifecycle.c before it can be used.
258
272
All fields not initialized here are expected to be zeroed out,
259
- e.g. by PyMem_RawCalloc() or memset().
273
+ e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized .
260
274
The runtime state is not manipulated. Instead it is assumed that
261
275
the interpreter is getting added to the runtime.
262
276
*/
@@ -338,23 +352,23 @@ PyInterpreterState_New(void)
338
352
assert (interpreters -> main == NULL );
339
353
assert (id == 0 );
340
354
341
- interp = alloc_interpreter ();
342
- if (interp == NULL ) {
343
- goto error ;
344
- }
355
+ interp = & runtime -> _main_interpreter ;
345
356
assert (interp -> id == 0 );
346
357
assert (interp -> next == NULL );
347
358
348
359
interpreters -> main = interp ;
349
360
}
350
361
else {
351
- assert (id != 0 );
352
362
assert (interpreters -> main != NULL );
363
+ assert (id != 0 );
353
364
354
365
interp = alloc_interpreter ();
355
366
if (interp == NULL ) {
356
367
goto error ;
357
368
}
369
+ // Set to _PyInterpreterState_INIT.
370
+ memcpy (interp , & initial ._main_interpreter ,
371
+ sizeof (* interp ));
358
372
359
373
if (id < 0 ) {
360
374
/* overflow or Py_Initialize() not called yet! */
@@ -735,13 +749,15 @@ alloc_threadstate(void)
735
749
static void
736
750
free_threadstate (PyThreadState * tstate )
737
751
{
738
- PyMem_RawFree (tstate );
752
+ if (!tstate -> _static ) {
753
+ PyMem_RawFree (tstate );
754
+ }
739
755
}
740
756
741
757
/* Get the thread state to a minimal consistent state.
742
758
Further init happens in pylifecycle.c before it can be used.
743
759
All fields not initialized here are expected to be zeroed out,
744
- e.g. by PyMem_RawCalloc() or memset().
760
+ e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized .
745
761
The interpreter state is not manipulated. Instead it is assumed that
746
762
the thread is getting added to the interpreter.
747
763
*/
@@ -808,10 +824,7 @@ new_threadstate(PyInterpreterState *interp)
808
824
// It's the interpreter's initial thread state.
809
825
assert (id == 1 );
810
826
811
- tstate = alloc_threadstate ();
812
- if (tstate == NULL ) {
813
- goto error ;
814
- }
827
+ tstate = & interp -> _initial_thread ;
815
828
}
816
829
else {
817
830
// Every valid interpreter must have at least one thread.
@@ -822,6 +835,10 @@ new_threadstate(PyInterpreterState *interp)
822
835
if (tstate == NULL ) {
823
836
goto error ;
824
837
}
838
+ // Set to _PyThreadState_INIT.
839
+ memcpy (tstate ,
840
+ & initial ._main_interpreter ._initial_thread ,
841
+ sizeof (* tstate ));
825
842
}
826
843
interp -> threads .head = tstate ;
827
844
@@ -1159,7 +1176,7 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
1159
1176
for (p = list ; p ; p = next ) {
1160
1177
next = p -> next ;
1161
1178
PyThreadState_Clear (p );
1162
- PyMem_RawFree (p );
1179
+ free_threadstate (p );
1163
1180
}
1164
1181
}
1165
1182
0 commit comments