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