Commit 8eba7be7 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook GitHub Bot

Fix Core::hasCallback to return true for State::Empty

Summary:
This specifically fixes a TSAN detected race where SemiFuture destructor was checking Core state to see if deferred executor has to be detached, while that state could become Empty if the callback is being proxied and both threads code be racing while accessing the executor.
hasCallback() checks if the callback was ever set (not if the callback is stil alive) and it's true for State::Empty (similar to State::Done).

Differential Revision: D24271346

fbshipit-source-id: 5f52f20783d36745d1200497e0300bc086b65213
parent 1902d0ff
......@@ -259,15 +259,15 @@ class InterruptHandlerImpl : public InterruptHandler {
/// | \ (setCallback()) (setResult()) |
/// | \ \ / |
/// | \ ---> OnlyCallback --- |
/// | \ or OnlyCallbackAllowInline |
/// | \ \ |
/// | (setProxy()) (setProxy()) |
/// | \ \ |
/// | \ ------> Empty |
/// | \ / |
/// | \ (setCallback()) |
/// | \ / |
/// | ---------> Proxy ---------- |
/// | \ or OnlyCallbackAllowInline |
/// | \ \ |
/// | (setProxy()) (setProxy()) |
/// | \ \ |
/// | \ ------> Empty |
/// | \ / |
/// | \ (setCallback()) |
/// | \ / |
/// | --------> Proxy ---------- |
/// +----------------------------------------------------------------+
///
/// States and the corresponding producer-to-consumer data status & ownership:
......@@ -354,8 +354,8 @@ class CoreBase {
/// May call from any thread
bool hasCallback() const noexcept {
constexpr auto allowed =
State::OnlyCallback | State::OnlyCallbackAllowInline | State::Done;
constexpr auto allowed = State::OnlyCallback |
State::OnlyCallbackAllowInline | State::Done | State::Empty;
auto const state = state_.load(std::memory_order_acquire);
return State() != (state & allowed);
}
......
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