Commit 753868d5 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by facebook-github-bot-4

Unify runInMainContext for void and non-void

Summary: This also fixes a bug where exception was not re-thrown for functions returning void.

Reviewed By: spalamarchuk

Differential Revision: D2936887

fb-gh-sync-id: 9828dec131203528c27eae874aba147168f40d0d
shipit-source-id: 9828dec131203528c27eae874aba147168f40d0d
parent fea483aa
......@@ -429,14 +429,6 @@ void FiberManager::addTaskFinally(F&& func, G&& finally) {
template <typename F>
typename std::result_of<F()>::type
FiberManager::runInMainContext(F&& func) {
return runInMainContextHelper(std::forward<F>(func));
}
template <typename F>
inline typename std::enable_if<
!std::is_same<typename std::result_of<F()>::type, void>::value,
typename std::result_of<F()>::type>::type
FiberManager::runInMainContextHelper(F&& func) {
if (UNLIKELY(activeFiber_ == nullptr)) {
return func();
}
......@@ -451,21 +443,7 @@ FiberManager::runInMainContextHelper(F&& func) {
immediateFunc_ = std::ref(f);
activeFiber_->preempt(Fiber::AWAITING_IMMEDIATE);
return std::move(result.value());
}
template <typename F>
inline typename std::enable_if<
std::is_same<typename std::result_of<F()>::type, void>::value,
void>::type
FiberManager::runInMainContextHelper(F&& func) {
if (UNLIKELY(activeFiber_ == nullptr)) {
func();
return;
}
immediateFunc_ = std::ref(func);
activeFiber_->preempt(Fiber::AWAITING_IMMEDIATE);
return std::move(result).value();
}
inline FiberManager& FiberManager::getFiberManager() {
......
......@@ -373,24 +373,6 @@ class FiberManager : public ::folly::Executor {
*/
static FOLLY_TLS FiberManager* currentFiberManager_;
/**
* runInMainContext implementation for non-void functions.
*/
template <typename F>
typename std::enable_if<
!std::is_same<typename std::result_of<F()>::type, void>::value,
typename std::result_of<F()>::type>::type
runInMainContextHelper(F&& func);
/**
* runInMainContext implementation for void functions
*/
template <typename F>
typename std::enable_if<
std::is_same<typename std::result_of<F()>::type, void>::value,
void>::type
runInMainContextHelper(F&& func);
/**
* Allocator used to allocate stack for Fibers in the pool.
* Allocates stack on the stack of the main context.
......
......@@ -937,16 +937,22 @@ TEST(FiberManager, runInMainContext) {
checkRan = false;
manager.addTask(
[&]() {
int stackLocation;
runInMainContext(
[&]() {
expectMainContext(checkRan, &mainLocation, &stackLocation);
});
EXPECT_TRUE(checkRan);
}
);
manager.addTask([&]() {
struct A {
explicit A(int value_) : value(value_) {}
A(const A&) = delete;
A(A&&) = default;
int value;
};
int stackLocation;
auto ret = runInMainContext([&]() {
expectMainContext(checkRan, &mainLocation, &stackLocation);
return A(42);
});
EXPECT_TRUE(checkRan);
EXPECT_EQ(42, ret.value);
});
loopController.loop(
[&]() {
......
......@@ -102,13 +102,19 @@ Try<T>::~Try() {
}
template <class T>
T& Try<T>::value() {
T& Try<T>::value() & {
throwIfFailed();
return value_;
}
template <class T>
const T& Try<T>::value() const {
T&& Try<T>::value() && {
throwIfFailed();
return std::move(value_);
}
template <class T>
const T& Try<T>::value() const & {
throwIfFailed();
return value_;
}
......
......@@ -124,14 +124,21 @@ class Try {
*
* @returns mutable reference to the contained value
*/
T& value();
T& value()&;
/*
* Get a rvalue reference to the contained value. If the Try contains an
* exception it will be rethrown.
*
* @returns rvalue reference to the contained value
*/
T&& value()&&;
/*
* Get a const reference to the contained value. If the Try contains an
* exception it will be rethrown.
*
* @returns const reference to the contained value
*/
const T& value() const;
const T& value() const&;
/*
* If the Try contains an exception, rethrow it. Otherwise do nothing.
......
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