summaryrefslogtreecommitdiff
path: root/src/msg/Message.h
diff options
context:
space:
mode:
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;