Commit 310a5f37 authored by Lewis Baker's avatar Lewis Baker Committed by Facebook Github Bot

Make folly::coro::Baton awaitable

Summary:
Remove the `waitAsync()` method from `folly::coro::Baton` and provide an `operator co_await()` instead.

 This moves the method to be consistent with other folly::coro APIs that use the convention of prefixing the method with co_ when the return-value is an awaitable type.

 In this case it seemed better to allow `co_await baton;` rather than use the potentially confusing `co_await baton.co_wait()` method as the `co_wait` method name seemed too close to and easily confused with the `co_await` keyword.

Reviewed By: andriigrynenko

Differential Revision: D9308773

fbshipit-source-id: 922793a83306e5b1e5e60c69b47b98a9bdd17d8d
parent be0d65cb
......@@ -25,8 +25,9 @@ namespace coro {
/// coroutine to co_await the baton and suspend until the baton is posted
/// by some other thread via a call to .post().
///
/// The Baton supports multiple awaiting coroutines at a time. When the
/// baton is posted, all awaiting coroutines are resumed.
/// The Baton supports being awaited by a single coroutine at a time. If the
/// baton is not ready at the time it is awaited then the awaiting coroutine
/// suspends and is later resumed when some thread calls .post().
///
/// Example usage:
///
......@@ -36,7 +37,7 @@ namespace coro {
/// folly::coro::Task<void> consumer()
/// {
/// // Wait until the baton is posted.
/// co_await baton.waitAsync().via(executor);
/// co_await baton;
///
/// // Now safe to read shared state.
/// std::cout << sharedValue << std::cout;
......@@ -77,7 +78,7 @@ class Baton {
/// the behaviour is as if an inline executor was specified.
/// i.e. the coroutine will be resumed inside the call to .post() on the
/// thread that next calls .post().
[[nodiscard]] WaitOperation waitAsync() const noexcept;
[[nodiscard]] WaitOperation operator co_await() const noexcept;
/// Set the Baton to the signalled state if it is not already signalled.
///
......@@ -136,7 +137,7 @@ inline bool Baton::ready() const noexcept {
static_cast<const void*>(this);
}
inline Baton::WaitOperation Baton::waitAsync() const noexcept {
inline Baton::WaitOperation Baton::operator co_await() const noexcept {
return Baton::WaitOperation{*this};
}
......
......@@ -44,29 +44,29 @@ TEST(Baton, InitiallyReady) {
TEST(Baton, AwaitBaton) {
coro::Baton baton;
bool reachedBeforeWait = false;
bool reachedAfterWait = false;
bool reachedBeforeAwait = false;
bool reachedAfterAwait = false;
auto makeTask = [&]() -> coro::Task<void> {
reachedBeforeWait = true;
co_await baton.waitAsync();
reachedAfterWait = true;
reachedBeforeAwait = true;
co_await baton;
reachedAfterAwait = true;
};
coro::Task<void> t = makeTask();
CHECK(!reachedBeforeWait);
CHECK(!reachedAfterWait);
CHECK(!reachedBeforeAwait);
CHECK(!reachedAfterAwait);
auto& executor = InlineExecutor::instance();
coro::Future<void> f = via(&executor, std::move(t));
CHECK(reachedBeforeWait);
CHECK(!reachedAfterWait);
CHECK(reachedBeforeAwait);
CHECK(!reachedAfterAwait);
baton.post();
CHECK(reachedAfterWait);
CHECK(reachedAfterAwait);
}
#endif
......@@ -66,7 +66,7 @@ TEST(Mutex, LockAsync) {
auto makeTask = [&](coro::Baton& b) -> coro::Task<void> {
co_await m.co_lock();
++value;
co_await b.waitAsync();
co_await b;
++value;
m.unlock();
};
......@@ -104,7 +104,7 @@ TEST(Mutex, ScopedLockAsync) {
auto makeTask = [&](coro::Baton& b) -> coro::Task<void> {
auto lock = co_await m.co_scoped_lock();
++value;
co_await b.waitAsync();
co_await b;
++value;
};
......@@ -120,7 +120,7 @@ TEST(Mutex, ScopedLockAsync) {
// This will resume f1 coroutine and let it release the
// lock. This will in turn resume f2 which was suspended
// at co_await m.lockAsync() which will then increment the value
// before becoming blocked on
// before becoming blocked on b2.
b1.post();
CHECK_EQ(3, value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment