Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Clean up the the locmem cache backend and utils.synch by using contex…

…t managers. Puch prettier.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17152 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e4919f64b09a1813d5f1b4854f8b7c6e3a3c7a9a 1 parent 1086a9a
@alex alex authored
Showing with 43 additions and 55 deletions.
  1. +20 −40 django/core/cache/backends/locmem.py
  2. +23 −15 django/utils/synch.py
View
60 django/core/cache/backends/locmem.py
@@ -1,5 +1,7 @@
"Thread-safe in-memory cache backend."
+from __future__ import with_statement
+
import time
try:
import cPickle as pickle
@@ -26,8 +28,7 @@ def __init__(self, name, params):
def add(self, key, value, timeout=None, version=None):
key = self.make_key(key, version=version)
self.validate_key(key)
- self._lock.writer_enters()
- try:
+ with self._lock.writer():
exp = self._expire_info.get(key)
if exp is None or exp <= time.time():
try:
@@ -37,14 +38,11 @@ def add(self, key, value, timeout=None, version=None):
except pickle.PickleError:
pass
return False
- finally:
- self._lock.writer_leaves()
def get(self, key, default=None, version=None):
key = self.make_key(key, version=version)
self.validate_key(key)
- self._lock.reader_enters()
- try:
+ with self._lock.reader():
exp = self._expire_info.get(key)
if exp is None:
return default
@@ -54,18 +52,13 @@ def get(self, key, default=None, version=None):
return pickle.loads(pickled)
except pickle.PickleError:
return default
- finally:
- self._lock.reader_leaves()
- self._lock.writer_enters()
- try:
+ with self._lock.writer():
try:
del self._cache[key]
del self._expire_info[key]
except KeyError:
pass
return default
- finally:
- self._lock.writer_leaves()
def _set(self, key, value, timeout=None):
if len(self._cache) >= self._max_entries:
@@ -78,14 +71,12 @@ def _set(self, key, value, timeout=None):
def set(self, key, value, timeout=None, version=None):
key = self.make_key(key, version=version)
self.validate_key(key)
- self._lock.writer_enters()
- try:
- pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
- self._set(key, pickled, timeout)
- except pickle.PickleError:
- pass
- finally:
- self._lock.writer_leaves()
+ with self._lock.writer():
+ try:
+ pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL)
+ self._set(key, pickled, timeout)
+ except pickle.PickleError:
+ pass
def incr(self, key, delta=1, version=None):
value = self.get(key, version=version)
@@ -93,39 +84,31 @@ def incr(self, key, delta=1, version=None):
raise ValueError("Key '%s' not found" % key)
new_value = value + delta
key = self.make_key(key, version=version)
- self._lock.writer_enters()
- try:
- pickled = pickle.dumps(new_value, pickle.HIGHEST_PROTOCOL)
- self._cache[key] = pickled
- except pickle.PickleError:
- pass
- finally:
- self._lock.writer_leaves()
+ with self._lock.writer():
+ try:
+ pickled = pickle.dumps(new_value, pickle.HIGHEST_PROTOCOL)
+ self._cache[key] = pickled
+ except pickle.PickleError:
+ pass
return new_value
def has_key(self, key, version=None):
key = self.make_key(key, version=version)
self.validate_key(key)
- self._lock.reader_enters()
- try:
+ with self._lock.reader():
exp = self._expire_info.get(key)
if exp is None:
return False
elif exp > time.time():
return True
- finally:
- self._lock.reader_leaves()
- self._lock.writer_enters()
- try:
+ with self._lock.writer():
try:
del self._cache[key]
del self._expire_info[key]
except KeyError:
pass
return False
- finally:
- self._lock.writer_leaves()
def _cull(self):
if self._cull_frequency == 0:
@@ -148,11 +131,8 @@ def _delete(self, key):
def delete(self, key, version=None):
key = self.make_key(key, version=version)
self.validate_key(key)
- self._lock.writer_enters()
- try:
+ with self._lock.writer():
self._delete(key)
- finally:
- self._lock.writer_leaves()
def clear(self):
self._cache.clear()
View
38 django/utils/synch.py
@@ -6,12 +6,16 @@
(Contributed to Django by eugene@lazutkin.com)
"""
+from __future__ import with_statement
+
+import contextlib
try:
import threading
except ImportError:
import dummy_threading as threading
-class RWLock:
+
+class RWLock(object):
"""
Classic implementation of reader-writer lock with preference to writers.
@@ -34,43 +38,41 @@ def __init__(self):
self.waiting_writers = 0
def reader_enters(self):
- self.mutex.acquire()
- try:
+ with self.mutex:
if self.active_writers == 0 and self.waiting_writers == 0:
self.active_readers += 1
self.can_read.release()
else:
self.waiting_readers += 1
- finally:
- self.mutex.release()
self.can_read.acquire()
def reader_leaves(self):
- self.mutex.acquire()
- try:
+ with self.mutex:
self.active_readers -= 1
if self.active_readers == 0 and self.waiting_writers != 0:
self.active_writers += 1
self.waiting_writers -= 1
self.can_write.release()
+
+ @contextlib.contextmanager
+ def reader(self):
+ self.reader_enters()
+ try:
+ yield
finally:
- self.mutex.release()
+ self.reader_leaves()
def writer_enters(self):
- self.mutex.acquire()
- try:
+ with self.mutex:
if self.active_writers == 0 and self.waiting_writers == 0 and self.active_readers == 0:
self.active_writers += 1
self.can_write.release()
else:
self.waiting_writers += 1
- finally:
- self.mutex.release()
self.can_write.acquire()
def writer_leaves(self):
- self.mutex.acquire()
- try:
+ with self.mutex:
self.active_writers -= 1
if self.waiting_writers != 0:
self.active_writers += 1
@@ -83,5 +85,11 @@ def writer_leaves(self):
while t > 0:
self.can_read.release()
t -= 1
+
+ @contextlib.contextmanager
+ def writer(self):
+ self.writer_enters()
+ try:
+ yield
finally:
- self.mutex.release()
+ self.writer_leaves()
Please sign in to comment.
Something went wrong with that request. Please try again.