@@ -213,7 +213,10 @@ new_threadstate(PyInterpreterState *interp, int init)
213
213
_PyThreadState_Init (tstate );
214
214
215
215
HEAD_LOCK ();
216
+ tstate -> prev = NULL ;
216
217
tstate -> next = interp -> tstate_head ;
218
+ if (tstate -> next )
219
+ tstate -> next -> prev = tstate ;
217
220
interp -> tstate_head = tstate ;
218
221
HEAD_UNLOCK ();
219
222
}
@@ -349,35 +352,18 @@ static void
349
352
tstate_delete_common (PyThreadState * tstate )
350
353
{
351
354
PyInterpreterState * interp ;
352
- PyThreadState * * p ;
353
- PyThreadState * prev_p = NULL ;
354
355
if (tstate == NULL )
355
356
Py_FatalError ("PyThreadState_Delete: NULL tstate" );
356
357
interp = tstate -> interp ;
357
358
if (interp == NULL )
358
359
Py_FatalError ("PyThreadState_Delete: NULL interp" );
359
360
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 ;
381
367
HEAD_UNLOCK ();
382
368
free (tstate );
383
369
}
@@ -429,26 +415,16 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
429
415
HEAD_LOCK ();
430
416
/* Remove all thread states, except tstate, from the linked list of
431
417
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. */
434
419
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 ;
435
427
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" );
452
428
HEAD_UNLOCK ();
453
429
/* Clear and deallocate all stale thread states. Even if this
454
430
executes Python code, we should be safe since it executes
0 commit comments