Commit d8cd7bc7 authored by Brian Watling's avatar Brian Watling Committed by Alecs King

Ensure the loop callback is scheduled when the ready queue is not empty

Summary: Previously we'd call ensureLoopScheduled() but it'd be a no-op since the loop was already scheduled. Delaying the call to ensureLoopScheduled() fixes the issue

Test Plan: unit tests (FiberManager.yieldTest fails without the changes to FiberManager-inl.h)

Reviewed By: andrii@fb.com

Subscribers: folly-diffs@, yfeldblum, chalfant

FB internal diff: D1993686

Signature: t1:1993686:1429070253:af933abbbbb33868a402f1d643e4e6f5fef1be83
parent 30d8a3d6
...@@ -97,6 +97,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -97,6 +97,9 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
inline bool FiberManager::loopUntilNoReady() { inline bool FiberManager::loopUntilNoReady() {
SCOPE_EXIT { SCOPE_EXIT {
isLoopScheduled_ = false; isLoopScheduled_ = false;
if (!readyFibers_.empty()) {
ensureLoopScheduled();
}
currentFiberManager_ = nullptr; currentFiberManager_ = nullptr;
}; };
...@@ -135,10 +138,7 @@ inline bool FiberManager::loopUntilNoReady() { ...@@ -135,10 +138,7 @@ inline bool FiberManager::loopUntilNoReady() {
); );
} }
if (!yieldedFibers_.empty()) { readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
ensureLoopScheduled();
}
return fibersActive_ > 0; return fibersActive_ > 0;
} }
......
...@@ -1281,6 +1281,31 @@ TEST(FiberManager, fiberLocalHeap) { ...@@ -1281,6 +1281,31 @@ TEST(FiberManager, fiberLocalHeap) {
testFiberLocal<LargeData>(); testFiberLocal<LargeData>();
} }
TEST(FiberManager, yieldTest) {
FiberManager manager(folly::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
bool checkRan = false;
manager.addTask(
[&]() {
manager.yield();
checkRan = true;
}
);
loopController.loop(
[&]() {
if (checkRan) {
loopController.stop();
}
}
);
EXPECT_TRUE(checkRan);
}
static size_t sNumAwaits; static size_t sNumAwaits;
void runBenchmark(size_t numAwaits, size_t toSend) { 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