Skip to content
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

Awaiting with context object. #115

Open
jbruechert opened this issue Aug 17, 2022 · 2 comments · May be fixed by #117
Open

Awaiting with context object. #115

jbruechert opened this issue Aug 17, 2022 · 2 comments · May be fixed by #117

Comments

@jbruechert
Copy link
Contributor

In some cases, one might want to update an object (for example a model), when a coroutine finished.
This can be done by either using a lambda that captures this as a coroutine, or by adding a coroutine member function.
However there is no guarantee that once the coroutine finishes, the object still exists, so this can lead to crashes.

It is pretty much the same issue as the 3-arg connect in Qt: https://github.com/KDE/clazy/blob/master/docs/checks/README-connect-3arg-lambda.md

Is this already a solved problem in some way that I have missed?

If not, I propose adding an overload of QCoro::Task<T>::then that takes a QObject pointer as an additional argument, so that it can connect to QObject::destroyed of the context object, and not invoke the continuation if the signal has been emitted in the meantime.

I currently can't find a good way to fix this when using the co_await keyword, but as this mostly concerns the issue of interaction between coroutine code and sync code, support in .then is probably enough.

If needed, there could be something like

co_await someFunctionReturningTask().withContext(this)

to inject the context even though using co_await.

I already have code for some of the proposed things here, so I can work on implementing it if needed.

@danvratil
Copy link
Collaborator

Hi Jonah,

adding the context to .then() makes sense, but I think it's not as simple as it sounds:

QCoro::Task<int> task = gimmeTask();
const auto result = co_await task.then(someObject, [someObject](int result) {
    return someObject->magicalNumber() + result;
});

If someObject is destroyed while the task is still running, you will skip calling the .then() continuation, but now you need to figure out what to do with the co_await, because you don't have a result for it. Should it simply not be resumed, ever? This might make the application stuck...

One option would be to join this with the #107 and allow context object only on CancellableTask<T>::then(), where the result of the chain would be a cancelled Result<U>, if the context object was destroyed.

@jbruechert
Copy link
Contributor Author

That seems like a good idea!

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

Successfully merging a pull request may close this issue.

2 participants