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!
This commit is contained in:
enkore 2017-08-25 04:45:22 +02:00 committed by TW
parent 95d267493e
commit f7ed5d7220
1 changed files with 6 additions and 8 deletions

View File

@ -1,6 +1,3 @@
import threading
from collections import namedtuple
from .errors import Error from .errors import Error
@ -11,7 +8,9 @@ class StableDict(dict):
class Buffer: class Buffer:
"""provide a thread-local buffer""" """
Provides a managed, resizable buffer.
"""
class MemoryLimitExceeded(Error, OSError): class MemoryLimitExceeded(Error, OSError):
"""Requested buffer size {} is above the limit of {}.""" """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 callable(allocator), 'must give alloc(size) function as first param'
assert limit is None or size <= limit, 'initial size must be <= limit' assert limit is None or size <= limit, 'initial size must be <= limit'
self._thread_local = threading.local()
self.allocator = allocator self.allocator = allocator
self.limit = limit self.limit = limit
self.resize(size, init=True) self.resize(size, init=True)
def __len__(self): def __len__(self):
return len(self._thread_local.buffer) return len(self.buffer)
def resize(self, size, init=False): def resize(self, size, init=False):
""" """
@ -41,7 +39,7 @@ class Buffer:
if self.limit is not None and size > self.limit: if self.limit is not None and size > self.limit:
raise Buffer.MemoryLimitExceeded(size, self.limit) raise Buffer.MemoryLimitExceeded(size, self.limit)
if init or len(self) < size: 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): def get(self, size=None, init=False):
""" """
@ -50,4 +48,4 @@ class Buffer:
""" """
if size is not None: if size is not None:
self.resize(size, init) self.resize(size, init)
return self._thread_local.buffer return self.buffer