[Zope3-checkins] CVS: Zope3/src/zodb/storage - bdbminimal.py:1.23

Tim Peters tim.one@comcast.net
Mon, 30 Jun 2003 18:28:23 -0400


Update of /cvs-repository/Zope3/src/zodb/storage
In directory cvs.zope.org:/tmp/cvs-serv13069/src/zodb/storage

Modified Files:
	bdbminimal.py 
Log Message:
pack():  Added more words about why we're holding the commit lock.  While
that's an acceptable fix (we asked Jim <wink>) for a minimal storage, it's
not for other storages, and the race condition here probably exists
elsewhere (however much more unlikely it is to be *triggered* elsewhere).


=== Zope3/src/zodb/storage/bdbminimal.py 1.22 => 1.23 ===
--- Zope3/src/zodb/storage/bdbminimal.py:1.22	Mon Jun 30 13:02:23 2003
+++ Zope3/src/zodb/storage/bdbminimal.py	Mon Jun 30 18:28:22 2003
@@ -394,9 +394,21 @@
         # clear_packmark (below) was called, so there was a small chance
         # for transactions to commit between the packing phases.  This
         # suffered rare races, where packing could (erroneously) delete
-        # a newly-added object.  Since interleaving packing with commits
+        # an active object.  Since interleaving packing with commits
         # is thought to be unimportant for minimal storages, the easiest
         # (by far) fix is to hold the commit lock throughout packing.
+        # Details:  Suppose the commit lock is released after clearing
+        # packmark.  Suppose a transaction gets thru dostore before
+        # marking begins.  Then because self._packing is True, _dostore()
+        # adds the stored oids to _packmark.  But _mark() uses _packmark
+        # as a list of *chased* oids, not as a list of oids to *be* chased.
+        # So the oids added to _packmark by _dostore() don't get chased by
+        # _mark(), and anything they reference (that isn't referenced by
+        # something else too) is considered to be trash.  Holding the
+        # commit lock during all of packing makes it impossible for
+        # self._packing to be True when in _dostore() or _docommit(), so
+        # those never add anything to _packmark, and only the correct
+        # oid-chasing code in _mark() populates _packmark.
         self._commit_lock_acquire()
         try:
             # We have to do this within a Berkeley transaction