[Python-checkins] r65650 - in python/branches/release25-maint/Python: pystate.c thread.c
georg.brandl
python-checkins at python.org
Tue Aug 12 10:46:09 CEST 2008
Author: georg.brandl
Date: Tue Aug 12 10:46:02 2008
New Revision: 65650
Log:
Backport r60148 and r65481: sanity checks to avoid infinite loops.
Modified:
python/branches/release25-maint/Python/pystate.c
python/branches/release25-maint/Python/thread.c
Modified: python/branches/release25-maint/Python/pystate.c
==============================================================================
--- python/branches/release25-maint/Python/pystate.c (original)
+++ python/branches/release25-maint/Python/pystate.c Tue Aug 12 10:46:02 2008
@@ -240,6 +240,7 @@
{
PyInterpreterState *interp;
PyThreadState **p;
+ PyThreadState *prev_p = NULL;
if (tstate == NULL)
Py_FatalError("PyThreadState_Delete: NULL tstate");
interp = tstate->interp;
@@ -252,6 +253,19 @@
"PyThreadState_Delete: invalid tstate");
if (*p == tstate)
break;
+ /* Sanity check. These states should never happen but if
+ * they do we must abort. Otherwise we'll end up spinning in
+ * in a tight loop with the lock held. A similar check is done
+ * in thread.c find_key(). */
+ if (*p == prev_p)
+ Py_FatalError(
+ "PyThreadState_Delete: small circular list(!)"
+ " and tstate not found.");
+ prev_p = *p;
+ if ((*p)->next == interp->tstate_head)
+ Py_FatalError(
+ "PyThreadState_Delete: circular list(!) and"
+ " tstate not found.");
}
*p = tstate->next;
HEAD_UNLOCK();
Modified: python/branches/release25-maint/Python/thread.c
==============================================================================
--- python/branches/release25-maint/Python/thread.c (original)
+++ python/branches/release25-maint/Python/thread.c Tue Aug 12 10:46:02 2008
@@ -264,15 +264,25 @@
static struct key *
find_key(int key, void *value)
{
- struct key *p;
+ struct key *p, *prev_p;
long id = PyThread_get_thread_ident();
if (!keymutex)
return NULL;
PyThread_acquire_lock(keymutex, 1);
+ prev_p = NULL;
for (p = keyhead; p != NULL; p = p->next) {
if (p->id == id && p->key == key)
goto Done;
+ /* Sanity check. These states should never happen but if
+ * they do we must abort. Otherwise we'll end up spinning in
+ * in a tight loop with the lock held. A similar check is done
+ * in pystate.c tstate_delete_common(). */
+ if (p == prev_p)
+ Py_FatalError("tls find_key: small circular list(!)");
+ prev_p = p;
+ if (p->next == keyhead)
+ Py_FatalError("tls find_key: circular list(!)");
}
if (value == NULL) {
assert(p == NULL);
More information about the Python-checkins
mailing list