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 @@
namespace folly {
namespace fibers {
template <typename EventBaseT>
inline EventBaseLoopControllerT<EventBaseT>::EventBaseLoopControllerT()
inline EventBaseLoopController::EventBaseLoopController()
: callback_(*this), aliveWeak_(destructionCallback_.getWeak()) {}
template <typename EventBaseT>
inline EventBaseLoopControllerT<EventBaseT>::~EventBaseLoopControllerT() {
inline EventBaseLoopController::~EventBaseLoopController() {
callback_.cancelLoopCallback();
eventBaseKeepAlive_.reset();
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::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<EventBaseT>::attachEventBase(
}
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::setFiberManager(
FiberManager* fm) {
inline void EventBaseLoopController::setFiberManager(FiberManager* fm) {
fm_ = fm;
}
template <>
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() {
inline void EventBaseLoopController::schedule() {
if (eventBase_ == nullptr) {
// In this case we need to postpone scheduling.
awaitingScheduling_ = true;
......@@ -80,13 +66,11 @@ inline void EventBaseLoopControllerT<folly::VirtualEventBase>::schedule() {
}
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::cancel() {
inline void EventBaseLoopController::cancel() {
callback_.cancelLoopCallback();
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::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<EventBaseT>::runLoop() {
}
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::scheduleThreadSafe(
inline void EventBaseLoopController::scheduleThreadSafe(
std::function<bool()> 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<EventBaseT>::scheduleThreadSafe(
}
}
template <typename EventBaseT>
inline void EventBaseLoopControllerT<EventBaseT>::timedSchedule(
inline void EventBaseLoopController::timedSchedule(
std::function<void()> func,
TimePoint time) {
assert(eventBaseAttached_);
......
......@@ -17,30 +17,25 @@
#include <folly/fibers/FiberManagerInternal.h>
#include <folly/fibers/LoopController.h>
#include <folly/io/async/EventBase.h>
#include <folly/io/async/VirtualEventBase.h>
#include <atomic>
#include <memory>
namespace folly {
class EventBase;
}
namespace folly {
namespace fibers {
template <typename EventBaseT>
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<folly::EventBase>;
using VirtualEventBaseLoopController =
EventBaseLoopControllerT<folly::VirtualEventBase>;
}
} // folly::fibers
......
......@@ -63,7 +63,7 @@ class GlobalCache {
auto& fmPtrRef = map_[&evb];
if (!fmPtrRef) {
auto loopController = make_unique<EventBaseLoopControllerT<EventBaseT>>();
auto loopController = make_unique<EventBaseLoopController>();
loopController->attachEventBase(evb);
evb.runOnDestruction(new EventBaseOnDestructionCallback<EventBaseT>(evb));
......
......@@ -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.
......
......@@ -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<void> destroy();
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