Skip to content

Commit

Permalink
Remove unnecesary loop breaks from EventBase
Browse files Browse the repository at this point in the history
Summary: This logic makes it impossible to reason about order between io events, internal and external events. The comment also seems outdated.

Reviewed By: yfeldblum

Differential Revision: D19785249

fbshipit-source-id: 62eee5427a3c47cccba6cb33c2ca88af82767bed
  • Loading branch information
andriigrynenko authored and facebook-github-bot committed Feb 8, 2020
1 parent 0eb09b7 commit 070c3b7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 26 deletions.
1 change: 0 additions & 1 deletion folly/futures/test/SemiFutureTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,6 @@ TEST(SemiFuture, MakeFutureFromSemiFutureReturnSemiFuture) {
EXPECT_FALSE(future.isReady());
p.setValue(42);
e.loopOnce();
e.loopOnce();
EXPECT_TRUE(future.isReady());
ASSERT_EQ(future.value(), 42);
ASSERT_EQ(result, 42);
Expand Down
26 changes: 2 additions & 24 deletions folly/io/async/EventBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,19 +132,6 @@ class EventBase::FunctionRunner
: public NotificationQueue<EventBase::Func>::Consumer {
public:
void messageAvailable(Func&& msg) noexcept override {
// In libevent2, internal events do not break the loop.
// Most users would expect loop(), followed by runInEventBaseThread(),
// to break the loop and check if it should exit or not.
// To have similar bejaviour to libevent1.4, tell the loop to break here.
// Note that loop() may still continue to loop, but it will also check the
// stop_ flag as well as runInLoop callbacks, etc.
getEventBase()->getBackend()->eb_event_base_loopbreak();

if (!msg) {
// terminateLoopSoon() sends a null message just to
// wake up the loop. We can ignore these messages.
return;
}
msg();
}
};
Expand Down Expand Up @@ -574,24 +561,15 @@ void EventBase::terminateLoopSoon() {
// Set stop to true, so the event loop will know to exit.
stop_.store(true, std::memory_order_relaxed);

// Call event_base_loopbreak() so that libevent will exit the next time
// around the loop.
evb_->eb_event_base_loopbreak();

// If terminateLoopSoon() is called from another thread,
// the EventBase thread might be stuck waiting for events.
// 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.
//
// We don't care about the return value of trySendFrame(). If it fails
// this likely means the EventBase already has lots of events waiting
// anyway.
try {
queue_->putMessage(nullptr);
queue_->putMessage([&] { evb_->eb_event_base_loopbreak(); });
} catch (...) {
// We don't care if putMessage() fails. This likely means
// the EventBase already has lots of events waiting anyway.
// putMessage() can only fail when the queue is draining in ~EventBase.
}
}

Expand Down
30 changes: 29 additions & 1 deletion folly/io/async/test/EventBaseTestLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -1721,6 +1721,33 @@ TYPED_TEST_P(EventBaseTest, AlwaysEnqueueCallbackOrderTest) {
EXPECT_EQ(num, 2);
}

TYPED_TEST_P(EventBaseTest1, InternalExternalCallbackOrderTest) {
size_t counter = 0;

FOLLY_SKIP_IF_NULLPTR_BACKEND(evb);

std::vector<size_t> calls;

folly::Function<void(size_t)> runInLoopRecursive = [&](size_t left) {
evb.runInLoop([&, left]() mutable {
calls.push_back(counter++);
if (--left == 0) {
evb.terminateLoopSoon();
return;
}
runInLoopRecursive(left);
});
};

evb.runInEventBaseThread([&] { runInLoopRecursive(5); });
for (size_t i = 0; i < 49; ++i) {
evb.runInEventBaseThread([&] { ++counter; });
}
evb.loopForever();

EXPECT_EQ(std::vector<size_t>({9, 20, 31, 42, 53}), calls);
}

///////////////////////////////////////////////////////////////////////////
// Tests for latency calculations
///////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2317,6 +2344,7 @@ REGISTER_TYPED_TEST_CASE_P(
RunOnDestructionBasic,
RunOnDestructionCancelled,
RunOnDestructionAfterHandleDestroyed,
RunOnDestructionAddCallbackWithinCallback);
RunOnDestructionAddCallbackWithinCallback,
InternalExternalCallbackOrderTest);
} // namespace test
} // namespace folly

0 comments on commit 070c3b7

Please sign in to comment.