-
-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Try to solve deadlock when deallocating Python objects in threads #255
Conversation
I suppose the issue here is in the test itself, as this change makes it pass on my local machine: modified lupa/tests/test.py
@@ -103,14 +103,13 @@ class TestLuaRuntimeRefcounting(LupaTestCase):
self._run_gc_test(make_refcycle, off_by_one=True)
def test_lupa_gc_deadlock(self):
- lua = self.lupa.LuaRuntime()
-
def assert_no_deadlock(thread):
thread.start()
thread.join(1)
assert not thread.is_alive(), "thread didn't finish - deadlock?"
def delete_table_reference_in_thread():
+ lua = self.lupa.LuaRuntime()
ref = [lua.eval("{}")]
def trigger_gc(ref): |
@scoder Did you get the chance to try out my previous comment from last month? |
I had looked at it when you wrote it and wasn't sure. The difference is that, in your proposal, the Lua runtime gets cleaned up after each run, thus clearing all objects and freeing all memory. It's good to know that that doesn't leave anything behind, but my implementation wanted to make sure that the objects get cleaned up as early as possible (and safe), preferably before returning from Lua to Python, and not just kept around unnecessarily. Your change doesn't test that any more. I still think there's something wrong (or hopefully only missing) in my implementation. |
I took another look and it turns out that most of the excess references in the test are cleaned up by triggering a run of the Lua garbage collector. Most, but not all. There's around 20 remaining references that are created by the test and not cleaned up afterwards:
The test passes the Thread object through Lua and it's not obvious if some of these are related to that. |
I don't know much about GC, but isn't this due to Lua not using a reference count approach? What I imagine is, with reference counts you can deallocate objects as soon as the count reaches 0, but with other GC approaches every object survives at least until the next GC cycle runs.
In other words, in Lua you wouldn't expect that GC always runs before returning to Python. Anyway, this is just a wild hunch. I went through the old version of this PR and couldn't spot anything missing in it. |
I think it's too difficult to test correctly for reference leaks here, so the test sadly has to go without that. I simplified it. |
Closes #250