From: EtiennePelletier Date: Thu, 9 May 2019 20:47:54 +0000 (-0400) Subject: Prevent deadlock in LRUCache.setdefault X-Git-Tag: 2.11.0~61^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=065b58fc745e303b104995b101151e56b673f984;p=thirdparty%2Fjinja.git Prevent deadlock in LRUCache.setdefault setdefault was acquiring write_lock, then calling getitem and also potentially setitem, which also both try to acquire the write lock. --- diff --git a/CHANGES.rst b/CHANGES.rst index efcd2e29..bf4ac141 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -21,6 +21,7 @@ Unreleased 2.56e-3. :issue:`912`, :pr:`922` - Int and float literals can be written with the '_' separator for legibility, like 12_345. :pr:`923` +- Fix a bug causing deadlocks in ``LRUCache.setdefault``. :pr:`1000` Version 2.10.2 diff --git a/jinja2/utils.py b/jinja2/utils.py index 2e0aec22..9fb2b353 100644 --- a/jinja2/utils.py +++ b/jinja2/utils.py @@ -355,15 +355,11 @@ class LRUCache(object): """Set `default` if the key is not in the cache otherwise leave unchanged. Return the value of this key. """ - self._wlock.acquire() try: - try: - return self[key] - except KeyError: - self[key] = default - return default - finally: - self._wlock.release() + return self[key] + except KeyError: + self[key] = default + return default def clear(self): """Clear the cache.""" @@ -435,7 +431,6 @@ class LRUCache(object): try: self._remove(key) except ValueError: - # __getitem__ is not locked, it might happen pass finally: self._wlock.release() @@ -479,7 +474,7 @@ class LRUCache(object): __iter__ = iterkeys def __reversed__(self): - """Iterate over the values in the cache dict, oldest items + """Iterate over the keys in the cache dict, oldest items coming first. """ return iter(tuple(self._queue))