summaryrefslogtreecommitdiffstats
path: root/nova/utils.py
diff options
context:
space:
mode:
authorSoren Hansen <soren@linux2go.dk>2011-03-22 14:14:47 +0100
committerSoren Hansen <soren@linux2go.dk>2011-03-22 14:14:47 +0100
commit60a3aa86db1d0e1ea2f680c9587881e45fa99336 (patch)
tree59847656ca6d2f3326e80848822e7deb6f520f8b /nova/utils.py
parentd1860ce5d26fbbadb2310e8225e924879cde9a6c (diff)
downloadnova-60a3aa86db1d0e1ea2f680c9587881e45fa99336.tar.gz
nova-60a3aa86db1d0e1ea2f680c9587881e45fa99336.tar.xz
nova-60a3aa86db1d0e1ea2f680c9587881e45fa99336.zip
Make synchronized decorator not leak semaphores, at the expense of not being truly thread safe (but safe enough for Eventlet style green threads).
Diffstat (limited to 'nova/utils.py')
-rw-r--r--nova/utils.py18
1 files changed, 13 insertions, 5 deletions
diff --git a/nova/utils.py b/nova/utils.py
index 8936614cc..c580e805a 100644
--- a/nova/utils.py
+++ b/nova/utils.py
@@ -574,10 +574,12 @@ def synchronized(name, external=False):
def wrap(f):
@functools.wraps(f)
def inner(*args, **kwargs):
- with _semaphores_semaphore:
- if name not in _semaphores:
- _semaphores[name] = semaphore.Semaphore()
- sem = _semaphores[name]
+ # NOTE(soren): If we ever go natively threaded, this will be racy.
+ # See http://stackoverflow.com/questions/5390569/dyn\
+ # amically-allocating-and-destroying-mutexes
+ if name not in _semaphores:
+ _semaphores[name] = semaphore.Semaphore()
+ sem = _semaphores[name]
LOG.debug(_('Attempting to grab semaphore "%(lock)s" for method '
'"%(method)s"...' % {"lock": name,
"method": f.__name__}))
@@ -593,8 +595,14 @@ def synchronized(name, external=False):
lock = _NoopContextManager()
with lock:
- return f(*args, **kwargs)
+ retval = f(*args, **kwargs)
+ # If no-one else is waiting for it, delete it.
+ # See note about possible raciness above.
+ if not sem.balance < 1:
+ del _semaphores[name]
+
+ return retval
return inner
return wrap