aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Fisher <paul@pfish.zone>2020-09-12 02:13:24 -0400
committerThomas Kemmer <tkemmer@computer.org>2020-12-09 23:38:17 +0100
commit5085c57624065759ea66911e52273f0fea918ac5 (patch)
tree53c32e4fe91dea8a81ac300c3ca2992c8bd9310e
parent6d2692fcb697984fdae53ee38fb3dd61fb3dc27d (diff)
downloadcachetools-5085c57624065759ea66911e52273f0fea918ac5.tar.gz
Add a test demonstrating the need for RLock in func.py.
-rw-r--r--tests/test_func.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/tests/test_func.py b/tests/test_func.py
index b6c4fe1..39dce77 100644
--- a/tests/test_func.py
+++ b/tests/test_func.py
@@ -88,6 +88,29 @@ class DecoratorTestMixin(object):
self.assertEqual(cached(1.0), 1.0)
self.assertEqual(cached.cache_info(), (2, 1, 128, 1))
+ def test_decorator_needs_rlock(self):
+ cached = self.decorator(lambda n: n)
+
+ class RecursiveEquals:
+ def __init__(self, use_cache):
+ self._use_cache = use_cache
+
+ def __hash__(self):
+ return hash(self._use_cache)
+
+ def __eq__(self, other):
+ if self._use_cache:
+ # This call will happen while the cache-lock is held,
+ # requiring a reentrant lock to avoid deadlock.
+ cached(self)
+ return self._use_cache == other._use_cache
+
+ # Prime the cache.
+ cached(RecursiveEquals(False))
+ cached(RecursiveEquals(True))
+ # Then do a call which will cause a deadlock with a non-reentrant lock.
+ self.assertEqual(cached(RecursiveEquals(True)), RecursiveEquals(True))
+
class FIFODecoratorTest(unittest.TestCase, DecoratorTestMixin):