def test_untraceable_lock_uses_different_lock(self): if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None PY3 = sys.version_info[0] > 2 lst = [] # we should be able to use unrelated locks from within the trace function l = allocate_lock() try: def trace(frame, ev, _arg): with l: lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) print("TRACE: %s:%s %s" % lst[-1]) return trace l2 = allocate_lock() sys.settrace(trace) # Separate functions, not the C-implemented `with` so the trace # function gets a crack at them l2.acquire() l2.release() finally: sys.settrace(old) if not PY3: # Py3 overrides acquire in Python to do argument checking self.assertEqual(lst, [], "trace not empty") else: # Have an assert so that we know if we miscompile self.assertTrue(lst, "should not compile on pypy")
def test_untraceable_lock_uses_different_lock(self): if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None PYPY = hasattr(sys, 'pypy_version_info') PY3 = sys.version_info[0] > 2 lst = [] # we should be able to use unrelated locks from within the trace function l = allocate_lock() try: def trace(frame, ev, arg): with l: lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) if not PYPY: # because we expect to trace on PyPy print("TRACE: %s:%s %s" % lst[-1]) return trace l2 = allocate_lock() sys.settrace(trace) # Separate functions, not the C-implemented `with` so the trace # function gets a crack at them l2.acquire() l2.release() finally: sys.settrace(old) if not PYPY and not PY3: # Py3 overrides acquire in Python to do argument checking self.assertEqual(lst, [], "trace not empty") else: # Have an assert so that we know if we miscompile self.assertTrue(len(lst) > 0, "should not compile on pypy")
def test_untraceable_lock(self): # Untraceable locks were part of the solution to https://bugs.python.org/issue1733757 # which details a deadlock that could happen if a trace function invoked # threading.currentThread at shutdown time---the cleanup lock would be held # by the VM, and calling currentThread would try to acquire it again. The interpreter # changed in 2.6 to use the `with` statement (https://hg.python.org/cpython/rev/76f577a9ec03/), # which apparently doesn't trace in quite the same way. if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None lst = [] try: def trace(frame, ev, _arg): lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) print("TRACE: %s:%s %s" % lst[-1]) return trace with allocate_lock(): sys.settrace(trace) finally: sys.settrace(old) self.assertEqual(lst, [], "trace not empty")
def test_untraceable_lock_uses_same_lock(self): from gevent.hub import LoopExit if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None PY3 = sys.version_info[0] > 2 lst = [] e = None # we should not be able to use the same lock from within the trace function # because it's over acquired but instead of deadlocking it raises an exception l = allocate_lock() try: def trace(frame, ev, _arg): with l: lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) return trace sys.settrace(trace) # Separate functions, not the C-implemented `with` so the trace # function gets a crack at them l.acquire() except LoopExit as ex: e = ex finally: sys.settrace(old) if not PY3: # Py3 overrides acquire in Python to do argument checking self.assertEqual(lst, [], "trace not empty") else: # Have an assert so that we know if we miscompile self.assertTrue(lst, "should not compile on pypy") self.assertTrue(isinstance(e, LoopExit))
def test_untraceable_lock(self): # Untraceable locks were part of the solution to https://bugs.python.org/issue1733757 # which details a deadlock that could happen if a trace function invoked # threading.currentThread at shutdown time---the cleanup lock would be held # by the VM, and calling currentThread would try to acquire it again. The interpreter # changed in 2.6 to use the `with` statement (https://hg.python.org/cpython/rev/76f577a9ec03/), # which apparently doesn't trace in quite the same way. if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None PYPY = hasattr(sys, 'pypy_version_info') lst = [] try: def trace(frame, ev, arg): lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) if not PYPY: # because we expect to trace on PyPy print("TRACE: %s:%s %s" % lst[-1]) return trace with allocate_lock(): sys.settrace(trace) finally: sys.settrace(old) if not PYPY: self.assertEqual(lst, [], "trace not empty") else: # Have an assert so that we know if we miscompile self.assertTrue(len(lst) > 0, "should not compile on pypy")
def test_untraceable_lock_uses_same_lock(self): from gevent.hub import LoopExit if hasattr(sys, 'gettrace'): old = sys.gettrace() else: old = None PYPY = hasattr(sys, 'pypy_version_info') PY3 = sys.version_info[0] > 2 lst = [] e = None # we should not be able to use the same lock from within the trace function # because it's over acquired but instead of deadlocking it raises an exception l = allocate_lock() try: def trace(frame, ev, arg): with l: lst.append((frame.f_code.co_filename, frame.f_lineno, ev)) return trace sys.settrace(trace) # Separate functions, not the C-implemented `with` so the trace # function gets a crack at them l.acquire() except LoopExit as ex: e = ex finally: sys.settrace(old) if not PYPY and not PY3: # Py3 overrides acquire in Python to do argument checking self.assertEqual(lst, [], "trace not empty") else: # Have an assert so that we know if we miscompile self.assertTrue(len(lst) > 0, "should not compile on pypy") self.assertTrue(isinstance(e, LoopExit))
def __init__(self, expired_minutes: int = 120): assert expired_minutes > 0, f"'expired_minutes' must be greater than 0" self._db_lock = allocate_lock() self._db: Dict[P, T] = dict() self._expired: Dict[P, datetime] = dict() self._expired_minutes = expired_minutes
def test_release_unheld_lock(self): std_lock = std_allocate_lock() g_lock = allocate_lock() with self.assertRaises(Exception) as exc: std_lock.release() std_exc = exc.exception with self.assertRaises(Exception) as exc: g_lock.release() g_exc = exc.exception self.assertIsInstance(g_exc, type(std_exc))
def test_release_unheld_lock(self): std_lock = std_allocate_lock() g_lock = allocate_lock() try: std_lock.release() self.fail("Should have thrown an exception") except Exception as e: std_exc = e try: g_lock.release() self.fail("Should have thrown an exception") except Exception as e: g_exc = e self.assertTrue(isinstance(g_exc, type(std_exc)), (g_exc, std_exc))
def test_release_unheld_lock(self): std_lock = std_allocate_lock() g_lock = allocate_lock() try: std_lock.release() self.fail("Should have thrown an exception") except Exception as e: std_exc = e try: g_lock.release() self.fail("Should have thrown an exception") except Exception as e: g_exc = e self.assertIsInstance(g_exc, type(std_exc))
def allocate_lock(*args): return green_thread.allocate_lock()