[Zodb-checkins] CVS: ZODB3/BDBStorage - BDBMinimalStorage.py:1.29
Barry Warsaw
barry@wooz.org
Thu, 30 Jan 2003 18:31:27 -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