From: Haomai Wang Date: Fri, 5 Dec 2014 18:18:36 +0000 (+0800) Subject: AsyncConnection: Avoid hungry if mark_down's caller is the eventcenter's owner X-Git-Tag: v0.91~37^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b3e3fae35e3ea587d3375868a667ff638647e45b;p=ceph.git AsyncConnection: Avoid hungry if mark_down's caller is the eventcenter's owner Signed-off-by: Haomai Wang --- diff --git a/src/msg/async/AsyncConnection.h b/src/msg/async/AsyncConnection.h index ac1e3e3f5593..5ccd7904c7fa 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 03afc0adeb26..032538aa6985 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 6d2960f8a26c..15dccbee8d1d 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 50ae7553a540..a35c9fe9ecb3 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);