}
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;
#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>
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) {