Commit 33f3c4a3 authored by Tim Peters's avatar Tim Peters

loadBefore(): This forgot to acquire the lock. That's a clear bug.

However, fixing it so far *appears* to fix a bunch of shy FileStorage
pack[Now]WhileWriting test failures whose connection to loadBefore()
isn't obvious.  It's plausible that it's a real fix for those, just
not (yet) compelling.  It seems very likely to be a real fix for very
rare failures that have shown up only in ChrisM's overnight testrunner
reports (because those did have stuff related to loadBefore() in their
tracebacks).
parent 800c94c5
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
############################################################################## ##############################################################################
"""Storage implementation using a log written to a single file. """Storage implementation using a log written to a single file.
$Revision: 1.4 $ $Revision: 1.5 $
""" """
import base64 import base64
...@@ -589,35 +589,40 @@ class FileStorage(BaseStorage.BaseStorage, ...@@ -589,35 +589,40 @@ class FileStorage(BaseStorage.BaseStorage,
self._lock_release() self._lock_release()
def loadBefore(self, oid, tid): def loadBefore(self, oid, tid):
pos = self._lookup_pos(oid) self._lock_acquire()
end_tid = None try:
while True: pos = self._lookup_pos(oid)
h = self._read_data_header(pos, oid) end_tid = None
if h.version: while True:
# Just follow the pnv pointer to the previous h = self._read_data_header(pos, oid)
# non-version data. if h.version:
if not h.pnv: # Just follow the pnv pointer to the previous
# Object was created in version. There is no # non-version data.
# before data to find. if not h.pnv:
return None # Object was created in version. There is no
pos = h.pnv # before data to find.
# The end_tid for the non-version data is not affected return None
# by versioned data records. pos = h.pnv
continue # The end_tid for the non-version data is not affected
# by versioned data records.
continue
if h.tid < tid:
break
if h.tid < tid: pos = h.prev
break end_tid = h.tid
if not pos:
return None
pos = h.prev if h.back:
end_tid = h.tid data, _, _, _ = self._loadBack_impl(oid, h.back)
if not pos: return data, h.tid, end_tid
return None else:
return self._file.read(h.plen), h.tid, end_tid
if h.back: finally:
data, _, _, _ = self._loadBack_impl(oid, h.back) self._lock_release()
return data, h.tid, end_tid
else:
return self._file.read(h.plen), h.tid, end_tid
def modifiedInVersion(self, oid): def modifiedInVersion(self, oid):
self._lock_acquire() self._lock_acquire()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment