File tree Expand file tree Collapse file tree 1 file changed +13
-11
lines changed Expand file tree Collapse file tree 1 file changed +13
-11
lines changed Original file line number Diff line number Diff line change @@ -810,7 +810,12 @@ new_threadstate(PyInterpreterState *interp)
810
810
{
811
811
PyThreadState * tstate ;
812
812
_PyRuntimeState * runtime = interp -> runtime ;
813
-
813
+ // Allocate eagerly without lock
814
+ PyThreadState * new_tstate = alloc_threadstate ();
815
+ int used_newtstate ;
816
+ if (new_tstate == NULL ) {
817
+ return NULL ;
818
+ }
814
819
/* We serialize concurrent creation to protect global state. */
815
820
HEAD_LOCK (runtime );
816
821
@@ -822,18 +827,15 @@ new_threadstate(PyInterpreterState *interp)
822
827
if (old_head == NULL ) {
823
828
// It's the interpreter's initial thread state.
824
829
assert (id == 1 );
825
-
830
+ used_newtstate = 0 ;
826
831
tstate = & interp -> _initial_thread ;
827
832
}
828
833
else {
829
834
// Every valid interpreter must have at least one thread.
830
835
assert (id > 1 );
831
836
assert (old_head -> prev == NULL );
832
-
833
- tstate = alloc_threadstate ();
834
- if (tstate == NULL ) {
835
- goto error ;
836
- }
837
+ used_newtstate = 1 ;
838
+ tstate = new_tstate ;
837
839
// Set to _PyThreadState_INIT.
838
840
memcpy (tstate ,
839
841
& initial ._main_interpreter ._initial_thread ,
@@ -844,11 +846,11 @@ new_threadstate(PyInterpreterState *interp)
844
846
init_threadstate (tstate , interp , id , old_head );
845
847
846
848
HEAD_UNLOCK (runtime );
849
+ if (!used_newtstate ) {
850
+ // Must be called with lock unlocked to avoid re-entrancy deadlock.
851
+ PyMem_RawFree (new_tstate );
852
+ }
847
853
return tstate ;
848
-
849
- error :
850
- HEAD_UNLOCK (runtime );
851
- return NULL ;
852
854
}
853
855
854
856
PyThreadState *
You can’t perform that action at this time.
0 commit comments