Exit stack and py2.6 with locks do not work
Due to https://bitbucket.org/ncoghlan/contextlib2/issue/17/ it appears the the exit stack has issues with locks on py2.6 so use a smaller implementation that does the same thing instead.
This commit is contained in:
@@ -23,6 +23,30 @@ except ImportError:
|
||||
from time import time as now
|
||||
|
||||
|
||||
class LockStack(object):
|
||||
"""Simple lock stack to get and release many locks."""
|
||||
|
||||
def __init__(self):
|
||||
self._stack = []
|
||||
|
||||
def acquire_lock(self, lock):
|
||||
gotten = lock.acquire()
|
||||
self._stack.append(lock)
|
||||
return gotten
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, exc_tb):
|
||||
while self._stack:
|
||||
lock = self._stack.pop()
|
||||
try:
|
||||
lock.release()
|
||||
except Exception:
|
||||
# Always suppress this exception...
|
||||
pass
|
||||
|
||||
|
||||
class StopWatch(object):
|
||||
"""A really basic stop watch."""
|
||||
|
||||
|
||||
@@ -17,15 +17,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
try:
|
||||
from contextlib import ExitStack # noqa
|
||||
except ImportError:
|
||||
from contextlib2 import ExitStack # noqa
|
||||
|
||||
import collections
|
||||
import contextlib
|
||||
import threading
|
||||
|
||||
from fasteners import _utils
|
||||
|
||||
import six
|
||||
|
||||
try:
|
||||
@@ -273,9 +270,9 @@ def locked(*args, **kwargs):
|
||||
def wrapper(self, *args, **kwargs):
|
||||
attr_value = getattr(self, attr_name)
|
||||
if isinstance(attr_value, (tuple, list)):
|
||||
with ExitStack() as stack:
|
||||
with _utils.LockStack() as stack:
|
||||
for lock in attr_value:
|
||||
stack.enter_context(lock)
|
||||
stack.acquire_lock(lock)
|
||||
return f(self, *args, **kwargs)
|
||||
else:
|
||||
lock = attr_value
|
||||
|
||||
@@ -32,6 +32,22 @@ class Locked(object):
|
||||
cb(self._lock.locked())
|
||||
|
||||
|
||||
class ManyLocks(object):
|
||||
def __init__(self, amount):
|
||||
self._lock = []
|
||||
for _i in range(0, amount):
|
||||
self._lock.append(threading.Lock())
|
||||
|
||||
@fasteners.locked
|
||||
def i_am_locked(self, cb):
|
||||
gotten = [lock.locked() for lock in self._lock]
|
||||
cb(gotten)
|
||||
|
||||
def i_am_not_locked(self, cb):
|
||||
gotten = [lock.locked() for lock in self._lock]
|
||||
cb(gotten)
|
||||
|
||||
|
||||
class RWLocked(object):
|
||||
def __init__(self):
|
||||
self._lock = fasteners.ReaderWriterLock()
|
||||
@@ -54,6 +70,11 @@ class DecoratorsTest(test.TestCase):
|
||||
obj.i_am_locked(lambda is_locked: self.assertTrue(is_locked))
|
||||
obj.i_am_not_locked(lambda is_locked: self.assertFalse(is_locked))
|
||||
|
||||
def test_many_locked(self):
|
||||
obj = ManyLocks(10)
|
||||
obj.i_am_locked(lambda gotten: self.assertTrue(all(gotten)))
|
||||
obj.i_am_not_locked(lambda gotten: self.assertEqual(0, sum(gotten)))
|
||||
|
||||
def test_read_write_locked(self):
|
||||
reader = fasteners.ReaderWriterLock.READER
|
||||
writer = fasteners.ReaderWriterLock.WRITER
|
||||
|
||||
Reference in New Issue
Block a user