Commit 0806af8f authored by Alexey Spiridonov's avatar Alexey Spiridonov Committed by Facebook Github Bot 4

DCHECK on reentrant invocations of loop()

Summary:
I had a crash bug where an `EventBase` handler called a function, which tried to use the thread's EventBase as if it were its own:

```
auto evb = folly::EventBaseManager::get()->getEventBase();
// schedule work on evb, which calls evb->terminateLoopSoon() on completion
evb->loopForever();
```

This ended up invoking the `event_base_loop()` reentrantly, and corrupting the heap in a hard-to-debug way.

Reviewed By: djwatson

Differential Revision: D3408155

fbshipit-source-id: b8855aa3b390fa33e032ab295d386122d2cb872a
parent 52155e1d
......@@ -303,6 +303,19 @@ bool EventBase::loopOnce(int flags) {
bool EventBase::loopBody(int flags) {
VLOG(5) << "EventBase(): Starting loop.";
DCHECK(!invokingLoop_)
<< "Your code just tried to loop over an event base from inside another "
<< "event base loop. Since libevent is not reentrant, this leads to "
<< "undefined behavior in opt builds. Please fix immediately. For the "
<< "common case of an inner function that needs to do some synchronous "
<< "computation on an event-base, replace getEventBase() by a new, "
<< "stack-allocated EvenBase.";
invokingLoop_ = true;
SCOPE_EXIT {
invokingLoop_ = false;
};
int res = 0;
bool ranLoopCallbacks;
bool blocking = !(flags & EVLOOP_NONBLOCK);
......
......@@ -723,6 +723,11 @@ class EventBase : private boost::noncopyable,
uint64_t nextLoopCnt_;
uint64_t latestLoopCnt_;
uint64_t startWork_;
// Prevent undefined behavior from invoking event_base_loop() reentrantly.
// This is needed since many projects use libevent-1.4, which lacks commit
// b557b175c00dc462c1fce25f6e7dd67121d2c001 from
// https://github.com/libevent/libevent/.
bool invokingLoop_{false};
// Observer to export counters
std::shared_ptr<EventBaseObserver> observer_;
......
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