Skip to content

Commit

Permalink
Cancel the timeout in timed_wait on success
Browse files Browse the repository at this point in the history
Summary:
`timed_wait` is not expected to frequently time-out, so by canceling the timer we can save a wake-up of the future timekeeper eventbase.

In reality we don't always save it because in order to cancel the timeout we have to enqueue a task in the eventbase, which also may wake it up, unless the queue is already non-empty in which case we can enjoy some batching, but on average this should be a minor improvement (and we may optimize that separately).

Other timeout primitives like `folly::coro::timeout` already do this.

Reviewed By: dmm-fb

Differential Revision: D48832670

fbshipit-source-id: c3534aa067b7e49b44954b5f81938754e2d6eefd
  • Loading branch information
ot authored and facebook-github-bot committed Aug 31, 2023
1 parent fa4c8e8 commit 13897bc
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions folly/experimental/coro/TimedWait.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ timed_wait(Awaitable awaitable, Duration duration) {
detail::lift_lvalue_reference_t<semi_await_result_t<Awaitable>>>>>
result;

Executor* executor = co_await co_current_executor;
auto sleepFuture = futures::sleep(duration).toUnsafeFuture();
auto posted = new std::atomic<bool>(false);
std::move(sleepFuture)
.setCallback_([posted, &baton, executor = co_await co_current_executor](
auto&&, auto&&) {
sleepFuture.setCallback_(
[posted, &baton, executor = Executor::KeepAlive<>{executor}](
auto&&, auto&&) {
if (!posted->exchange(true, std::memory_order_acq_rel)) {
executor->add([&baton] { baton.post(); });
} else {
Expand All @@ -58,9 +59,10 @@ timed_wait(Awaitable awaitable, Duration duration) {
awaitable)]() mutable -> Task<semi_await_result_t<Awaitable>> {
co_return co_await std::move(awaitable);
});
std::move(t)
.scheduleOn(co_await co_current_executor)
.start([posted, &baton, &result](auto&& r) {
std::move(t).scheduleOn(executor).start(
[posted, &baton, &result, sleepFuture = std::move(sleepFuture)](
auto&& r) mutable {
sleepFuture.cancel();
if (!posted->exchange(true, std::memory_order_acq_rel)) {
result = std::move(r);
baton.post();
Expand Down

0 comments on commit 13897bc

Please sign in to comment.