Commit 5947ad63 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Fix waitImpl to detach the future after calling setCallback_

Summary: It's not safe to access the core after setCallback_ was called, while SemiFuture::operator= may check core_.executor_

Reviewed By: yfeldblum

Differential Revision: D15871436

fbshipit-source-id: 1fe0a6b3fe1638cd8f5bab49572203f7b252c0dd
parent 9074a5ba
......@@ -324,6 +324,13 @@ void FutureBase<T>::setCallback_(
std::forward<F>(func), RequestContext::saveContext(), allowInline);
}
template <class T>
template <class F>
void FutureBase<T>::setCallbackAndDetach_(F&& func) {
setCallback_(std::forward<F>(func));
detach();
}
template <class T>
FutureBase<T>::FutureBase(futures::detail::EmptyConstruct) noexcept
: core_(nullptr) {}
......@@ -2254,8 +2261,8 @@ void waitImpl(FutureType& f) {
Promise<T> promise;
auto ret = convertFuture(promise.getSemiFuture(), f);
auto baton = std::make_shared<FutureBatonType>();
f.setCallback_([baton, promise = std::move(promise)](
Executor::KeepAlive<>&&, Try<T>&& t) mutable {
f.setCallbackAndDetach_([baton, promise = std::move(promise)](
Executor::KeepAlive<>&&, Try<T>&& t) mutable {
promise.setTry(std::move(t));
baton->post();
});
......@@ -2289,8 +2296,8 @@ void waitImpl(FutureType& f, Duration dur) {
Promise<T> promise;
auto ret = convertFuture(promise.getSemiFuture(), f);
auto baton = std::make_shared<FutureBatonType>();
f.setCallback_([baton, promise = std::move(promise)](
Executor::KeepAlive<>&&, Try<T>&& t) mutable {
f.setCallbackAndDetach_([baton, promise = std::move(promise)](
Executor::KeepAlive<>&&, Try<T>&& t) mutable {
promise.setTry(std::move(t));
baton->post();
});
......
......@@ -261,6 +261,9 @@ class FutureBase {
template <class F>
void setCallback_(F&& func, InlineContinuation = InlineContinuation::forbid);
template <class F>
void setCallbackAndDetach_(F&& func);
/// Provides a threadsafe back-channel so the consumer's thread can send an
/// interrupt-object to the producer's thread.
///
......@@ -550,6 +553,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
using Base::raise;
using Base::result;
using Base::setCallback_;
using Base::setCallbackAndDetach_;
using Base::valid;
using Base::value;
......@@ -1014,6 +1018,7 @@ class Future : private futures::detail::FutureBase<T> {
using Base::raise;
using Base::result;
using Base::setCallback_;
using Base::setCallbackAndDetach_;
using Base::valid;
using Base::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