Skip to content

Commit

Permalink
Relax AwaitableStateChecker and fix AwaitableLambda
Browse files Browse the repository at this point in the history
1. `MuxHelper` calls `await_set_executor()` even when the underlying awaitable
has returned `true` from `await_ready()`. The `AwaitableStateChecker` does not
allow this. We discussed several other options, but for now this is the least
intrusive "fix" to stop ASSERT-failing in `linux.debug` variants.

2. We may call `AwaitableLambda::await_early_cancel()` after calling
`AwaitableLambda:: await_set_executor()`. As far as I can tell,
AwaitableStateChecker::earlyCancelReturned() does not disallow this.
Let's not ASSERT-fail on this.
  • Loading branch information
andreimaximov authored and dprokoptsev committed Mar 25, 2024
1 parent 48b7621 commit d399355
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 16 deletions.
30 changes: 16 additions & 14 deletions corral/detail/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,9 @@ struct AwaitableStateChecker : ProxyFrame {
break;
case State::ReadyImmediately:
case State::ReadyAfterCancel:
// Redundant readiness check is allowed as long as we haven't
// suspended yet (which hasExecutor is a proxy for) and
// we don't backtrack in readiness
CORRAL_ASSERT(!hasExecutor_ && val);
// Redundant readiness check is allowed as long as we don't
// backtrack in readiness
CORRAL_ASSERT(val);
break;
default:
CORRAL_ASSERT_UNREACHABLE();
Expand Down Expand Up @@ -268,7 +267,8 @@ struct AwaitableStateChecker : ProxyFrame {
void aboutToSetExecutor() noexcept {
CORRAL_ASSERT(
state_ == State::NotReady || state_ == State::CancelPending ||
state_ == State::Initial || state_ == State::InitialCxlPend);
state_ == State::ReadyImmediately || state_ == State::Initial ||
state_ == State::InitialCxlPend);
hasExecutor_ = true;
}
Handle aboutToSuspend(Handle h) noexcept {
Expand Down Expand Up @@ -404,22 +404,15 @@ template <class Callable> class AwaitableLambda {
bool await_ready() const noexcept { return false; }

void await_set_executor(Executor* ex) noexcept {
if (!task_) {
task_ = callable_();
awaitable_ = task_.operator co_await();
}
awaitable_.await_set_executor(ex);
awaitable().await_set_executor(ex);
}
auto await_suspend(Handle h) { return awaitable_.await_suspend(h); }
decltype(auto) await_resume() {
return std::forward<AwaitableT>(awaitable_).await_resume();
}

auto await_early_cancel() noexcept {
CORRAL_ASSERT(!task_);
task_ = callable_();
awaitable_ = task_.operator co_await();
return awaitable_.await_early_cancel();
return awaitable().await_early_cancel();
}
auto await_cancel(Handle h) noexcept { return awaitable_.await_cancel(h); }
auto await_must_resume() const noexcept {
Expand All @@ -431,6 +424,15 @@ template <class Callable> class AwaitableLambda {
}

private:
AwaitableT& awaitable() {
if (!task_) {
task_ = callable_();
awaitable_ = task_.operator co_await();
}

return awaitable_;
}

Callable callable_;
TaskT task_;
AwaitableT awaitable_;
Expand Down
15 changes: 15 additions & 0 deletions test/basic_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,11 @@ CORRAL_TEST_CASE("anyof") {
CATCH_CHECK(&*rx == &x);
CATCH_CHECK(!s2);
}

CATCH_SECTION("immediate-lambda") {
co_await anyOf(Ready{}, [&]() -> Task<> { co_await t.sleep(1ms); });
CATCH_CHECK(t.now() == 0ms);
}
}

CORRAL_TEST_CASE("mostof") {
Expand Down Expand Up @@ -394,6 +399,16 @@ CORRAL_TEST_CASE("allof") {
CATCH_CHECK(t.now() == 5ms);
}

CATCH_SECTION("immediate-front") {
co_await allOf(Ready{}, [&t]() -> Task<> { co_await t.sleep(1ms); });
CATCH_CHECK(t.now() == 1ms);
}

CATCH_SECTION("immediate-back") {
co_await allOf([&t]() -> Task<> { co_await t.sleep(1ms); }, Ready{});
CATCH_CHECK(t.now() == 1ms);
}

CATCH_SECTION("empty") {
auto r = co_await allOf();
static_assert(std::tuple_size_v<decltype(r)> == 0);
Expand Down
4 changes: 2 additions & 2 deletions test/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Expand Down

0 comments on commit d399355

Please sign in to comment.