-
Notifications
You must be signed in to change notification settings - Fork 19
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
Why the support for cancellation is removed? #27
Comments
Because it was slow and greatly complicated the implementation. I was planning implement a variation based on stop_token but I was busy on other things. |
@rzbdz I have seen your implementation. However since your task is lazy ( you can't start a task without waiting for its completion ), I don't think your cancel operation is very useful. |
You are right. |
Well, the problem is that people usually want their tasks getting cancelled ( clean up the context ) when something bad happens. For example when an exception is thrown, cancel all pending tasks in destructors. However, cancellation for io_uring is also async, which is problematic because destructors in C++ cannot be a coroutine. In addition, cancellation for io_uring won't always succeed, which is even more problematic because people usually want to free the buffers provided for That makes cancellation for io_uring is very hard to use in C++. I don't find a solution yet. |
IMHO laziness coroutines are pretty much useless because laziness coroutines cannot be run in parallel. If we must wait for every io task's completion immediately, why not use the old sync version ( read(2) / accept4(2) ) directly? io_uring is built for parallel and laziness coroutines make the async interface of io_uring meaningless. Yes we have
while (true) {
auto clientfd = co_await accept(serverfd);
/* no co_await */ ([clientfd]() {
// sub coroutine for clientfd
co_await recv(clientfd, buf);
// handle buf
})();
} Since sub coroutine won't block the main coroutine, we can still accept for new connection when waiting for IO tasks in sub coroutine. With laziness coroutines I don't know how I can do that. |
And you are right, it make sense. I will take a look if I really need laziness task. For now, I think An example would be like this: task<> echo(...){
// sub coroutine for clientfd
co_await recv(clientfd, buf);
// handle buf
}
task<void> listener()
{
auto exec = something::get_executor_on_this_thread();
for (;;)
{
auto socket = co_await async_accept();
// what co_spawn does is simply
// do sth like:
// []()->not_lazy<>{ co_await echo(...); } ();
// where not_lazy<> won't block,
// instead detached from current coroutine
// Or do more thing you want to,
// maybe run on another thread etc..
co_spawn(exec, echo(std::move(socket)));
}
} I think one of the benefits laziness task brings is that you can move coroutine to another thread, say if a coroutine want to use another It's like something more general but roundabout , you can use it as if it's lazy or not lazy with Maybe I should make the Thank you for a detailed explanation. |
I think async_scope and spawn semantic (https://github.com/lewissbaker/cppcoro/blob/master/include/cppcoro/async_scope.hpp) would do what you describe, it's just bring another function call. And you are right, it make sense. I will take a look if I really need laziness task. Maybe I should make the task not lazy anymore and introduce another lazy<> coroutine. Thank you for a detailed explaination.
发自我的小米手机
在 Carter Li ***@***.***>,2022年4月3日 23:43写道:
You are right. Actually I didn't know how to implement one and the one you mention is indeed useless now. I am just wandering around to see if someone else have a solution 👀
IMHO I think laziness coroutines are pretty much useless. Laziness coroutines cannot be run in parallel. If we must wait for every io task's completion immediately, why not use the old sync version directly? io_uring is built for parallel and laziness coroutines make the async interface of io_uring meaningless.
Yes we have when_all when_any, but
1. you can't implement when_* with lazy coroutines.
2. you can't detach a coroutine. Imaging you have a server pending for connections. You want to create independent coroutines for every client.
while (true) {
auto clientfd = co_await accept(serverfd);
/* no co_await */ ([clientfd]() {
// sub coroutine for clientfd
co_await recv(clientfd, buf);
// handle buf
})();
}
Since sub coroutine won't block the main coroutine, we can still accept for new connection when waiting for IO tasks in sub coroutine. With laziness coroutines I don't know how I can do that.
—
Reply to this email directly, view it on GitHub<#27 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AELB23XT7ZW5XSH7ICETJ3TVDG4CLANCNFSM5SNGDUEQ>.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
We now have sync cancel History: axboe/liburing#608 |
I found that one of the very old versions have a file
promise.hpp
and it supports cancellation but was removed later.The text was updated successfully, but these errors were encountered: