comparison Python/pystate.c @ 33940:dfd07b7be407 legacy-trunk

SF bug 1061968: threads: segfault or Py_FatalError at exit PyGILState_Ensure(): The fix in 2.4a3 for bug 1010677 reintroduced thread shutdown race bug 225673. Repaired by (once again) ensuring the GIL is held whenever deleting a thread state. Alas, there's no useful test case for this shy bug. Four years ago, only Guido could provoke it, on his box, and today only Armin can provoke it on his box. I've never been able to provoke it (but not for lack of trying!). This is a critical fix for 2.3.5 too, since the fix for 1010677 got backported there already and so also reintroduced 225673. I don't intend to backport this fix. For whoever (if anyone) does, there are other thread fixes in 2.4 that need backporting too, and I bet they need to happen first for this patch to apply cleanly.
author Tim Peters <tim.peters@gmail.com>
date Mon, 08 Nov 2004 04:30:21 +0000
parents 635dd8a9ebd9
children ff3ca656c281
comparison
equal deleted inserted replaced
33939:5fbbe8233b76 33940:dfd07b7be407
481 Py_FatalError("This thread state must be current when releasing"); 481 Py_FatalError("This thread state must be current when releasing");
482 assert(PyThreadState_IsCurrent(tcur)); 482 assert(PyThreadState_IsCurrent(tcur));
483 --tcur->gilstate_counter; 483 --tcur->gilstate_counter;
484 assert(tcur->gilstate_counter >= 0); /* illegal counter value */ 484 assert(tcur->gilstate_counter >= 0); /* illegal counter value */
485 485
486 /* If we are about to destroy this thread-state, we must 486 /* If we're going to destroy this thread-state, we must
487 clear it while the lock is held, as destructors may run 487 * clear it while the GIL is held, as destructors may run.
488 */ 488 */
489 if (tcur->gilstate_counter == 0) { 489 if (tcur->gilstate_counter == 0) {
490 /* can't have been locked when we created it */ 490 /* can't have been locked when we created it */
491 assert(oldstate == PyGILState_UNLOCKED); 491 assert(oldstate == PyGILState_UNLOCKED);
492 PyThreadState_Clear(tcur); 492 PyThreadState_Clear(tcur);
493 } 493 /* Delete the thread-state. Note this releases the GIL too!
494 494 * It's vital that the GIL be held here, to avoid shutdown
495 * races; see bugs 225673 and 1061968 (that nasty bug has a
496 * habit of coming back).
497 */
498 PyThreadState_DeleteCurrent();
499 /* Delete this thread from our TLS. */
500 PyThread_delete_key_value(autoTLSkey);
501 }
495 /* Release the lock if necessary */ 502 /* Release the lock if necessary */
496 if (oldstate == PyGILState_UNLOCKED) 503 else if (oldstate == PyGILState_UNLOCKED)
497 PyEval_ReleaseThread(tcur); 504 PyEval_ReleaseThread(tcur);
498
499 /* Now complete destruction of the thread if necessary */
500 if (tcur->gilstate_counter == 0) {
501 /* Delete this thread from our TLS */
502 PyThread_delete_key_value(autoTLSkey);
503 /* Delete the thread-state */
504 PyThreadState_Delete(tcur);
505 }
506 } 505 }
507 #endif /* WITH_THREAD */ 506 #endif /* WITH_THREAD */