diff options
author | Yehuda Sadeh <yehuda@hq.newdream.net> | 2012-04-24 15:51:14 -0700 |
---|---|---|
committer | Yehuda Sadeh <yehuda@hq.newdream.net> | 2012-04-25 14:14:29 -0700 |
commit | 70f70d803ab72ccad22c42e117a65062a43a23e0 (patch) | |
tree | 7fde3d97243307a21af32ac32cbad9759db4f973 /src/msg/Message.h | |
parent | e51772ca1953e25119b010e446092756cf59fc8d (diff) | |
download | ceph-70f70d803ab72ccad22c42e117a65062a43a23e0.tar.gz |
librados: call notification under different thread context
This fixes #2342. We shouldn't call notify on the dispatcher
context. We should also make sure that we don't hold
the client lock while waiting for the responses.
Also, pushed the client_lock locking into the
ctx->notify().
Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
Diffstat (limited to 'src/msg/Message.h')
-rw-r--r-- | src/msg/Message.h | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/msg/Message.h b/src/msg/Message.h index 476b93f4079..865ea268b91 100644 --- a/src/msg/Message.h +++ b/src/msg/Message.h @@ -168,6 +168,69 @@ struct RefCountedObject { } }; +struct RefCountedCond : public RefCountedObject { + Mutex lock; + Cond cond; + atomic_t complete; + + RefCountedCond() : lock("RefCountedCond") {} + + void wait() { + Mutex::Locker l(lock); + while (!complete.read()) + cond.Wait(lock); + } + + void done() { + Mutex::Locker l(lock); + cond.SignalAll(); + complete.set(1); + } +}; + +struct RefCountedWaitObject { + atomic_t nref; + RefCountedCond *c; + + RefCountedWaitObject() : nref(1) { + c = new RefCountedCond; + } + virtual ~RefCountedWaitObject() { + c->put(); + } + + RefCountedWaitObject *get() { + nref.inc(); + return this; + } + + bool put() { + bool ret = false; + RefCountedCond *cond = c; + cond->get(); + if (nref.dec() == 0) { + cond->done(); + delete this; + ret = true; + } + cond->put(); + return ret; + } + + void put_wait() { + RefCountedCond *cond = c; + + cond->get(); + if (nref.dec() == 0) { + cond->done(); + delete this; + } else { + cond->wait(); + } + cond->put(); + } +}; + struct Connection : public RefCountedObject { Mutex lock; RefCountedObject *priv; |