Sfoglia il codice sorgente

keep "data" as is, use "d" for slices

so that the data.release() call is on the original memoryview and
also we can delete the last reference to a slice of it first.
Thomas Waldmann 6 anni fa
parent
commit
78361744ea
1 ha cambiato i file con 12 aggiunte e 9 eliminazioni
  1. 12 9
      src/borg/repository.py

+ 12 - 9
src/borg/repository.py

@@ -1395,21 +1395,24 @@ class LoggedIO:
         with open(backup_filename, 'rb') as backup_fd:
             # note: file must not be 0 size (windows can't create 0 size mapping)
             with mmap.mmap(backup_fd.fileno(), 0, access=mmap.ACCESS_READ) as mm:
-                data = memoryview(mm)  # didn't use memoryview context manager, it does not work correctly.
+                # memoryview context manager is problematic, see https://bugs.python.org/issue35686
+                data = memoryview(mm)
+                d = data
                 try:
                     with open(filename, 'wb') as fd:
                         fd.write(MAGIC)
-                        while len(data) >= self.header_fmt.size:
-                            crc, size, tag = self.header_fmt.unpack(data[:self.header_fmt.size])
-                            if size < self.header_fmt.size or size > len(data):
-                                data = data[1:]
+                        while len(d) >= self.header_fmt.size:
+                            crc, size, tag = self.header_fmt.unpack(d[:self.header_fmt.size])
+                            if size < self.header_fmt.size or size > len(d):
+                                d = d[1:]
                                 continue
-                            if crc32(data[4:size]) & 0xffffffff != crc:
-                                data = data[1:]
+                            if crc32(d[4:size]) & 0xffffffff != crc:
+                                d = d[1:]
                                 continue
-                            fd.write(data[:size])
-                            data = data[size:]
+                            fd.write(d[:size])
+                            d = d[size:]
                 finally:
+                    del d
                     data.release()
 
     def read(self, segment, offset, id, read_data=True):