-
Notifications
You must be signed in to change notification settings - Fork 454
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
Implement io_service::process_events_until_complete #69
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,6 +79,13 @@ namespace cppcoro | |
const std::chrono::duration<REP, PERIOD>& delay, | ||
cancellation_token cancellationToken = {}) noexcept; | ||
|
||
/// Process events until the task completes. | ||
/// | ||
/// \return | ||
/// Result of the co_await task. | ||
template<typename TASK> | ||
decltype(auto) process_events_until_complete(TASK&& task); | ||
|
||
/// Process events until the io_service is stopped. | ||
/// | ||
/// \return | ||
|
@@ -178,6 +185,26 @@ namespace cppcoro | |
|
||
}; | ||
|
||
template<typename TASK> | ||
decltype(auto) io_service::process_events_until_complete(TASK&& task) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This implementation should work just fine for the cases where there is only a single thread processing events, but if there are multiple threads processing events then calling To implement support for this behaviour would require integration into the core event loop within It will also need to change a little once the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be clear, I'm happy with the implementation as it is for now. I'll think further about whether it makes sense to limit its use to the single-threaded event processing case or to use a more complicated implementation that allows for boost-blocking use-cases with multiple I/O threads. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll try to make it work with multiple threads. I think it may be possible to do it without polling. FWIW I think that this function is semantically similar to |
||
{ | ||
if (!task.is_ready()) | ||
{ | ||
auto callback = [](void* io) noexcept | ||
{ | ||
static_cast<io_service*>(io)->stop(); | ||
}; | ||
|
||
auto starter = task.get_starter(); | ||
starter.start(cppcoro::detail::continuation{ callback, this }); | ||
|
||
process_events(); | ||
reset(); | ||
} | ||
|
||
return std::forward<TASK>(task).operator co_await().await_resume(); | ||
} | ||
|
||
class io_service::schedule_operation | ||
{ | ||
public: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -226,4 +226,40 @@ TEST_CASE_FIXTURE(io_service_fixture_with_threads<1>, "Many concurrent timers") | |
<< "ms"); | ||
} | ||
|
||
TEST_CASE("io_service::process_events_until_complete(task<T>)") | ||
{ | ||
cppcoro::io_service ioService; | ||
|
||
auto makeTask = [](cppcoro::io_service& io) -> cppcoro::task<std::string> | ||
{ | ||
co_await io.schedule(); | ||
co_return "foo"; | ||
}; | ||
|
||
auto task = makeTask(ioService); | ||
|
||
CHECK(ioService.process_events_until_complete(task) == "foo"); | ||
CHECK(task.is_ready()); | ||
CHECK(ioService.process_events_until_complete(task) == "foo"); | ||
CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); | ||
} | ||
|
||
TEST_CASE("io_service::process_events_until_complete(shared_task<T>)") | ||
{ | ||
cppcoro::io_service ioService; | ||
|
||
auto makeTask = [](cppcoro::io_service& io) -> cppcoro::shared_task<std::string> | ||
{ | ||
co_await io.schedule(); | ||
co_return "foo"; | ||
}; | ||
|
||
auto task = makeTask(ioService); | ||
|
||
CHECK(ioService.process_events_until_complete(task) == "foo"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you be able to add an extra test in here for passing the already-completed |
||
CHECK(task.is_ready()); | ||
CHECK(ioService.process_events_until_complete(task) == "foo"); | ||
CHECK(ioService.process_events_until_complete(makeTask(ioService)) == "foo"); | ||
} | ||
|
||
TEST_SUITE_END(); |
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.
Thanks :)