summaryrefslogtreecommitdiff
path: root/event.c
diff options
context:
space:
mode:
authorJames Synge <jamessynge@google.com>2017-08-07 11:06:28 -0400
committerAzat Khuzhin <a3at.mail@gmail.com>2017-08-15 00:09:04 +0300
commit27934f0b39991172dcfdad23faea9874dd386f10 (patch)
tree1d8ad8c45dcd3a731f564a7ed58efccf9b8a2623 /event.c
parenta10a6f4ed918ea1432820d99e9373f37f906d6f0 (diff)
downloadlibevent-27934f0b39991172dcfdad23faea9874dd386f10.tar.gz
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)
Diffstat (limited to 'event.c')
-rw-r--r--event.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/event.c b/event.c
index d2768793..98b1bc4a 100644
--- a/event.c
+++ b/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: {