[Python-Dev] Re: test_bsddb blocks testing popitem - reason

Gregory P. Smith greg at electricrain.com
Sun Nov 2 05:00:06 EST 2003

On Tue, Oct 28, 2003 at 11:12:21AM +0100, Alex Martelli wrote:
> On Monday 27 October 2003 10:56 pm, Gregory P. Smith wrote:
> > What about the behaviour of multiple iterators for the same dict being
> > used at once (either interleaved or by multiple threads; it shouldn't
> > matter)?  I expect that works fine in python.
> If the dict is not being modified, or if the only modifications on it are
> assigning different values for already-existing keys, multiple iterators
> on the same unchanging dict do work fine in one or more threads.
> But note that iterators only "read" the dict, don't change it.  If any
> change to the set of keys in the dict happens, all bets are off.
> > This is something the _DBWithCursor iteration interface does not currently
> > support due to its use of a single DBCursor internally.
> >
> > _DBWithCursor is currently written such that the cursor is never closed
> > once created.  This leaves tons of potential for deadlock even in single
> > threaded apps.  Reworking _DBWithCursor into a _DBThatUsesCursorsSafely
> > such that each iterator creates its own cursor in an internal pool
> > and other non cursor methods that would write to the db destroy all
> > cursors after saving their current() position so that the iterators can
> > reopen+reposition them is a solution.
> Woof.  I think I understand what you're saying.  However, writing to a
> dict (in the sense of changing the sets of keys) while one is iterating
> on the dict is NOT supported in Python -- basically "undefined behavior"
> (which does NOT include possibilities of crashes and deadlocks, though).
> So, maybe, we could get away with something a bit less rich here?

I just implemented and committed something about that rich.

I believe I could simplify it: have __iter__() and iteritems() return if
their cursor was closed out from underneath them instead of the current
attempt to reopen a cursor, reposition themselves, and keep going [which
could still have unpredictable results since a db modification could
rearrange the keys in some types of databases].

> So, maybe I _should_ just fix popitem that way and see if all tests pass?
> I dunno -- it feels a bit like fixing the symptoms and leaving some deep
> underlying problems intact...

My commit fixed the deadlock problem for the single threaded case and
wrote a test case to prove it.  I opened a SF bug to track fixing the
deadlock possibilities in the multithreaded case (and a memory leak i
believe i added).


More information about the Python-Dev mailing list