Commit 4f2c98ac authored by Andrii Grynenko's avatar Andrii Grynenko Committed by Facebook Github Bot

Use loopKeepAlive() mechanism in FiberManager

Reviewed By: yfeldblum

Differential Revision: D4086486

fbshipit-source-id: bd0cca8dd2c9b74d5c30e4cd095191c1d1ecab79
parent d2c8a36b
...@@ -24,6 +24,7 @@ inline EventBaseLoopController::EventBaseLoopController() ...@@ -24,6 +24,7 @@ inline EventBaseLoopController::EventBaseLoopController()
inline EventBaseLoopController::~EventBaseLoopController() { inline EventBaseLoopController::~EventBaseLoopController() {
callback_.cancelLoopCallback(); callback_.cancelLoopCallback();
eventBaseKeepAlive_.reset();
} }
inline void EventBaseLoopController::attachEventBase( inline void EventBaseLoopController::attachEventBase(
...@@ -62,10 +63,16 @@ inline void EventBaseLoopController::cancel() { ...@@ -62,10 +63,16 @@ inline void EventBaseLoopController::cancel() {
} }
inline void EventBaseLoopController::runLoop() { inline void EventBaseLoopController::runLoop() {
if (!eventBaseKeepAlive_) {
eventBaseKeepAlive_ = eventBase_->loopKeepAlive();
}
if (loopRunner_) { if (loopRunner_) {
loopRunner_->run([&] { fm_->loopUntilNoReady(); }); loopRunner_->run([&] { fm_->loopUntilNoReadyImpl(); });
} else { } else {
fm_->loopUntilNoReady(); fm_->loopUntilNoReadyImpl();
}
if (!fm_->hasTasks()) {
eventBaseKeepAlive_.reset();
} }
} }
......
...@@ -91,6 +91,7 @@ class EventBaseLoopController : public LoopController { ...@@ -91,6 +91,7 @@ class EventBaseLoopController : public LoopController {
bool awaitingScheduling_{false}; bool awaitingScheduling_{false};
folly::EventBase* eventBase_{nullptr}; folly::EventBase* eventBase_{nullptr};
folly::EventBase::LoopKeepAlive eventBaseKeepAlive_;
ControllerCallback callback_; ControllerCallback callback_;
DestructionCallback destructionCallback_; DestructionCallback destructionCallback_;
FiberManager* fm_{nullptr}; FiberManager* fm_{nullptr};
...@@ -103,7 +104,7 @@ class EventBaseLoopController : public LoopController { ...@@ -103,7 +104,7 @@ class EventBaseLoopController : public LoopController {
void setFiberManager(FiberManager* fm) override; void setFiberManager(FiberManager* fm) override;
void schedule() override; void schedule() override;
void cancel() override; void cancel() override;
void runLoop(); void runLoop() override;
void scheduleThreadSafe(std::function<bool()> func) override; void scheduleThreadSafe(std::function<bool()> func) override;
void timedSchedule(std::function<void()> func, TimePoint time) override; void timedSchedule(std::function<void()> func, TimePoint time) override;
......
...@@ -185,7 +185,11 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) { ...@@ -185,7 +185,11 @@ inline void FiberManager::runReadyFiber(Fiber* fiber) {
} }
} }
inline bool FiberManager::loopUntilNoReady() { inline void FiberManager::loopUntilNoReady() {
return loopController_->runLoop();
}
inline void FiberManager::loopUntilNoReadyImpl() {
#ifndef _WIN32 #ifndef _WIN32
if (UNLIKELY(!alternateSignalStackRegistered_)) { if (UNLIKELY(!alternateSignalStackRegistered_)) {
registerAlternateSignalStack(); registerAlternateSignalStack();
...@@ -243,8 +247,6 @@ inline bool FiberManager::loopUntilNoReady() { ...@@ -243,8 +247,6 @@ inline bool FiberManager::loopUntilNoReady() {
} }
} }
readyFibers_.splice(readyFibers_.end(), yieldedFibers_); readyFibers_.splice(readyFibers_.end(), yieldedFibers_);
return fibersActive_ > 0;
} }
// We need this to be in a struct, not inlined in addTask, because clang crashes // We need this to be in a struct, not inlined in addTask, because clang crashes
......
...@@ -155,10 +155,13 @@ class FiberManager : public ::folly::Executor { ...@@ -155,10 +155,13 @@ class FiberManager : public ::folly::Executor {
/** /**
* Keeps running ready tasks until the list of ready tasks is empty. * Keeps running ready tasks until the list of ready tasks is empty.
*
* @return True if there are any waiting tasks remaining.
*/ */
bool loopUntilNoReady(); void loopUntilNoReady();
/**
* This should only be called by a LoopController.
*/
void loopUntilNoReadyImpl();
/** /**
* @return true if there are outstanding tasks. * @return true if there are outstanding tasks.
......
...@@ -170,11 +170,6 @@ void EventBaseOnDestructionCallback::runLoopCallback() noexcept { ...@@ -170,11 +170,6 @@ void EventBaseOnDestructionCallback::runLoopCallback() noexcept {
DCHECK(fm.get() != nullptr); DCHECK(fm.get() != nullptr);
ThreadLocalCache::erase(evb_); ThreadLocalCache::erase(evb_);
while (fm->hasTasks()) {
fm->loopUntilNoReady();
evb_.loopOnce();
}
delete this; delete this;
} }
......
...@@ -41,6 +41,12 @@ class LoopController { ...@@ -41,6 +41,12 @@ class LoopController {
*/ */
virtual void schedule() = 0; virtual void schedule() = 0;
/**
* Run FiberManager loopUntilNoReadyImpl(). May have additional logic specific
* to a LoopController.
*/
virtual void runLoop() = 0;
/** /**
* Same as schedule(), but safe to call from any thread. * Same as schedule(), but safe to call from any thread.
* Runs func and only schedules if func returned true. * Runs func and only schedules if func returned true.
......
...@@ -54,7 +54,8 @@ class SimpleLoopController : public LoopController { ...@@ -54,7 +54,8 @@ class SimpleLoopController : public LoopController {
if (scheduled_) { if (scheduled_) {
scheduled_ = false; scheduled_ = false;
waiting = fm_->loopUntilNoReady(); runLoop();
waiting = fm_->hasTasks();
} }
} }
} }
...@@ -70,6 +71,10 @@ class SimpleLoopController : public LoopController { ...@@ -70,6 +71,10 @@ class SimpleLoopController : public LoopController {
return remoteScheduleCalled_; return remoteScheduleCalled_;
} }
void runLoop() override {
fm_->loopUntilNoReadyImpl();
}
void schedule() override { void schedule() override {
scheduled_ = true; scheduled_ = true;
} }
......
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