diff options
author | Tres Seaver <tseaver@palladion.com> | 2012-03-24 14:02:07 -0400 |
---|---|---|
committer | Tres Seaver <tseaver@palladion.com> | 2012-03-24 14:02:07 -0400 |
commit | 6beb4393e2c6788a14689bcb3e325c8e787bda35 (patch) | |
tree | f1477f2c92acc0f8370c172d0c43ae192af0b1ad | |
parent | a0f71cfbcbc6593c1cdeb7fce9a53384ccfb9f13 (diff) | |
download | repoze-lru-6beb4393e2c6788a14689bcb3e325c8e787bda35.tar.gz |
Use lock-as-context manager to avoid race condition (issue #10).
-rw-r--r-- | repoze/lru/__init__.py | 22 |
1 files changed, 5 insertions, 17 deletions
diff --git a/repoze/lru/__init__.py b/repoze/lru/__init__.py index d7bcfef..4092ce0 100644 --- a/repoze/lru/__init__.py +++ b/repoze/lru/__init__.py @@ -1,4 +1,5 @@ """ LRU caching class and decorator """ +from __future__ import with_statement import threading import time @@ -34,8 +35,7 @@ class LRUCache(object): def clear(self): """Remove all entries from the cache""" - self.lock.acquire() - try: + with self.lock: # If really clear()ing a full cache, clean up self.data first to # give garbage collection a chance to reduce memorey usage. # Instantiating "[_MARKER] * size" will temporarily have 2 lists @@ -47,8 +47,6 @@ class LRUCache(object): self.clock_keys = [_MARKER] * size self.clock_refs = [False] * size self.hand = 0 - finally: - self.lock.release() def get(self, key, default=None): """Return value for key. If not in cache, return default""" @@ -66,10 +64,8 @@ class LRUCache(object): clock_refs = self.clock_refs clock_keys = self.clock_keys data = self.data - lock = self.lock - lock.acquire() - try: + with self.lock: entry = data.get(key) if entry is not None: # We already have key. Only make sure data is up to date and @@ -111,8 +107,6 @@ class LRUCache(object): hand = 0 self.hand = hand break - finally: - lock.release() def invalidate(self, key): """Remove key from the cache""" @@ -147,8 +141,7 @@ class ExpiringLRUCache(object): def clear(self): """Remove all entries from the cache""" - self.lock.acquire() - try: + with self.lock: # If really clear()ing a full cache, clean up self.data first to # give garbage collection a chance to reduce memorey usage. # Instantiating "[_MARKER] * size" will temporarily have 2 lists @@ -161,8 +154,6 @@ class ExpiringLRUCache(object): self.clock_keys = [_MARKER] * size self.clock_refs = [False] * size self.hand = 0 - finally: - self.lock.release() def get(self, key, default=None): """Return value for key. If not in cache or expired, return default""" @@ -195,8 +186,7 @@ class ExpiringLRUCache(object): if timeout is None: timeout = self.default_timeout - lock.acquire() - try: + with self.lock: entry = data.get(key) if entry is not None: # We already have key. Only make sure data is up to date and @@ -237,8 +227,6 @@ class ExpiringLRUCache(object): hand = 0 self.hand = hand break - finally: - lock.release() def invalidate(self, key): """Remove key from the cache""" |