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

Make EventBaseLoopController only support VirtualEventBase

Summary: EventBase support is achieved through default VirtualEventBase mechanism.

Reviewed By: yfeldblum

Differential Revision: D4685948

fbshipit-source-id: 15c8c789a55776984aa9087455e3f7b79d7604ad
parent 95310177
...@@ -19,19 +19,20 @@ ...@@ -19,19 +19,20 @@
namespace folly { namespace folly {
namespace fibers { namespace fibers {
template <typename EventBaseT> inline EventBaseLoopController::EventBaseLoopController()
inline EventBaseLoopControllerT<EventBaseT>::EventBaseLoopControllerT()
: callback_(*this), aliveWeak_(destructionCallback_.getWeak()) {} : callback_(*this), aliveWeak_(destructionCallback_.getWeak()) {}
template <typename EventBaseT> inline EventBaseLoopController::~EventBaseLoopController() {
inline EventBaseLoopControllerT<EventBaseT>::~EventBaseLoopControllerT() {
callback_.cancelLoopCallback(); callback_.cancelLoopCallback();
eventBaseKeepAlive_.reset(); eventBaseKeepAlive_.reset();
} }
template <typename EventBaseT> inline void EventBaseLoopController::attachEventBase(EventBase& eventBase) {
inline void EventBaseLoopControllerT<EventBaseT>::attachEventBase( attachEventBase(eventBase.getVirtualEventBase());
EventBaseT& eventBase) { }
inline void EventBaseLoopController::attachEventBase(
VirtualEventBase& eventBase) {
if (eventBase_ != nullptr) { if (eventBase_ != nullptr) {
LOG(ERROR) << "Attempt to reattach EventBase to LoopController"; LOG(ERROR) << "Attempt to reattach EventBase to LoopController";
} }
...@@ -46,26 +47,11 @@ inline void EventBaseLoopControllerT<EventBaseT>::attachEventBase( ...@@ -46,26 +47,11 @@ inline void EventBaseLoopControllerT<EventBaseT>::attachEventBase(
} }
} }
template <typename EventBaseT> inline void EventBaseLoopController::setFiberManager(FiberManager* fm) {
inline void EventBaseLoopControllerT<EventBaseT>::setFiberManager(
FiberManager* fm) {
fm_ = fm; fm_ = fm;
} }
template <> inline void EventBaseLoopController::schedule() {
inline void EventBaseLoopControllerT<folly::EventBase>::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<folly::VirtualEventBase>::schedule() {
if (eventBase_ == nullptr) { if (eventBase_ == nullptr) {
// In this case we need to postpone scheduling. // In this case we need to postpone scheduling.
awaitingScheduling_ = true; awaitingScheduling_ = true;
...@@ -80,13 +66,11 @@ inline void EventBaseLoopControllerT<folly::VirtualEventBase>::schedule() { ...@@ -80,13 +66,11 @@ inline void EventBaseLoopControllerT<folly::VirtualEventBase>::schedule() {
} }
} }
template <typename EventBaseT> inline void EventBaseLoopController::cancel() {
inline void EventBaseLoopControllerT<EventBaseT>::cancel() {
callback_.cancelLoopCallback(); callback_.cancelLoopCallback();
} }
template <typename EventBaseT> inline void EventBaseLoopController::runLoop() {
inline void EventBaseLoopControllerT<EventBaseT>::runLoop() {
if (!eventBaseKeepAlive_) { if (!eventBaseKeepAlive_) {
// runLoop can be called twice if both schedule() and scheduleThreadSafe() // runLoop can be called twice if both schedule() and scheduleThreadSafe()
// were called. // were called.
...@@ -105,8 +89,7 @@ inline void EventBaseLoopControllerT<EventBaseT>::runLoop() { ...@@ -105,8 +89,7 @@ inline void EventBaseLoopControllerT<EventBaseT>::runLoop() {
} }
} }
template <typename EventBaseT> inline void EventBaseLoopController::scheduleThreadSafe(
inline void EventBaseLoopControllerT<EventBaseT>::scheduleThreadSafe(
std::function<bool()> func) { std::function<bool()> func) {
/* The only way we could end up here is if /* The only way we could end up here is if
1) Fiber thread creates a fiber that awaits (which means we must 1) Fiber thread creates a fiber that awaits (which means we must
...@@ -127,8 +110,7 @@ inline void EventBaseLoopControllerT<EventBaseT>::scheduleThreadSafe( ...@@ -127,8 +110,7 @@ inline void EventBaseLoopControllerT<EventBaseT>::scheduleThreadSafe(
} }
} }
template <typename EventBaseT> inline void EventBaseLoopController::timedSchedule(
inline void EventBaseLoopControllerT<EventBaseT>::timedSchedule(
std::function<void()> func, std::function<void()> func,
TimePoint time) { TimePoint time) {
assert(eventBaseAttached_); assert(eventBaseAttached_);
......
...@@ -17,30 +17,25 @@ ...@@ -17,30 +17,25 @@
#include <folly/fibers/FiberManagerInternal.h> #include <folly/fibers/FiberManagerInternal.h>
#include <folly/fibers/LoopController.h> #include <folly/fibers/LoopController.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/VirtualEventBase.h> #include <folly/io/async/VirtualEventBase.h>
#include <atomic> #include <atomic>
#include <memory> #include <memory>
namespace folly {
class EventBase;
}
namespace folly { namespace folly {
namespace fibers { namespace fibers {
template <typename EventBaseT> class EventBaseLoopController : public LoopController {
class EventBaseLoopControllerT : public LoopController {
public: public:
explicit EventBaseLoopControllerT(); explicit EventBaseLoopController();
~EventBaseLoopControllerT(); ~EventBaseLoopController();
/** /**
* Attach EventBase after LoopController was created. * Attach EventBase after LoopController was created.
*/ */
void attachEventBase(EventBaseT& eventBase); void attachEventBase(EventBase& eventBase);
void attachEventBase(VirtualEventBase& eventBase);
EventBaseT* getEventBase() { VirtualEventBase* getEventBase() {
return eventBase_; return eventBase_;
} }
...@@ -51,7 +46,7 @@ class EventBaseLoopControllerT : public LoopController { ...@@ -51,7 +46,7 @@ class EventBaseLoopControllerT : public LoopController {
private: private:
class ControllerCallback : public folly::EventBase::LoopCallback { class ControllerCallback : public folly::EventBase::LoopCallback {
public: public:
explicit ControllerCallback(EventBaseLoopControllerT& controller) explicit ControllerCallback(EventBaseLoopController& controller)
: controller_(controller) {} : controller_(controller) {}
void runLoopCallback() noexcept override { void runLoopCallback() noexcept override {
...@@ -59,7 +54,7 @@ class EventBaseLoopControllerT : public LoopController { ...@@ -59,7 +54,7 @@ class EventBaseLoopControllerT : public LoopController {
} }
private: private:
EventBaseLoopControllerT& controller_; EventBaseLoopController& controller_;
}; };
class DestructionCallback : public folly::EventBase::LoopCallback { class DestructionCallback : public folly::EventBase::LoopCallback {
...@@ -92,7 +87,7 @@ class EventBaseLoopControllerT : public LoopController { ...@@ -92,7 +87,7 @@ class EventBaseLoopControllerT : public LoopController {
}; };
bool awaitingScheduling_{false}; bool awaitingScheduling_{false};
EventBaseT* eventBase_{nullptr}; VirtualEventBase* eventBase_{nullptr};
Executor::KeepAlive eventBaseKeepAlive_; Executor::KeepAlive eventBaseKeepAlive_;
ControllerCallback callback_; ControllerCallback callback_;
DestructionCallback destructionCallback_; DestructionCallback destructionCallback_;
...@@ -113,9 +108,6 @@ class EventBaseLoopControllerT : public LoopController { ...@@ -113,9 +108,6 @@ class EventBaseLoopControllerT : public LoopController {
friend class FiberManager; friend class FiberManager;
}; };
using EventBaseLoopController = EventBaseLoopControllerT<folly::EventBase>;
using VirtualEventBaseLoopController =
EventBaseLoopControllerT<folly::VirtualEventBase>;
} }
} // folly::fibers } // folly::fibers
......
...@@ -63,7 +63,7 @@ class GlobalCache { ...@@ -63,7 +63,7 @@ class GlobalCache {
auto& fmPtrRef = map_[&evb]; auto& fmPtrRef = map_[&evb];
if (!fmPtrRef) { if (!fmPtrRef) {
auto loopController = make_unique<EventBaseLoopControllerT<EventBaseT>>(); auto loopController = make_unique<EventBaseLoopController>();
loopController->attachEventBase(evb); loopController->attachEventBase(evb);
evb.runOnDestruction(new EventBaseOnDestructionCallback<EventBaseT>(evb)); evb.runOnDestruction(new EventBaseOnDestructionCallback<EventBaseT>(evb));
......
...@@ -408,16 +408,23 @@ ssize_t EventBase::loopKeepAliveCount() { ...@@ -408,16 +408,23 @@ ssize_t EventBase::loopKeepAliveCount() {
loopKeepAliveCountAtomic_.exchange(0, std::memory_order_relaxed); loopKeepAliveCountAtomic_.exchange(0, std::memory_order_relaxed);
} }
DCHECK_GE(loopKeepAliveCount_, 0); DCHECK_GE(loopKeepAliveCount_, 0);
return loopKeepAliveCount_; return loopKeepAliveCount_;
} }
void EventBase::applyLoopKeepAlive() { 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 // Restore the notification queue internal flag
fnRunner_->stopConsuming(); fnRunner_->stopConsuming();
fnRunner_->startConsumingInternal(this, queue_.get()); fnRunner_->startConsumingInternal(this, queue_.get());
loopKeepAliveActive_ = false; loopKeepAliveActive_ = false;
} else if (!loopKeepAliveActive_ && loopKeepAliveCount() > 0) { } else if (!loopKeepAliveActive_ && keepAliveCount > 0) {
// Update the notification queue event to treat it as a normal // Update the notification queue event to treat it as a normal
// (non-internal) event. The notification queue event always remains // (non-internal) event. The notification queue event always remains
// installed, and the main loop won't exit with it installed. // installed, and the main loop won't exit with it installed.
......
...@@ -137,7 +137,7 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager { ...@@ -137,7 +137,7 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager {
protected: protected:
void keepAliveRelease() override { void keepAliveRelease() override {
DCHECK(getEventBase().inRunningEventBaseThread()); DCHECK(getEventBase().isInEventBaseThread());
if (loopKeepAliveCountAtomic_.load()) { if (loopKeepAliveCountAtomic_.load()) {
loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0); loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0);
} }
...@@ -150,6 +150,13 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager { ...@@ -150,6 +150,13 @@ class VirtualEventBase : public folly::Executor, public folly::TimeoutManager {
private: private:
friend class EventBase; friend class EventBase;
ssize_t keepAliveCount() {
if (loopKeepAliveCountAtomic_.load()) {
loopKeepAliveCount_ += loopKeepAliveCountAtomic_.exchange(0);
}
return loopKeepAliveCount_;
}
std::future<void> destroy(); std::future<void> destroy();
void destroyImpl(); void destroyImpl();
......
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