From a6685a3b090de89e76f12b3c620c6fd84afb9f85 Mon Sep 17 00:00:00 2001 From: Andrii Grynenko Date: Fri, 10 Mar 2017 17:06:58 -0800 Subject: [PATCH] Make EventBaseLoopController only support VirtualEventBase Summary: EventBase support is achieved through default VirtualEventBase mechanism. Reviewed By: yfeldblum Differential Revision: D4685948 fbshipit-source-id: 15c8c789a55776984aa9087455e3f7b79d7604ad --- folly/fibers/EventBaseLoopController-inl.h | 46 +++++++--------------- folly/fibers/EventBaseLoopController.h | 26 +++++------- folly/fibers/FiberManagerMap.cpp | 2 +- folly/io/async/EventBase.cpp | 11 +++++- folly/io/async/VirtualEventBase.h | 9 ++++- 5 files changed, 41 insertions(+), 53 deletions(-) diff --git a/folly/fibers/EventBaseLoopController-inl.h b/folly/fibers/EventBaseLoopController-inl.h index 4c01ed00..f0aa4c9b 100644 --- a/folly/fibers/EventBaseLoopController-inl.h +++ b/folly/fibers/EventBaseLoopController-inl.h @@ -19,19 +19,20 @@ namespace folly { namespace fibers { -template -inline EventBaseLoopControllerT::EventBaseLoopControllerT() +inline EventBaseLoopController::EventBaseLoopController() : callback_(*this), aliveWeak_(destructionCallback_.getWeak()) {} -template -inline EventBaseLoopControllerT::~EventBaseLoopControllerT() { +inline EventBaseLoopController::~EventBaseLoopController() { callback_.cancelLoopCallback(); eventBaseKeepAlive_.reset(); } -template -inline void EventBaseLoopControllerT::attachEventBase( - EventBaseT& eventBase) { +inline void EventBaseLoopController::attachEventBase(EventBase& eventBase) { + attachEventBase(eventBase.getVirtualEventBase()); +} + +inline void EventBaseLoopController::attachEventBase( + VirtualEventBase& eventBase) { if (eventBase_ != nullptr) { LOG(ERROR) << "Attempt to reattach EventBase to LoopController"; } @@ -46,26 +47,11 @@ inline void EventBaseLoopControllerT::attachEventBase( } } -template -inline void EventBaseLoopControllerT::setFiberManager( - FiberManager* fm) { +inline void EventBaseLoopController::setFiberManager(FiberManager* fm) { fm_ = fm; } -template <> -inline void EventBaseLoopControllerT::schedule() { - if (eventBase_ == nullptr) { - // In this case we need to postpone scheduling. - awaitingScheduling_ = true; - } else { - // Schedule it to run in current iteration. - eventBase_->runInLoop(&callback_, true); - awaitingScheduling_ = false; - } -} - -template <> -inline void EventBaseLoopControllerT::schedule() { +inline void EventBaseLoopController::schedule() { if (eventBase_ == nullptr) { // In this case we need to postpone scheduling. awaitingScheduling_ = true; @@ -80,13 +66,11 @@ inline void EventBaseLoopControllerT::schedule() { } } -template -inline void EventBaseLoopControllerT::cancel() { +inline void EventBaseLoopController::cancel() { callback_.cancelLoopCallback(); } -template -inline void EventBaseLoopControllerT::runLoop() { +inline void EventBaseLoopController::runLoop() { if (!eventBaseKeepAlive_) { // runLoop can be called twice if both schedule() and scheduleThreadSafe() // were called. @@ -105,8 +89,7 @@ inline void EventBaseLoopControllerT::runLoop() { } } -template -inline void EventBaseLoopControllerT::scheduleThreadSafe( +inline void EventBaseLoopController::scheduleThreadSafe( std::function func) { /* The only way we could end up here is if 1) Fiber thread creates a fiber that awaits (which means we must @@ -127,8 +110,7 @@ inline void EventBaseLoopControllerT::scheduleThreadSafe( } } -template -inline void EventBaseLoopControllerT::timedSchedule( +inline void EventBaseLoopController::timedSchedule( std::function func, TimePoint time) { assert(eventBaseAttached_); diff --git a/folly/fibers/EventBaseLoopController.h b/folly/fibers/EventBaseLoopController.h index ce97240b..a8a82766 100644 --- a/folly/fibers/EventBaseLoopController.h +++ b/folly/fibers/EventBaseLoopController.h @@ -17,30 +17,25 @@ #include #include -#include #include #include #include -namespace folly { -class EventBase; -} - namespace folly { namespace fibers { -template -class EventBaseLoopControllerT : public LoopController { +class EventBaseLoopController : public LoopController { public: - explicit EventBaseLoopControllerT(); - ~EventBaseLoopControllerT(); + explicit EventBaseLoopController(); + ~EventBaseLoopController(); /** * Attach EventBase after LoopController was created. */ - void attachEventBase(EventBaseT& eventBase); + void attachEventBase(EventBase& eventBase); + void attachEventBase(VirtualEventBase& eventBase); - EventBaseT* getEventBase() { + VirtualEventBase* getEventBase() { return eventBase_; } @@ -51,7 +46,7 @@ class EventBaseLoopControllerT : public LoopController { private: class ControllerCallback : public folly::EventBase::LoopCallback { public: - explicit ControllerCallback(EventBaseLoopControllerT& controller) + explicit ControllerCallback(EventBaseLoopController& controller) : controller_(controller) {} void runLoopCallback() noexcept override { @@ -59,7 +54,7 @@ class EventBaseLoopControllerT : public LoopController { } private: - EventBaseLoopControllerT& controller_; + EventBaseLoopController& controller_; }; class DestructionCallback : public folly::EventBase::LoopCallback { @@ -92,7 +87,7 @@ class EventBaseLoopControllerT : public LoopController { }; bool awaitingScheduling_{false}; - EventBaseT* eventBase_{nullptr}; + VirtualEventBase* eventBase_{nullptr}; Executor::KeepAlive eventBaseKeepAlive_; ControllerCallback callback_; DestructionCallback destructionCallback_; @@ -113,9 +108,6 @@ class EventBaseLoopControllerT : public LoopController { friend class FiberManager; }; -using EventBaseLoopController = EventBaseLoopControllerT; -using VirtualEventBaseLoopController = - EventBaseLoopControllerT; } } // folly::fibers diff --git a/folly/fibers/FiberManagerMap.cpp b/folly/fibers/FiberManagerMap.cpp index 8e294c12..5e2eebca 100644 --- a/folly/fibers/FiberManagerMap.cpp +++ b/folly/fibers/FiberManagerMap.cpp @@ -63,7 +63,7 @@ class GlobalCache { auto& fmPtrRef = map_[&evb]; if (!fmPtrRef) { - auto loopController = make_unique>(); + auto loopController = make_unique(); loopController->attachEventBase(evb); evb.runOnDestruction(new EventBaseOnDestructionCallback(evb)); diff --git a/folly/io/async/EventBase.cpp b/folly/io/async/EventBase.cpp index 062ec2d3..1f5ea560 100644 --- a/folly/io/async/EventBase.cpp +++ b/folly/io/async/EventBase.cpp @@ -408,16 +408,23 @@ ssize_t EventBase::loopKeepAliveCount() { loopKeepAliveCountAtomic_.exchange(0, std::memory_order_relaxed); } DCHECK_GE(loopKeepAliveCount_, 0); + return loopKeepAliveCount_; } void EventBase::applyLoopKeepAlive() { - if (loopKeepAliveActive_ && loopKeepAliveCount() == 0) { + auto keepAliveCount = loopKeepAliveCount(); + // Make sure default VirtualEventBase won't hold EventBase::loop() forever. + if (virtualEventBase_ && virtualEventBase_->keepAliveCount() == 1) { + --keepAliveCount; + } + + if (loopKeepAliveActive_ && keepAliveCount == 0) { // Restore the notification queue internal flag fnRunner_->stopConsuming(); fnRunner_->startConsumingInternal(this, queue_.get()); loopKeepAliveActive_ = false; - } else if (!loopKeepAliveActive_ && loopKeepAliveCount() > 0) { + } else if (!loopKeepAliveActive_ && keepAliveCount > 0) { // Update the notification queue event to treat it as a normal // (non-internal) event. The notification queue event always remains // installed, and the main loop won't exit with it installed. diff --git a/folly/io/async/VirtualEventBase.h b/folly/io/async/VirtualEventBase.h index a1194d82..4719fdea 100644 --- a/folly/io/async/VirtualEventBase.h +++ b/folly/io/async/VirtualEventBase.h @@ -137,7 +137,7 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager { protected: void keepAliveRelease() override { - DCHECK(getEventBase().inRunningEventBaseThread()); + DCHECK(getEventBase().isInEventBaseThread()); if (loopKeepAliveCountAtomic_.load()) { loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0); } @@ -150,6 +150,13 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager { private: friend class EventBase; + ssize_t keepAliveCount() { + if (loopKeepAliveCountAtomic_.load()) { + loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0); + } + return loopKeepAliveCount_; + } + std::future destroy(); void destroyImpl(); -- 2.34.1