-
Notifications
You must be signed in to change notification settings - Fork 52
Fix _QThreadWorker.run not releasing references to fulfilled command and result objects before blocking on next queue.get call #113
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
Conversation
2252042
to
3890145
Compare
Thinking about it, the |
Hi @hosaka , hope you are well. Sorry for a direct mention, but you were the last person ever active in this repository. May I ask you if it is possible to get this PR reviewed or approved and merged? Regards,
|
Hello @kormax , I am a bit concerned about an effect this will have on QObjects, because the ownership/lifetime is managed internally in PySide at least (Shiboken). You do mention it as a "potential downside", I think this could be an issue for code that uses QObjects and Slots and most of the code using this library probably does use QObjects. At least some tests should be performed to see if this might cause a double free. |
After a bit of testing with QObjects and a codebase of mine that relies on qasync I can see no issues related to this change, including parent-child objects. Just like the comments in cpython issue state, the worker should not keep these references. @kormax it would be nice to have a new test in |
NP. Gonna add this change a bit later . |
d019e53
to
8df9bb7
Compare
After looking at the problem again, it turned out that pytest or some other testing utilities affect the behavior of LogRecord, causing it to keep references to all objects in the scope where Disabling logging for To verify that new tests actually test the behavior, I suggest to comment out new lines added to _QThreadWorker, and observing that the tests will fail after that. |
…and result objects before blocking on next queue.get call
8df9bb7
to
cca1617
Compare
Great work, thanks @kormax! I've remove |
When writing tests, I've noticed that when using
qasync.QThreadExecutor
, the objects, be it instance method owners, or something passed in as args, were not deleted immediately as the executor finished running the submitted task, even if there were no more references to those objects on the user side. The only way to release them was either to submit a new task, or shutdown an executor.While investigating the code, I've also taken a look into
concurrent.futures.ThreadPoolExecutor
, which didn't exhibit this behaviour.That's where I found the following code:
This PR mimics this change by adding a manual deletion of references to command tuple and its inner parameters inside of
_QThreadWorker.run
;The change can be tested by running the following example:
Before:
After:
As for potential downsides of this change: there could theoretically be code that accidentally relies on QThreadExecutor not releasing references, especially if QObject, Slots and other Qt-related stuff is involved.
But even if it's a big issue, it still might be worth adding an option to enable proper behaviour via an environment variable or other parameter.