Explorar el Código

use try/finally to ensure correct memoryview release

see #4243.
Thomas Waldmann hace 6 años
padre
commit
2910d13055
Se han modificado 1 ficheros con 16 adiciones y 12 borrados
  1. 16 12
      src/borg/repository.py

+ 16 - 12
src/borg/repository.py

@@ -1395,18 +1395,22 @@ 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:
-                with memoryview(mm) as data, 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:]
-                            continue
-                        if crc32(data[4:size]) & 0xffffffff != crc:
-                            data = data[1:]
-                            continue
-                        fd.write(data[:size])
-                        data = data[size:]
+                data = memoryview(mm)  # didn't use memoryview context manager, it does not work correctly.
+                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:]
+                                continue
+                            if crc32(data[4:size]) & 0xffffffff != crc:
+                                data = data[1:]
+                                continue
+                            fd.write(data[:size])
+                            data = data[size:]
+                finally:
+                    data.release()
 
 
     def read(self, segment, offset, id, read_data=True):
     def read(self, segment, offset, id, read_data=True):
         """
         """