]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/midx.py
PackWriter._end: always try to release objcache and parentfd
[bup.git] / lib / bup / midx.py
index 0338906735fba53b3372916a588335677cfc044b..1b3708e81fe0b714736f9aaba65bc5f5a86d30be 100644 (file)
@@ -1,9 +1,9 @@
 
 from __future__ import absolute_import, print_function
-import glob, mmap, os, struct
+import glob, os, struct
 
 from bup import _helpers
-from bup.compat import range
+from bup.compat import pending_raise, range
 from bup.helpers import log, mmap_read
 from bup.io import path_msg
 
@@ -22,6 +22,7 @@ class PackMidx:
     amounts of files.
     """
     def __init__(self, filename):
+        self.closed = False
         self.name = filename
         self.force_keep = False
         self.map = None
@@ -31,18 +32,21 @@ class PackMidx:
             log('Warning: skipping: invalid MIDX header in %r\n'
                 % path_msg(filename))
             self.force_keep = True
-            return self._init_failed()
+            self._init_failed()
+            return
         ver = struct.unpack('!I', self.map[4:8])[0]
         if ver < MIDX_VERSION:
-            log('Warning: ignoring old-style (v%d) midx %r\n' 
+            log('Warning: ignoring old-style (v%d) midx %r\n'
                 % (ver, path_msg(filename)))
-            self.force_keep = False  # old stuff is boring  
-            return self._init_failed()
+            self.force_keep = False  # old stuff is boring
+            self._init_failed()
+            return
         if ver > MIDX_VERSION:
             log('Warning: ignoring too-new (v%d) midx %r\n'
                 % (ver, path_msg(filename)))
             self.force_keep = True  # new stuff is exciting
-            return self._init_failed()
+            self._init_failed()
+            return
 
         self.bits = _helpers.firstword(self.map[8:12])
         self.entries = 2**self.bits
@@ -55,8 +59,12 @@ class PackMidx:
         # which len is self.nsha * 4
         self.idxnames = self.map[self.which_ofs + 4 * self.nsha:].split(b'\0')
 
-    def __del__(self):
-        self.close()
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        with pending_raise(value, rethrow=False):
+            self.close()
 
     def _init_failed(self):
         self.bits = 0
@@ -85,11 +93,15 @@ class PackMidx:
         return self.idxnames[self._get_idx_i(i)]
 
     def close(self):
+        self.closed = True
         if self.map is not None:
             self.fanout = self.shatable = self.whichlist = self.idxnames = None
             self.map.close()
             self.map = None
 
+    def __del__(self):
+        assert self.closed
+
     def exists(self, hash, want_source=False):
         """Return nonempty if the object exists in the index files."""
         global _total_searches, _total_steps