Skip to content
This repository has been archived by the owner on Apr 22, 2020. It is now read-only.

singleton_context_manager does not play well with RLock #44

Open
idanarye opened this issue Aug 30, 2017 · 0 comments
Open

singleton_context_manager does not play well with RLock #44

idanarye opened this issue Aug 30, 2017 · 0 comments

Comments

@idanarye
Copy link

from easypy.decorations import singleton_contextmanager_method
from threading import RLock, Thread, Event
from time import sleep


def test_singleton_contextmanager_method_with_rlocks_bad_order():
    class Foo:
        lock = RLock()

        @singleton_contextmanager_method
        def cm(self):
            with self.lock:
                yield

    foo = Foo()
    event1 = Event()
    event2 = Event()

    def lock_and_wait(event):
        with foo.cm():
            event.wait()

    thread1 = Thread(target=lock_and_wait, args=(event1,))
    thread1.start()
    sleep(1)
    thread2 = Thread(target=lock_and_wait, args=(event2,))
    thread2.start()

    event1.set()
    thread1.join()

    event2.set()
    thread2.join()

Running this test prints:

$ py.test tests/ -s -k test_singleton_contextmanager_method_with_rlocks_bad_order
========================================== test session starts ===========================================
platform linux -- Python 3.6.2, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
rootdir: /files/code/easypy, inifile: pytest.ini
collected 118 items

tests/test_decorations.py Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/files/code/easypy/tests/test_decorations.py", line 87, in lock_and_wait
    event.wait()
  File "/usr/lib/python3.6/contextlib.py", line 88, in __exit__
    next(self.gen)
  File "/files/code/easypy/easypy/decorations.py", line 114, in inner
    yield val
  File "/files/code/easypy/easypy/decorations.py", line 90, in __exit__
    self.ctm.__exit__(*sys.exc_info())
  File "/usr/lib/python3.6/contextlib.py", line 88, in __exit__
    next(self.gen)
  File "/files/code/easypy/tests/test_decorations.py", line 79, in cm
    yield
RuntimeError: cannot release un-acquired lock

.

========================================== 117 tests deselected ==========================================
================================ 1 passed, 117 deselected in 1.31 seconds ================================

(the test still passes, but there is an exception in a thread)

The problem here is that we lock in thread1 - the first thread to enter the singleton contextmanager - and release in thread2 - the last thread to exit the singleton contextmanager.

I'm... not really sure if we can fix this...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant