Skip to content

Commit

Permalink
Use lock-as-context manager to avoid race condition (issue #10).
Browse files Browse the repository at this point in the history
  • Loading branch information
tseaver committed Mar 24, 2012
1 parent a0f71cf commit 6beb439
Showing 1 changed file with 5 additions and 17 deletions.
22 changes: 5 additions & 17 deletions repoze/lru/__init__.py
@@ -1,4 +1,5 @@
""" LRU caching class and decorator """
from __future__ import with_statement

import threading
import time
Expand Down Expand Up @@ -34,8 +35,7 @@ def __init__(self, size):

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
Expand All @@ -47,8 +47,6 @@ def clear(self):
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"""
Expand All @@ -66,10 +64,8 @@ def put(self, key, val):
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
Expand Down Expand Up @@ -111,8 +107,6 @@ def put(self, key, val):
hand = 0
self.hand = hand
break
finally:
lock.release()

def invalidate(self, key):
"""Remove key from the cache"""
Expand Down Expand Up @@ -147,8 +141,7 @@ def __init__(self, size, default_timeout=_DEFAULT_TIMEOUT):

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
Expand All @@ -161,8 +154,6 @@ def clear(self):
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"""
Expand Down Expand Up @@ -195,8 +186,7 @@ def put(self, key, val, timeout=None):
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
Expand Down Expand Up @@ -237,8 +227,6 @@ def put(self, key, val, timeout=None):
hand = 0
self.hand = hand
break
finally:
lock.release()

def invalidate(self, key):
"""Remove key from the cache"""
Expand Down

0 comments on commit 6beb439

Please sign in to comment.