mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-12 13:58:58 -04:00
Fix race in access to ev_res from event loop with event_active()
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) (cherry picked from commit 27934f0b39991172dcfdad23faea9874dd386f10)
This commit is contained in:
parent
2bf8b0ff0e
commit
43d92a6dab
4
event.c
4
event.c
@ -1641,10 +1641,12 @@ event_process_active_single_queue(struct event_base *base,
|
||||
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: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user