summaryrefslogtreecommitdiff
path: root/src/msg/Message.h
diff options
context:
space:
mode:
authorYehuda Sadeh <yehuda@hq.newdream.net>2012-04-24 15:51:14 -0700
committerYehuda Sadeh <yehuda@hq.newdream.net>2012-04-25 14:14:29 -0700
commit70f70d803ab72ccad22c42e117a65062a43a23e0 (patch)
tree7fde3d97243307a21af32ac32cbad9759db4f973 /src/msg/Message.h
parente51772ca1953e25119b010e446092756cf59fc8d (diff)
downloadceph-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.h63
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;