Commit 1d42dc0b authored by Hans Fugal's avatar Hans Fugal Committed by Tudor Bosman

(wangle) s/FutureObject/detail::State/

Summary:
codemod
I never was satisfied with this name. `State` feels a little better. More descriptive. But still pretty generic, so I'm open to alternative ideas.

Test Plan: It still builds and tests pass.

Reviewed By: hannesr@fb.com

Subscribers: jsedgwick, net-systems@, fugalh, exa

FB internal diff: D1411506
parent 02a9ec75
......@@ -16,7 +16,7 @@
#pragma once
#include "detail.h"
#include "detail/State.h"
#include <folly/LifoSem.h>
namespace folly { namespace wangle {
......@@ -32,26 +32,26 @@ struct isFuture<Future<T> > {
};
template <class T>
Future<T>::Future(Future<T>&& other) noexcept : obj_(other.obj_) {
other.obj_ = nullptr;
Future<T>::Future(Future<T>&& other) noexcept : state_(other.state_) {
other.state_ = nullptr;
}
template <class T>
Future<T>& Future<T>::operator=(Future<T>&& other) {
std::swap(obj_, other.obj_);
std::swap(state_, other.state_);
return *this;
}
template <class T>
Future<T>::~Future() {
if (obj_) {
if (state_) {
setCallback_([](Try<T>&&) {}); // detach
}
}
template <class T>
void Future<T>::throwIfInvalid() const {
if (!obj_)
if (!state_)
throw NoState();
}
......@@ -59,8 +59,8 @@ template <class T>
template <class F>
void Future<T>::setCallback_(F&& func) {
throwIfInvalid();
obj_->setCallback_(std::move(func));
obj_ = nullptr;
state_->setCallback_(std::move(func));
state_ = nullptr;
}
template <class T>
......@@ -87,10 +87,10 @@ Future<T>::then(F&& func) {
sophisticated that avoids making a new Future object when it can, as an
optimization. But this is correct.
obj_ can't be moved, it is explicitly disallowed (as is copying). But
state_ can't be moved, it is explicitly disallowed (as is copying). But
if there's ever a reason to allow it, this is one place that makes that
assumption and would need to be fixed. We use a standard shared pointer
for obj_ (by copying it in), which means in essence obj holds a shared
for state_ (by copying it in), which means in essence obj holds a shared
pointer to itself. But this shouldn't leak because Promise will not
outlive the continuation, because Promise will setException() with a
broken Promise if it is destructed before completed. We could use a
......@@ -102,11 +102,11 @@ Future<T>::then(F&& func) {
We have to move in the Promise and func using the MoveWrapper
hack. (func could be copied but it's a big drag on perf).
Two subtle but important points about this design. FutureObject has no
Two subtle but important points about this design. detail::State has no
back pointers to Future or Promise, so if Future or Promise get moved
(and they will be moved in performant code) we don't have to do
anything fancy. And because we store the continuation in the
FutureObject, not in the Future, we can execute the continuation even
detail::State, not in the Future, we can execute the continuation even
after the Future has gone out of scope. This is an intentional design
decision. It is likely we will want to be able to cancel a continuation
in some circumstances, but I think it should be explicit not implicit
......@@ -164,21 +164,21 @@ template <class T>
typename std::add_lvalue_reference<T>::type Future<T>::value() {
throwIfInvalid();
return obj_->value();
return state_->value();
}
template <class T>
typename std::add_lvalue_reference<const T>::type Future<T>::value() const {
throwIfInvalid();
return obj_->value();
return state_->value();
}
template <class T>
Try<T>& Future<T>::getTry() {
throwIfInvalid();
return obj_->getTry();
return state_->getTry();
}
template <class T>
......@@ -191,7 +191,7 @@ inline Later<T> Future<T>::via(Executor* executor) {
template <class T>
bool Future<T>::isReady() const {
throwIfInvalid();
return obj_->ready();
return state_->ready();
}
// makeFuture
......
......@@ -181,13 +181,13 @@ class Future {
void setCallback_(F&& func);
private:
typedef detail::FutureObject<T>* objPtr;
typedef detail::State<T>* statePtr;
// shared state object
objPtr obj_;
statePtr state_;
explicit
Future(objPtr obj) : obj_(obj) {}
Future(statePtr obj) : state_(obj) {}
void throwIfInvalid() const;
......
......@@ -20,30 +20,30 @@
#include <thread>
#include "WangleException.h"
#include "detail.h"
#include "detail/State.h"
namespace folly { namespace wangle {
template <class T>
Promise<T>::Promise() : retrieved_(false), obj_(new detail::FutureObject<T>())
Promise<T>::Promise() : retrieved_(false), state_(new detail::State<T>())
{}
template <class T>
Promise<T>::Promise(Promise<T>&& other) :
retrieved_(other.retrieved_), obj_(other.obj_) {
other.obj_ = nullptr;
retrieved_(other.retrieved_), state_(other.state_) {
other.state_ = nullptr;
}
template <class T>
Promise<T>& Promise<T>::operator=(Promise<T>&& other) {
std::swap(obj_, other.obj_);
std::swap(state_, other.state_);
std::swap(retrieved_, other.retrieved_);
return *this;
}
template <class T>
void Promise<T>::throwIfFulfilled() {
if (!obj_)
if (!state_)
throw PromiseAlreadySatisfied();
}
......@@ -55,7 +55,7 @@ void Promise<T>::throwIfRetrieved() {
template <class T>
Promise<T>::~Promise() {
if (obj_) {
if (state_) {
setException(BrokenPromise());
}
}
......@@ -65,7 +65,7 @@ Future<T> Promise<T>::getFuture() {
throwIfRetrieved();
throwIfFulfilled();
retrieved_ = true;
return Future<T>(obj_);
return Future<T>(state_);
}
template <class T>
......@@ -78,21 +78,21 @@ void Promise<T>::setException(E const& e) {
template <class T>
void Promise<T>::setException(std::exception_ptr const& e) {
throwIfFulfilled();
obj_->setException(e);
state_->setException(e);
if (!retrieved_) {
delete obj_;
delete state_;
}
obj_ = nullptr;
state_ = nullptr;
}
template <class T>
void Promise<T>::fulfilTry(Try<T>&& t) {
throwIfFulfilled();
obj_->fulfil(std::move(t));
state_->fulfil(std::move(t));
if (!retrieved_) {
delete obj_;
delete state_;
}
obj_ = nullptr;
state_ = nullptr;
}
template <class T>
......@@ -102,11 +102,11 @@ void Promise<T>::setValue(M&& v) {
"Use setValue() instead");
throwIfFulfilled();
obj_->fulfil(Try<T>(std::forward<M>(v)));
state_->fulfil(Try<T>(std::forward<M>(v)));
if (!retrieved_) {
delete obj_;
delete state_;
}
obj_ = nullptr;
state_ = nullptr;
}
template <class T>
......@@ -115,11 +115,11 @@ void Promise<T>::setValue() {
"Use setValue(value) instead");
throwIfFulfilled();
obj_->fulfil(Try<void>());
state_->fulfil(Try<void>());
if (!retrieved_) {
delete obj_;
delete state_;
}
obj_ = nullptr;
state_ = nullptr;
}
template <class T>
......
......@@ -76,13 +76,13 @@ public:
void fulfil(F&& func);
private:
typedef typename Future<T>::objPtr objPtr;
typedef typename Future<T>::statePtr statePtr;
// Whether the Future has been retrieved (a one-time operation).
bool retrieved_;
// shared state object
objPtr obj_;
statePtr state_;
void throwIfFulfilled();
void throwIfRetrieved();
......
......@@ -17,29 +17,30 @@
#pragma once
#include <atomic>
#include <folly/Optional.h>
#include <stdexcept>
#include <vector>
#include "Try.h"
#include "Promise.h"
#include "Future.h"
#include <folly/Optional.h>
#include <folly/wangle/Try.h>
#include <folly/wangle/Promise.h>
#include <folly/wangle/Future.h>
namespace folly { namespace wangle { namespace detail {
/** The shared state object for Future and Promise. */
template<typename T>
class FutureObject {
class State {
public:
FutureObject() = default;
State() = default;
// not copyable
FutureObject(FutureObject const&) = delete;
FutureObject& operator=(FutureObject const&) = delete;
State(State const&) = delete;
State& operator=(State const&) = delete;
// not movable (see comment in the implementation of Future::then)
FutureObject(FutureObject&&) noexcept = delete;
FutureObject& operator=(FutureObject&&) = delete;
State(State&&) noexcept = delete;
State& operator=(State&&) = delete;
Try<T>& getTry() {
return *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