Skip to content

Commit

Permalink
Revert D53292113: Improve management of EventBase keepalives
Browse files Browse the repository at this point in the history
Differential Revision:
D53292113

Original commit changeset: c0817cad9866

Original Phabricator Diff: D53292113

fbshipit-source-id: b695869f67602c64d00c4e5e34eaa856dab482f4
  • Loading branch information
ot authored and facebook-github-bot committed Feb 3, 2024
1 parent 0fb2b8a commit 718e602
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 14 deletions.
16 changes: 13 additions & 3 deletions folly/io/async/EventBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,14 @@ void EventBase::loopMainCleanup() {
loopThread_.store({}, std::memory_order_release);
}

size_t EventBase::loopKeepAliveCount() {
return loopKeepAliveCount_.load(std::memory_order_relaxed);
ssize_t EventBase::loopKeepAliveCount() {
if (loopKeepAliveCountAtomic_.load(std::memory_order_relaxed)) {
loopKeepAliveCount_ +=
loopKeepAliveCountAtomic_.exchange(0, std::memory_order_relaxed);
}
DCHECK_GE(loopKeepAliveCount_, 0);

return loopKeepAliveCount_;
}

void EventBase::applyLoopKeepAlive() {
Expand Down Expand Up @@ -698,7 +704,11 @@ void EventBase::terminateLoopSoon() {
// In this case, it won't wake up and notice that stop_ is set until it
// receives another event. Send an empty frame to the notification queue
// so that the event loop will wake up even if there are no other events.
queue_->putMessage([] {});
try {
queue_->putMessage([] {});
} catch (...) {
// putMessage() can only fail when the queue is draining in ~EventBase.
}
}

void EventBase::runInLoop(
Expand Down
24 changes: 14 additions & 10 deletions folly/io/async/EventBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,8 @@ class EventBase : public TimeoutManager,

/// Implements the DrivableExecutor interface
void drive() override {
loopKeepAliveCount_.fetch_add(1, std::memory_order_relaxed);
SCOPE_EXIT { loopKeepAliveCount_.fetch_sub(1, std::memory_order_relaxed); };
++loopKeepAliveCount_;
SCOPE_EXIT { --loopKeepAliveCount_; };
loopOnce();
}

Expand Down Expand Up @@ -962,17 +962,19 @@ class EventBase : public TimeoutManager,

protected:
bool keepAliveAcquire() noexcept override {
loopKeepAliveCount_.fetch_add(1, std::memory_order_relaxed);
if (inRunningEventBaseThread()) {
loopKeepAliveCount_++;
} else {
loopKeepAliveCountAtomic_.fetch_add(1, std::memory_order_relaxed);
}
return true;
}

void keepAliveRelease() noexcept override {
auto oldCount = loopKeepAliveCount_.fetch_sub(1, std::memory_order_acq_rel);
DCHECK_GT(oldCount, 0);
if (oldCount == 1 && !inRunningEventBaseThread()) {
// Unblock the loop so it can exit.
runInEventBaseThreadAlwaysEnqueue([] {});
if (!inRunningEventBaseThread()) {
return add([this] { loopKeepAliveCount_--; });
}
loopKeepAliveCount_--;
}

private:
Expand All @@ -981,9 +983,10 @@ class EventBase : public TimeoutManager,

folly::VirtualEventBase* tryGetVirtualEventBase();

size_t loopKeepAliveCount();
void applyLoopKeepAlive();

ssize_t loopKeepAliveCount();

/*
* Helper function that tells us whether we have already handled
* some event/timeout/callback in this loop iteration.
Expand Down Expand Up @@ -1036,7 +1039,8 @@ class EventBase : public TimeoutManager,
// A notification queue for runInEventBaseThread() to use
// to send function requests to the EventBase thread.
std::unique_ptr<EventBaseAtomicNotificationQueue<Func, FuncRunner>> queue_;
std::atomic<size_t> loopKeepAliveCount_{0};
ssize_t loopKeepAliveCount_{0};
std::atomic<ssize_t> loopKeepAliveCountAtomic_{0};
bool loopKeepAliveActive_{false};

// limit for latency in microseconds (0 disables)
Expand Down
2 changes: 1 addition & 1 deletion folly/io/async/VirtualEventBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace folly {
* VirtualEventBase implements a light-weight view onto existing EventBase.
*
* Multiple VirtualEventBases can be backed by a single EventBase. Similarly
* to EventBase, VirtualEventBase implements KeepAlive functionality,
* to EventBase, VirtualEventBase implements loopKeepAlive() functionality,
* which allows callbacks holding KeepAlive token to keep EventBase looping
* until they are complete.
*
Expand Down

0 comments on commit 718e602

Please sign in to comment.