Commit 327cac1e authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Fix a race in AwaitWrapper::promise_type::final_suspend

Summary: This fixes a race in AwaitWrapper, but also makes it easier for compiler to perform the heap elision optimisation.

Differential Revision: D8701500

fbshipit-source-id: 86efd5089ac7fdf32f64b3d84fcbfbefb9824365
parent 110882c8
...@@ -31,10 +31,19 @@ class AwaitWrapper { ...@@ -31,10 +31,19 @@ class AwaitWrapper {
return {}; return {};
} }
std::experimental::suspend_never final_suspend() { auto final_suspend() {
executor_->add(awaiter_); struct FinalAwaiter {
awaitWrapper_->promise_ = nullptr; bool await_ready() noexcept {
return {}; return false;
}
void await_suspend(
std::experimental::coroutine_handle<promise_type> h) noexcept {
auto& p = h.promise();
p.executor_->add(p.awaiter_);
}
void await_resume() noexcept {}
};
return FinalAwaiter{};
} }
void return_void() {} void return_void() {}
...@@ -50,7 +59,6 @@ class AwaitWrapper { ...@@ -50,7 +59,6 @@ class AwaitWrapper {
Executor* executor_; Executor* executor_;
std::experimental::coroutine_handle<> awaiter_; std::experimental::coroutine_handle<> awaiter_;
AwaitWrapper* awaitWrapper_{nullptr};
}; };
static AwaitWrapper create(Awaitable* awaitable) { static AwaitWrapper create(Awaitable* awaitable) {
...@@ -90,8 +98,6 @@ class AwaitWrapper { ...@@ -90,8 +98,6 @@ class AwaitWrapper {
~AwaitWrapper() { ~AwaitWrapper() {
if (promise_) { if (promise_) {
// This happens if await_ready() returns true or await_suspend() returns
// false.
std::experimental::coroutine_handle<promise_type>::from_promise(*promise_) std::experimental::coroutine_handle<promise_type>::from_promise(*promise_)
.destroy(); .destroy();
} }
...@@ -99,9 +105,7 @@ class AwaitWrapper { ...@@ -99,9 +105,7 @@ class AwaitWrapper {
private: private:
AwaitWrapper(Awaitable* awaitable) : awaitable_(awaitable) {} AwaitWrapper(Awaitable* awaitable) : awaitable_(awaitable) {}
AwaitWrapper(promise_type& promise) : promise_(&promise) { AwaitWrapper(promise_type& promise) : promise_(&promise) {}
promise.awaitWrapper_ = this;
}
static AwaitWrapper awaitWrapper() { static AwaitWrapper awaitWrapper() {
co_return; co_return;
......
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