diff options
author | Soren Hansen <soren@linux2go.dk> | 2011-03-22 14:14:47 +0100 |
---|---|---|
committer | Soren Hansen <soren@linux2go.dk> | 2011-03-22 14:14:47 +0100 |
commit | 60a3aa86db1d0e1ea2f680c9587881e45fa99336 (patch) | |
tree | 59847656ca6d2f3326e80848822e7deb6f520f8b /nova/utils.py | |
parent | d1860ce5d26fbbadb2310e8225e924879cde9a6c (diff) | |
download | nova-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.py | 18 |
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 |