X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fio%2Fasync%2FEventBase.h;h=3399cea2dacbdcc57af56f3318efd1837b65583e;hp=487af0547f09071c83bd1dd669a7645b2c3b5ee7;hb=bda67fde120837b77ddab74f23abcb22ae5b3029;hpb=887367cae9e579cd1b715265a4f1b089beda71da diff --git a/folly/io/async/EventBase.h b/folly/io/async/EventBase.h index 487af054..3399cea2 100644 --- a/folly/io/async/EventBase.h +++ b/folly/io/async/EventBase.h @@ -17,11 +17,11 @@ #pragma once #include +#include +#include #include -#include #include #include -#include #include #include #include @@ -33,21 +33,20 @@ #include #include +#include -#include #include #include #include #include +#include #include -#include #include #include #include #include #include -#include - +#include namespace folly { @@ -63,7 +62,7 @@ class EventBaseLocalBaseBase { virtual void onEventBaseDestruction(EventBase& evb) = 0; virtual ~EventBaseLocalBaseBase() = default; }; -} +} // namespace detail template class EventBaseLocal; @@ -96,6 +95,10 @@ class RequestEventBase : public RequestData { std::unique_ptr(new RequestEventBase(eb))); } + bool hasCallback() override { + return false; + } + private: explicit RequestEventBase(EventBase* eb) : eb_(eb) {} EventBase* eb_; @@ -127,7 +130,6 @@ class EventBase : private boost::noncopyable, public DrivableExecutor { public: using Func = folly::Function; - using FuncRef = folly::FunctionRef; /** * A callback interface to use with runInLoop() @@ -148,6 +150,7 @@ class EventBase : private boost::noncopyable, virtual void runLoopCallback() noexcept = 0; void cancelLoopCallback() { + context_.reset(); unlink(); } @@ -221,7 +224,7 @@ class EventBase : private boost::noncopyable, * observer, max latency and avg loop time. */ explicit EventBase(event_base* evb, bool enableTimeMeasurement = true); - ~EventBase(); + ~EventBase() override; /** * Runs the event loop. @@ -417,7 +420,7 @@ class EventBase : private boost::noncopyable, * Like runInEventBaseThread, but the caller waits for the callback to be * executed. */ - bool runInEventBaseThreadAndWait(FuncRef fn); + bool runInEventBaseThreadAndWait(Func fn); /* * Like runInEventBaseThreadAndWait, except if the caller is already in the @@ -430,7 +433,7 @@ class EventBase : private boost::noncopyable, * Like runInEventBaseThreadAndWait, except if the caller is already in the * event base thread, the functor is simply run inline. */ - bool runImmediatelyOrRunInEventBaseThreadAndWait(FuncRef fn); + bool runImmediatelyOrRunInEventBaseThreadAndWait(Func fn); /** * Set the maximum desired latency in us and provide a callback which will be @@ -492,6 +495,18 @@ class EventBase : private boost::noncopyable, std::this_thread::get_id(); } + /** + * Equivalent to CHECK(isInEventBaseThread()) (and assert/DCHECK for + * dcheckIsInEventBaseThread), but it prints more information on + * failure. + */ + void checkIsInEventBaseThread() const; + void dcheckIsInEventBaseThread() const { + if (kIsDebug) { + checkIsInEventBaseThread(); + } + } + HHWheelTimer& timer() { if (!wheelTimer_) { wheelTimer_ = HHWheelTimer::newTimer(this); @@ -515,7 +530,7 @@ class EventBase : private boost::noncopyable, * first handler fired within that cycle. * */ - void bumpHandlingTime() override final; + void bumpHandlingTime() final; class SmoothLoopTime { public: @@ -592,8 +607,6 @@ class EventBase : private boost::noncopyable, /// Implements the DrivableExecutor interface void drive() override { - // We can't use loopKeepAlive() here since LoopKeepAlive token can only be - // released inside a loop. ++loopKeepAliveCount_; SCOPE_EXIT { --loopKeepAliveCount_; @@ -603,30 +616,25 @@ class EventBase : private boost::noncopyable, /// Returns you a handle which make loop() behave like loopForever() until /// destroyed. loop() will return to its original behavior only when all - /// loop keep-alives are released. Loop holder is safe to release only from - /// EventBase thread. + /// loop keep-alives are released. KeepAlive getKeepAliveToken() override { - if (inRunningEventBaseThread()) { - loopKeepAliveCount_++; - } else { - loopKeepAliveCountAtomic_.fetch_add(1, std::memory_order_relaxed); - } + keepAliveAcquire(); return makeKeepAlive(); } // TimeoutManager void attachTimeoutManager( AsyncTimeout* obj, - TimeoutManager::InternalEnum internal) override final; + TimeoutManager::InternalEnum internal) final; - void detachTimeoutManager(AsyncTimeout* obj) override final; + void detachTimeoutManager(AsyncTimeout* obj) final; bool scheduleTimeout(AsyncTimeout* obj, TimeoutManager::timeout_type timeout) - override final; + final; - void cancelTimeout(AsyncTimeout* obj) override final; + void cancelTimeout(AsyncTimeout* obj) final; - bool isInTimeoutManagerThread() override final { + bool isInTimeoutManagerThread() final { return isInEventBaseThread(); } @@ -640,8 +648,18 @@ class EventBase : private boost::noncopyable, folly::VirtualEventBase& getVirtualEventBase(); protected: + void keepAliveAcquire() override { + if (inRunningEventBaseThread()) { + loopKeepAliveCount_++; + } else { + loopKeepAliveCountAtomic_.fetch_add(1, std::memory_order_relaxed); + } + } + void keepAliveRelease() override { - DCHECK(isInEventBaseThread()); + if (!inRunningEventBaseThread()) { + return add([=] { keepAliveRelease(); }); + } loopKeepAliveCount_--; } @@ -767,4 +785,4 @@ bool EventBase::runImmediatelyOrRunInEventBaseThreadAndWait( return runImmediatelyOrRunInEventBaseThreadAndWait([=] { fn(arg); }); } -} // folly +} // namespace folly