Message150330
| Author |
neologix |
| Recipients |
belopolsky, brett.cannon, christian.heimes, grahamd, gvanrossum, ncoghlan, neologix, pitrou, vstinner |
| Date |
2011年12月29日.13:45:48 |
| SpamBayes Score |
1.5935159e-07 |
| Marked as misclassified |
No |
| Message-id |
<CAH_1eM2jfJmbJiERNWVLrnPvv75BJFoUjGnkQdXNBm6AjfueTQ@mail.gmail.com> |
| In-reply-to |
<1325114282.32.0.397373477094.issue9260@psf.upfronthosting.co.za> |
| Content |
IIUC, the deadlock avoidance code just checks that acquiring a
per-module lock won't create a cycle.
However, I think there's a race, because the cycle detection and the
lock acquisition is not atomic.
For example, let's say we have a thread exactly here in in
acquire_import_lock():
PyThread_acquire_lock(lock->lock, 1);
/* thread inside PyEval_RestoreThread(), waiting for the GIL */
PyEval_RestoreThread(saved);
lock->waiters--;
}
assert(lock->level == 0);
lock->tstate = tstate;
It owns the lock, but hasn't yet updated the lock's owner
(lock->tstate), so another thread calling detect_circularity() will
think that this lock is available, and will proceed, which can
eventually lead to a deadlock.
Also, I think that locks will use POSIX semaphores on systems that
support only a limited number of them (such as FreeBSD 7), and this
might fail in case of nested imports (the infamous ENFILE). I'd have
to double check this, though. |
|