From: Haomai Wang Date: Sat, 12 Sep 2015 09:31:10 +0000 (+0800) Subject: AsyncMessenger: Kepp file_lock hold when accessing its event field X-Git-Tag: v9.1.0~144^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=6e854338329786e1bc74b9e535c6776eef99cda5;p=ceph.git AsyncMessenger: Kepp file_lock hold when accessing its event field When process_event get a file event, other thread may delete this event later but before we do event Fix #13001 Signed-off-by: Haomai Wang --- diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc index 79bff33673d0..03119dec5c97 100644 --- a/src/msg/async/Event.cc +++ b/src/msg/async/Event.cc @@ -367,29 +367,38 @@ int EventCenter::process_events(int timeout_microseconds) vector fired_events; next_time = shortest; numevents = driver->event_wait(fired_events, &tv); + file_lock.Lock(); for (int j = 0; j < numevents; j++) { int rfired = 0; FileEvent *event; - { - Mutex::Locker l(file_lock); - event = _get_file_event(fired_events[j].fd); - } + EventCallbackRef cb; + event = _get_file_event(fired_events[j].fd); + // FIXME: Actually we need to pick up some ways to reduce potential + // file_lock contention here. /* note the event->mask & mask & ... code: maybe an already processed * event removed an element that fired and we still didn't * processed, so we check if the event is still valid. */ if (event->mask & fired_events[j].mask & EVENT_READABLE) { rfired = 1; - event->read_cb->do_request(fired_events[j].fd); + cb = event->read_cb; + file_lock.Unlock(); + cb->do_request(fired_events[j].fd); + file_lock.Lock(); } if (event->mask & fired_events[j].mask & EVENT_WRITABLE) { - if (!rfired || event->read_cb != event->write_cb) - event->write_cb->do_request(fired_events[j].fd); + if (!rfired || event->read_cb != event->write_cb) { + cb = event->write_cb; + file_lock.Unlock(); + cb->do_request(fired_events[j].fd); + file_lock.Lock(); + } } ldout(cct, 20) << __func__ << " event_wq process is " << fired_events[j].fd << " mask is " << fired_events[j].mask << dendl; } + file_lock.Unlock(); if (trigger_time) numevents += process_time_events();