Commit 7c81dc02 authored by Pranav Thulasiram Bhat's avatar Pranav Thulasiram Bhat Committed by Facebook GitHub Bot

FiberManager - addFiberFuture and blockingWait

Summary:
This diff has two goals:
- To provide an API that allows users to schedule async annotated functors to run on fibers (thereby removing the need to use `init_await` at the top of the stack)
- To provide a boilerplate-free entry point into fiber code that should work for a majority of testing/benchmarking interactions with fiber manager.

The diff implements two APIs:
-addFiberFuture: wrapper around `fiberManager.addTaskFuture`. The differing name is to mainly avoid namespace collisions and avoid confusion with `coro::Task`
- blockingWait: Fiber entry point helper

Reviewed By: A5he

Differential Revision: D22071005

fbshipit-source-id: 24ceea005d32f6e2c84b4599042703207504bd0f
parent f8ca5b8f
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/fibers/FiberManager.h>
#include <folly/fibers/async/Async.h>
#pragma once
namespace folly {
namespace fibers {
namespace async {
namespace detail {
/**
* Schedule an async-annotated functor to run on a fiber manager. Returns a
* future for the result.
*
* In most cases, you probably want to use executeOnFiberAndWait instead
*/
template <typename F>
auto addFiberFuture(F&& func, FiberManager& fm) {
return fm.addTaskFuture(
[func = std::forward<F>(func)] { return init_await(func()); });
}
} // namespace detail
} // namespace async
} // namespace fibers
} // namespace folly
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <folly/fibers/FiberManagerInternal.h>
#include <folly/fibers/FiberManagerMap.h>
#include <folly/fibers/async/Async.h>
#include <folly/fibers/async/FiberManager.h>
#pragma once
namespace folly {
namespace fibers {
namespace async {
namespace detail {
template <typename F>
auto executeOnFiberAndWait(F&& func, folly::EventBase& evb, FiberManager& fm) {
DCHECK(!detail::onFiber());
return addFiberFuture(std::forward<F>(func), fm).getVia(&evb);
}
} // namespace detail
/**
* Run an async-annotated functor `func`, to completion on a fiber manager `fm`
* associated with Event Base `evb`, blocking the current thread.
*
* Should not be called from fiber context.
*
* Several overloads are provided to configure the executor / fiber manager
* options
*/
template <typename F>
auto executeOnFiberAndWait(
F&& func,
const FiberManager::Options& opts = FiberManager::Options()) {
folly::EventBase evb;
return detail::executeOnFiberAndWait(
std::forward<F>(func), evb, getFiberManager(evb, opts));
}
template <typename F>
auto executeOnFiberAndWait(F&& func, const FiberManager::FrozenOptions& opts) {
folly::EventBase evb;
return detail::executeOnFiberAndWait(
std::forward<F>(func), evb, getFiberManager(evb, opts));
}
template <typename F>
auto executeOnFiberAndWait(
F&& func,
folly::EventBase& evb,
const FiberManager::Options& opts = FiberManager::Options()) {
return detail::executeOnFiberAndWait(
std::forward<F>(func), evb, getFiberManager(evb, opts));
}
template <typename F>
auto executeOnFiberAndWait(
F&& func,
folly::EventBase& evb,
const FiberManager::FrozenOptions& opts) {
return detail::executeOnFiberAndWait(
std::forward<F>(func), evb, getFiberManager(evb, opts));
}
} // namespace async
} // namespace fibers
} // namespace folly
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
#include <folly/fibers/FiberManagerMap.h> #include <folly/fibers/FiberManagerMap.h>
#include <folly/fibers/async/Async.h> #include <folly/fibers/async/Async.h>
#include <folly/fibers/async/Baton.h> #include <folly/fibers/async/Baton.h>
#include <folly/fibers/async/FiberManager.h>
#include <folly/fibers/async/Future.h> #include <folly/fibers/async/Future.h>
#include <folly/fibers/async/Promise.h> #include <folly/fibers/async/Promise.h>
#include <folly/fibers/async/WaitUtils.h>
#include <folly/io/async/EventBase.h> #include <folly/io/async/EventBase.h>
#if FOLLY_HAS_COROUTINES #if FOLLY_HAS_COROUTINES
...@@ -238,3 +240,27 @@ TEST(AsyncTest, asyncConstructorGuides) { ...@@ -238,3 +240,27 @@ TEST(AsyncTest, asyncConstructorGuides) {
std::is_same<int&, async::async_inner_type_t<decltype(getRef())>>::value); std::is_same<int&, async::async_inner_type_t<decltype(getRef())>>::value);
} }
#endif #endif
TEST(FiberManager, asyncFiberManager) {
{
folly::EventBase evb;
bool completed = false;
async::detail::addFiberFuture(
[&]() -> async::Async<void> {
completed = true;
return {};
},
getFiberManager(evb))
.getVia(&evb);
EXPECT_TRUE(completed);
}
{
bool completed = false;
async::executeOnFiberAndWait([&]() -> async::Async<void> {
completed = true;
return {};
});
EXPECT_TRUE(completed);
}
}
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