Commit 743a0b48 authored by Andrii Grynenko's avatar Andrii Grynenko Committed by facebook-github-bot-0

Support nested FiberManagers

Summary:It's possible to have nested loopUntilNoReady (with different FiberManagers). See unit test for a simple example.
This diff fixes currentFiberManager_ to be a stack.

Reviewed By: meyering

Differential Revision: D2953468

fb-gh-sync-id: 0abdcb7f43c94e7bb0adef8440699dc8e138d21a
shipit-source-id: 0abdcb7f43c94e7bb0adef8440699dc8e138d21a
parent 95ade4c9
......@@ -141,16 +141,19 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
}
inline bool FiberManager::loopUntilNoReady() {
// Support nested FiberManagers
auto originalFiberManager = this;
std::swap(currentFiberManager_, originalFiberManager);
SCOPE_EXIT {
isLoopScheduled_ = false;
if (!readyFibers_.empty()) {
ensureLoopScheduled();
}
currentFiberManager_ = nullptr;
std::swap(currentFiberManager_, originalFiberManager);
CHECK_EQ(this, originalFiberManager);
};
currentFiberManager_ = this;
bool hadRemoteFiber = true;
while (hadRemoteFiber) {
hadRemoteFiber = false;
......
......@@ -26,6 +26,7 @@
#include <folly/experimental/fibers/AddTasks.h>
#include <folly/experimental/fibers/EventBaseLoopController.h>
#include <folly/experimental/fibers/FiberManager.h>
#include <folly/experimental/fibers/FiberManagerMap.h>
#include <folly/experimental/fibers/GenericBaton.h>
#include <folly/experimental/fibers/SimpleLoopController.h>
#include <folly/experimental/fibers/WhenN.h>
......@@ -1552,6 +1553,34 @@ TEST(FiberManager, remoteFutureTest) {
EXPECT_EQ(v2, testValue2);
}
TEST(FiberManager, nestedFiberManagers) {
folly::EventBase outerEvb;
folly::EventBase innerEvb;
getFiberManager(outerEvb).addTask([&]() {
EXPECT_EQ(&getFiberManager(outerEvb),
FiberManager::getFiberManagerUnsafe());
runInMainContext([&]() {
getFiberManager(innerEvb).addTask([&]() {
EXPECT_EQ(&getFiberManager(innerEvb),
FiberManager::getFiberManagerUnsafe());
innerEvb.terminateLoopSoon();
});
innerEvb.loopForever();
});
EXPECT_EQ(&getFiberManager(outerEvb),
FiberManager::getFiberManagerUnsafe());
outerEvb.terminateLoopSoon();
});
outerEvb.loopForever();
}
static size_t sNumAwaits;
void runBenchmark(size_t numAwaits, size_t toSend) {
......
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