monclient: use an async finisher

Otherwise we can deadlock if any completions call back into MonClient.

Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
Sage Weil 2011-10-03 15:36:56 -07:00
parent 04b90cc701
commit 9c56070bc2
2 changed files with 7 additions and 4 deletions

View File

@ -50,7 +50,7 @@ MonClient::MonClient(CephContext *cct_) :
messenger(NULL), messenger(NULL),
cur_con(NULL), cur_con(NULL),
monc_lock("MonClient::monc_lock"), monc_lock("MonClient::monc_lock"),
timer(cct_, monc_lock), timer(cct_, monc_lock), finisher(cct_),
log_client(NULL), log_client(NULL),
hunting(true), hunting(true),
want_monmap(true), want_monmap(true),
@ -355,6 +355,7 @@ int MonClient::init()
Mutex::Locker l(monc_lock); Mutex::Locker l(monc_lock);
timer.init(); timer.init();
finisher.start();
schedule_tick(); schedule_tick();
// seed rng so we choose a different monitor each time // seed rng so we choose a different monitor each time
@ -380,9 +381,9 @@ int MonClient::init()
void MonClient::shutdown() void MonClient::shutdown()
{ {
finisher.stop();
monc_lock.Lock(); monc_lock.Lock();
timer.shutdown(); timer.shutdown();
if (cur_con) { if (cur_con) {
cur_con->put(); cur_con->put();
cur_con = NULL; cur_con = NULL;
@ -542,7 +543,7 @@ void MonClient::_reopen_session()
// throw out version check requests // throw out version check requests
while (!version_requests.empty()) { while (!version_requests.empty()) {
version_requests.begin()->second->context->complete(-1); // watch out for deadlock finisher.queue(version_requests.begin()->second->context, -1);
version_requests.erase(version_requests.begin()); version_requests.erase(version_requests.begin());
} }
@ -792,7 +793,7 @@ void MonClient::handle_get_version_reply(MMonGetVersionReply* m)
*req->newest = m->version; *req->newest = m->version;
if (req->oldest) if (req->oldest)
*req->oldest = m->oldest_version; *req->oldest = m->oldest_version;
req->context->complete(0); finisher.queue(req->context, 0);
delete req; delete req;
} }
} }

View File

@ -21,6 +21,7 @@
#include "MonMap.h" #include "MonMap.h"
#include "common/Timer.h" #include "common/Timer.h"
#include "common/Finisher.h"
#include "auth/AuthClientHandler.h" #include "auth/AuthClientHandler.h"
#include "auth/RotatingKeyRing.h" #include "auth/RotatingKeyRing.h"
@ -62,6 +63,7 @@ private:
Mutex monc_lock; Mutex monc_lock;
SafeTimer timer; SafeTimer timer;
Finisher finisher;
LogClient *log_client; LogClient *log_client;