@@ -213,7 +213,10 @@ new_threadstate(PyInterpreterState *interp, int init)
213213 _PyThreadState_Init (tstate );
214214
215215 HEAD_LOCK ();
216+ tstate -> prev = NULL ;
216217 tstate -> next = interp -> tstate_head ;
218+ if (tstate -> next )
219+ tstate -> next -> prev = tstate ;
217220 interp -> tstate_head = tstate ;
218221 HEAD_UNLOCK ();
219222 }
@@ -349,35 +352,18 @@ static void
349352tstate_delete_common (PyThreadState * tstate )
350353{
351354 PyInterpreterState * interp ;
352- PyThreadState * * p ;
353- PyThreadState * prev_p = NULL ;
354355 if (tstate == NULL )
355356 Py_FatalError ("PyThreadState_Delete: NULL tstate" );
356357 interp = tstate -> interp ;
357358 if (interp == NULL )
358359 Py_FatalError ("PyThreadState_Delete: NULL interp" );
359360 HEAD_LOCK ();
360- for (p = & interp -> tstate_head ; ; p = & (* p )-> next ) {
361- if (* p == NULL )
362- Py_FatalError (
363- "PyThreadState_Delete: invalid tstate" );
364- if (* p == tstate )
365- break ;
366- /* Sanity check. These states should never happen but if
367- * they do we must abort. Otherwise we'll end up spinning in
368- * in a tight loop with the lock held. A similar check is done
369- * in thread.c find_key(). */
370- if (* p == prev_p )
371- Py_FatalError (
372- "PyThreadState_Delete: small circular list(!)"
373- " and tstate not found." );
374- prev_p = * p ;
375- if ((* p )-> next == interp -> tstate_head )
376- Py_FatalError (
377- "PyThreadState_Delete: circular list(!) and"
378- " tstate not found." );
379- }
380- * p = tstate -> next ;
361+ if (tstate -> prev )
362+ tstate -> prev -> next = tstate -> next ;
363+ else
364+ interp -> tstate_head = tstate -> next ;
365+ if (tstate -> next )
366+ tstate -> next -> prev = tstate -> prev ;
381367 HEAD_UNLOCK ();
382368 free (tstate );
383369}
@@ -429,26 +415,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
429415 HEAD_LOCK ();
430416 /* Remove all thread states, except tstate, from the linked list of
431417 thread states. This will allow calling PyThreadState_Clear()
432- without holding the lock.
433- XXX This would be simpler with a doubly-linked list. */
418+ without holding the lock. */
434419 garbage = interp -> tstate_head ;
420+ if (garbage == tstate )
421+ garbage = tstate -> next ;
422+ if (tstate -> prev )
423+ tstate -> prev -> next = tstate -> next ;
424+ if (tstate -> next )
425+ tstate -> next -> prev = tstate -> prev ;
426+ tstate -> prev = tstate -> next = NULL ;
435427 interp -> tstate_head = tstate ;
436- if (garbage == tstate ) {
437- garbage = garbage -> next ;
438- tstate -> next = NULL ;
439- }
440- else {
441- for (p = garbage ; p ; p = p -> next ) {
442- if (p -> next == tstate ) {
443- p -> next = tstate -> next ;
444- tstate -> next = NULL ;
445- break ;
446- }
447- }
448- }
449- if (tstate -> next != NULL )
450- Py_FatalError ("_PyThreadState_DeleteExcept: tstate not found "
451- "in interpreter thread states" );
452428 HEAD_UNLOCK ();
453429 /* Clear and deallocate all stale thread states. Even if this
454430 executes Python code, we should be safe since it executes
0 commit comments