[Zodb-checkins] CVS: ZODB3/BDBStorage - BDBMinimalStorage.py:1.12.6.4

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


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

Modified Files:
      Tag: ZODB3-3_1-branch
	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.12.6.3 => 1.12.6.4 ===
--- ZODB3/BDBStorage/BDBMinimalStorage.py:1.12.6.3	Mon Jan 27 18:19:01 2003
+++ ZODB3/BDBStorage/BDBMinimalStorage.py	Thu Jan 30 18:33:00 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