Ver código fonte

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 anos atrás
pai
commit
78361744ea
1 arquivos alterados com 12 adições e 9 exclusões
  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:
         with open(backup_filename, 'rb') as backup_fd:
             # note: file must not be 0 size (windows can't create 0 size mapping)
             # 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:
             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:
                 try:
                     with open(filename, 'wb') as fd:
                     with open(filename, 'wb') as fd:
                         fd.write(MAGIC)
                         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
                                 continue
-                            if crc32(data[4:size]) & 0xffffffff != crc:
-                                data = data[1:]
+                            if crc32(d[4:size]) & 0xffffffff != crc:
+                                d = d[1:]
                                 continue
                                 continue
-                            fd.write(data[:size])
-                            data = data[size:]
+                            fd.write(d[:size])
+                            d = d[size:]
                 finally:
                 finally:
+                    del d
                     data.release()
                     data.release()
 
 
     def read(self, segment, offset, id, read_data=True):
     def read(self, segment, offset, id, read_data=True):