[Zope-Checkins] CVS: ZODB3/BDBStorage - BDBMinimalStorage.py:1.29

Barry Warsaw barry@wooz.org
Thu, 30 Jan 2003 18:31:26 -0500


Update of /cvs-repository/ZODB3/BDBStorage
In directory cvs.zope.org:/tmp/cvs-serv24890

Modified Files:
	BDBMinimalStorage.py 
Log Message:
Backported from ZODB4:

Close an autopack race, where if a store was done after a sweep, but
before the collect_objs, the stored object would stay in packmark
until the next pack, preventing any objects it references from being
counted in the root-reachable test.

I don't have time to write a test case for this. :(

pack(): After we acquire the packlock, but before we set the packing
flag to True, we clear the packmark table.

_dopack(): Use the convenience wrapper _withlock method.


=== ZODB3/BDBStorage/BDBMinimalStorage.py 1.28 => 1.29 ===
--- ZODB3/BDBStorage/BDBMinimalStorage.py:1.28	Mon Jan 27 16:08:13 2003
+++ ZODB3/BDBStorage/BDBMinimalStorage.py	Thu Jan 30 18:31:24 2003
@@ -17,6 +17,8 @@
 
 __version__ = '$Revision$'[-2:][0]
 
+from __future__ import nested_scopes
+
 from ZODB import POSException
 from ZODB.utils import p64, U64
 from ZODB.referencesf import referencesf
@@ -383,6 +385,12 @@
         # A simple wrapper around the bulk of packing, but which acquires a
         # lock that prevents multiple packs from running at the same time.
         self._packlock.acquire()
+        # Before setting the packing flag to true, acquire the storage lock
+        # and clear out the packmark table, in case there's any cruft left
+        # over from the previous pack.
+        def clear_packmark(txn):
+            self._packmark.truncate(txn=txn)
+        self._withlock(self._withtxn, clear_packmark)
         self._packing = True
         try:
             # We don't wrap this in _withtxn() because we're going to do the
@@ -403,25 +411,13 @@
         # objects reachable from the root.  Anything else is a candidate for
         # having all their revisions packed away.  The set of reachable
         # objects lives in the _packmark table.
-        self._lock_acquire()
-        try:
-            self._withtxn(self._mark)
-        finally:
-            self._lock_release()
+        self._withlock(self._withtxn, self._mark)
         # Now perform a sweep, using oidqueue to hold all object ids for
         # objects which are not root reachable as of the pack time.
-        self._lock_acquire()
-        try:
-            self._withtxn(self._sweep)
-        finally:
-            self._lock_release()
+        self._withlock(self._withtxn, self._sweep)
         # Once again, collect any objects with refcount zero due to the mark
         # and sweep garbage collection pass.
-        self._lock_acquire()
-        try:
-            self._withtxn(self._collect_objs)
-        finally:
-            self._lock_release()
+        self._withlock(self._withtxn, self._collect_objs)
 
     def _mark(self, txn):
         # Find the oids for all the objects reachable from the root.  To