From b3e3fae35e3ea587d3375868a667ff638647e45b Mon Sep 17 00:00:00 2001 From: Haomai Wang Date: Sat, 6 Dec 2014 02:18:36 +0800 Subject: [PATCH] AsyncConnection: Avoid hungry if mark_down's caller is the eventcenter's owner Signed-off-by: Haomai Wang --- src/msg/async/AsyncConnection.h | 12 +++++++++--- src/msg/async/AsyncMessenger.cc | 1 + src/msg/async/Event.cc | 2 ++ src/msg/async/Event.h | 8 +++++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/msg/async/AsyncConnection.h b/src/msg/async/AsyncConnection.h index ac1e3e3f55930..5ccd7904c7fa2 100644 --- a/src/msg/async/AsyncConnection.h +++ b/src/msg/async/AsyncConnection.h @@ -17,6 +17,7 @@ #ifndef CEPH_MSG_ASYNCCONNECTION_H #define CEPH_MSG_ASYNCCONNECTION_H +#include #include #include using namespace std; @@ -140,11 +141,16 @@ class AsyncConnection : public Connection { // \ signal // finished // - // Note: Don't call it from AsyncConnection + // The above flow only happen when the caller isn't the pthread own center, + // if the owner of center is self, it's safe to call _stop() directly; void mark_down() { Mutex::Locker l(stop_lock); - center->dispatch_event_external(stop_handler); - stop_cond.Wait(stop_lock); + if (center->get_owner() == pthread_self()) { + _stop(); + } else { + center->dispatch_event_external(stop_handler); + stop_cond.Wait(stop_lock); + } } void mark_disposable() { Mutex::Locker l(lock); diff --git a/src/msg/async/AsyncMessenger.cc b/src/msg/async/AsyncMessenger.cc index 03afc0adeb269..032538aa6985f 100644 --- a/src/msg/async/AsyncMessenger.cc +++ b/src/msg/async/AsyncMessenger.cc @@ -293,6 +293,7 @@ void *Worker::entry() ldout(cct, 10) << __func__ << " starting" << dendl; int r; + center.set_owner(pthread_self()); while (!done) { ldout(cct, 20) << __func__ << " calling event process" << dendl; diff --git a/src/msg/async/Event.cc b/src/msg/async/Event.cc index 6d2960f8a26c8..15dccbee8d1db 100644 --- a/src/msg/async/Event.cc +++ b/src/msg/async/Event.cc @@ -248,6 +248,8 @@ int EventCenter::process_time_events() int EventCenter::process_events(int timeout_microseconds) { + // Must set owner before looping + assert(owner); struct timeval tv; int numevents; bool trigger_time = false; diff --git a/src/msg/async/Event.h b/src/msg/async/Event.h index 50ae7553a540a..a35c9fe9ecb3b 100644 --- a/src/msg/async/Event.h +++ b/src/msg/async/Event.h @@ -37,6 +37,8 @@ #endif #endif +#include + #include "include/Context.h" #include "include/unordered_map.h" #include "common/WorkQueue.h" @@ -112,6 +114,7 @@ class EventCenter { int notify_receive_fd; int notify_send_fd; NetHandler net; + pthread_t owner; int process_time_events(); FileEvent *_get_file_event(int fd) { @@ -126,11 +129,14 @@ class EventCenter { cct(c), nevent(0), lock("AsyncMessenger::lock"), driver(NULL), time_event_next_id(0), - notify_receive_fd(-1), notify_send_fd(-1), net(c) { + notify_receive_fd(-1), notify_send_fd(-1), net(c), owner(0) { last_time = time(NULL); } ~EventCenter(); int init(int nevent); + void set_owner(pthread_t p) { owner = p; } + pthread_t get_owner() { return owner; } + // Used by internal thread int create_file_event(int fd, int mask, EventCallbackRef ctxt); uint64_t create_time_event(uint64_t milliseconds, EventCallbackRef ctxt); -- 2.39.5