Detected using ThreadSanitizer, resolved by capturing the value
of ev_res in a local variable while the event is locked, then
passing that captured variable to the callback.
TSAN report:
I0728 14:35:09.822118 WARNING: ThreadSanitizer: data race (pid=815501)
I0728 14:35:09.822186 Write of size 2 at 0x7b2c00001bf2 by thread T80 (mutexes: write M1110835549570434736):
I0728 14:35:09.822248 #0 event_active_nolock_ libevent/event.c:2893:14 (
0a2b90577e830d775300664df77d0b91+0x1fdab28)
I0728 14:35:09.822316 #1 event_active libevent/event.c:2858:2 (
0a2b90577e830d775300664df77d0b91+0x1fdd10e)
I0728 14:35:09.822379 #2 Envoy::Event::TimerImpl::enableTimer(std::chrono::duration<long, std::ratio<1l, 1000l> > const&) envoy/source/common/event/timer_impl.cc:24:5 (
0a2b90577e830d775300664df77d0b91+0x459fa0)
...
I0728 14:35:09.824146 Previous read of size 2 at 0x7b2c00001bf2 by main thread:
I0728 14:35:09.824232 #0 event_process_active_single_queue libevent/event.c:1646:33 (
0a2b90577e830d775300664df77d0b91+0x1fdf83d)
I0728 14:35:09.824350 #1 event_process_active libevent/event.c (
0a2b90577e830d775300664df77d0b91+0x1fd9ad8)
I0728 14:35:09.824445 #2 event_base_loop libevent/event.c:1961 (
0a2b90577e830d775300664df77d0b91+0x1fd9ad8)
I0728 14:35:09.824550 #3 Envoy::Event::DispatcherImpl::run(Envoy::Event::Dispatcher::RunType) envoy/source/common/event/dispatcher_impl.cc:166:3 (
0a2b90577e830d775300664df77d0b91+0x4576d9)
...
Fixes: #543 (pull-request)
break;
case EV_CLOSURE_EVENT: {
void (*evcb_callback)(evutil_socket_t, short, void *);
+ short res;
EVUTIL_ASSERT(ev != NULL);
evcb_callback = *ev->ev_callback;
+ res = ev->ev_res;
EVBASE_RELEASE_LOCK(base, th_base_lock);
- evcb_callback(ev->ev_fd, ev->ev_res, ev->ev_arg);
+ evcb_callback(ev->ev_fd, res, ev->ev_arg);
}
break;
case EV_CLOSURE_CB_SELF: {