diff options
-rw-r--r-- | Python/pystate.c | 4 | ||||
-rw-r--r-- | Python/thread.c | 12 |
2 files changed, 15 insertions, 1 deletions
diff --git a/Python/pystate.c b/Python/pystate.c index 36b06d6..da417c1 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -253,6 +253,10 @@ tstate_delete_common(PyThreadState *tstate) "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(!)" diff --git a/Python/thread.c b/Python/thread.c index b21e53b..03580f3 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -264,15 +264,25 @@ static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ 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); |