[Zodb-checkins] CVS: ZODB4/src/zodb/storage - bdbminimal.py:1.10
Barry Warsaw
barry@wooz.org
Thu, 30 Jan 2003 18:17:45 -0500
Update of /cvs-repository/ZODB4/src/zodb/storage
In directory cvs.zope.org:/tmp/cvs-serv22393
Modified Files:
bdbminimal.py
Log Message:
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.
=== ZODB4/src/zodb/storage/bdbminimal.py 1.9 => 1.10 ===
--- ZODB4/src/zodb/storage/bdbminimal.py:1.9 Mon Jan 27 11:26:00 2003
+++ ZODB4/src/zodb/storage/bdbminimal.py Thu Jan 30 18:17:43 2003
@@ -370,6 +370,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
@@ -390,25 +396,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
@@ -462,7 +456,6 @@
finally:
c.close()
# We're done with the mark table
- self._packmark.truncate(txn)
def _collect_objs(self, txn):
orec = self._oidqueue.consume(txn)