From f7ed5d72201b0791a50707aefc68bcd22f12c800 Mon Sep 17 00:00:00 2001 From: enkore Date: Fri, 25 Aug 2017 04:45:22 +0200 Subject: [PATCH] Buffer: fix wrong thread-local storage use (#2951) Buffer: delete support for multiple threads Thread-local objects are a fairly complex footgun, so avoid them in the first place. When a Compressor uses a Buffer (for example), just create multiple Compressor instances for each thread, owned by each thread. Minimize multiple ownership of objects across threads if at all possible! --- src/borg/helpers/datastruct.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/borg/helpers/datastruct.py b/src/borg/helpers/datastruct.py index 0b465ee5f..1650d3cd0 100644 --- a/src/borg/helpers/datastruct.py +++ b/src/borg/helpers/datastruct.py @@ -1,6 +1,3 @@ -import threading -from collections import namedtuple - from .errors import Error @@ -11,7 +8,9 @@ class StableDict(dict): class Buffer: - """provide a thread-local buffer""" + """ + Provides a managed, resizable buffer. + """ class MemoryLimitExceeded(Error, OSError): """Requested buffer size {} is above the limit of {}.""" @@ -23,13 +22,12 @@ class Buffer: """ assert callable(allocator), 'must give alloc(size) function as first param' assert limit is None or size <= limit, 'initial size must be <= limit' - self._thread_local = threading.local() self.allocator = allocator self.limit = limit self.resize(size, init=True) def __len__(self): - return len(self._thread_local.buffer) + return len(self.buffer) def resize(self, size, init=False): """ @@ -41,7 +39,7 @@ class Buffer: if self.limit is not None and size > self.limit: raise Buffer.MemoryLimitExceeded(size, self.limit) if init or len(self) < size: - self._thread_local.buffer = self.allocator(size) + self.buffer = self.allocator(size) def get(self, size=None, init=False): """ @@ -50,4 +48,4 @@ class Buffer: """ if size is not None: self.resize(size, init) - return self._thread_local.buffer + return self.buffer