X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fio%2Fasync%2FEventBase.cpp;h=5c0b78129e37a39e9f4da5ecbba45604b9363710;hp=6f7e9a27425e264be6539998aaa73d87a55fdd28;hb=2d2aed32cff14f35fd3163276a0475fcd682edf5;hpb=93db3df45dd290f1024b9a4e556f65c549e0c43e diff --git a/folly/io/async/EventBase.cpp b/folly/io/async/EventBase.cpp index 6f7e9a27..5c0b7812 100644 --- a/folly/io/async/EventBase.cpp +++ b/folly/io/async/EventBase.cpp @@ -319,6 +319,7 @@ bool EventBase::loopBody(int flags) { } while (!stop_.load(std::memory_order_acquire)) { + applyLoopKeepAlive(); ++nextLoopCnt_; // Run the before loop callbacks @@ -425,18 +426,34 @@ bool EventBase::loopBody(int flags) { return true; } -void EventBase::loopForever() { - // 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. - fnRunner_->stopConsuming(); - fnRunner_->startConsuming(this, queue_.get()); - - bool ret = loop(); +void EventBase::applyLoopKeepAlive() { + if (loopKeepAliveActive_ && loopKeepAlive_.unique()) { + // Restore the notification queue internal flag + fnRunner_->stopConsuming(); + fnRunner_->startConsumingInternal(this, queue_.get()); + loopKeepAliveActive_ = false; + } else if (!loopKeepAliveActive_ && !loopKeepAlive_.unique()) { + // 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. + fnRunner_->stopConsuming(); + fnRunner_->startConsuming(this, queue_.get()); + loopKeepAliveActive_ = true; + } +} - // Restore the notification queue internal flag - fnRunner_->stopConsuming(); - fnRunner_->startConsumingInternal(this, queue_.get()); +void EventBase::loopForever() { + bool ret; + { + SCOPE_EXIT { + applyLoopKeepAlive(); + loopForeverActive_ = false; + }; + loopForeverActive_ = true; + // Make sure notification queue events are treated as normal events. + auto loopKeepAlive = loopKeepAlive_; + ret = loop(); + } if (!ret) { folly::throwSystemError("error in EventBase::loopForever()");