diff --git a/src/extrainterpreters/lock.py b/src/extrainterpreters/lock.py index ae46f35..92971d0 100644 --- a/src/extrainterpreters/lock.py +++ b/src/extrainterpreters/lock.py @@ -147,13 +147,11 @@ def __init__(self): def acquire(self, blocking=True, timeout=-1): if blocking: timeout = TIMEOUT_MAX if timeout == -1 or not blocking else timeout - self._lock.timeout(timeout) - self._lock.__enter__() + self._lock.acquire(timeout) return True else: - self._lock.timeout(None) try: - self._lock.__enter__() + self._lock.acquire(None) except ResourceBusyError: return False return True diff --git a/tests/test_lock.py b/tests/test_lock.py index 157b114..90e86f2 100644 --- a/tests/test_lock.py +++ b/tests/test_lock.py @@ -1,4 +1,6 @@ import pickle +import threading +import time from functools import partial from textwrap import dedent as D @@ -71,6 +73,32 @@ def test_lock_cant_be_reacquired_other_interpreter(interpreter): run (f"lock.release()") + +def test_lock_works_across_threads_in_same_interpreter(): + lock = Lock() + results = [] + def aux1(): + # assert code does't work in nested functions + results.append((lock.acquire(blocking=False), "aux1 - first lock, should work")) + time.sleep(0.1) + lock.release() + def aux2(): + time.sleep(0.025) + results.append((not lock.acquire(blocking=False), "aux2 - first lock, should fail")) + time.sleep(0.085) + results.append((lock.acquire(blocking=False), "aux2 - second lock, should work")) + if lock.locked(): + lock.release() + t1 = threading.Thread(target=aux1) + t2 = threading.Thread(target=aux2) + t1.start(); t2.start() + + t1.join(); t2.join() + + for status, message in results: + assert status, message + + @pytest.mark.parametrize("LockCls", [Lock, RLock, IntRLock]) def test_locks_can_be_passed_to_other_interpreter(LockCls, interpreter): lock = LockCls()