-
-
Notifications
You must be signed in to change notification settings - Fork 67
Do not destroy co-routines too early. #26
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
Generally this look OK, thanks a lot for working on the patch! I think we need to extend the test suite to cover all of the possible cases, including your original case in the bug report, as well as other cases when the Task is ignored (but has a value). I have some tests locally, I'll push them when I get to my home computer and try to write some more :-) |
Hi. I've merged some additional test cases for Task (see #29) - unfortunately the tests don't pass with your patch. I'll get back to you when I figure out what's wrong :) |
With some small corrections to the tests, the sync coroutine test passes, but all the other tests fail with use-after-free error. Looks like when we destroy the coroutine in ~Task, it causes a use-after-free error in TaskFinalSuspend afterwards, since it checks whether the coroutine is done or not, using a handle to the now-destroyed coroutine. |
Co-routines returning immediately with co_return would have an invalid result, because the co-routine handle was destroyed before the caller had a chance to get the result. We do have to make sure to still destroy co-routines in final-suspend, if nobody is awaiting the result (e.g. when called from Qt's event loop). Fixes: qcoro#24
I have a fix for the use-after-free. The problem comes from the resuming of the mAwaitingCoroutine in final_suspend: when the With this version, all your tests on main pass, but I had to fix the life-time of the
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @rgriebl , sorry for the huge delay in review. I tried to come up with some solution myself but got stuck and eventually distracted by other work. Sadly, the holidays weren't as peaceful as I hoped :-)
Anyway, I please add the scope fix for the test coroutine that you posted in your comment, I think we could land the patch this way.
I'll try to get back to reworking the Task in some way that will solve this problem in some generic way.
if (mCoroutine.done() && !mCoroutine.promise().isInFinalSuspend()) | ||
mCoroutine.destroy(); | ||
else | ||
mCoroutine.promise().setDestroyOnFinalSuspend(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add braces, even for one-line if blocks.
Hi, there was another patch to solve this issue (#35) that goes basically the same way as yours, but the code is simpler (one atomics fewer) and has passing tests. I decided to merge that one. Apologies for not picking up your patch, hope you don't mind. |
Co-routines returning immediately with co_return would have an invalid
result, because the co-routine handle was destroyed before the caller
had a chance to get the result.
We do have to make sure to still destroy co-routines in final-suspend,
if nobody is awaiting the result (e.g. when called from Qt's event
loop).
Fixes: #24