]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
RefCountedObject: relocate from msg/Message.h to common/RefCountedObj.h
authorYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 25 Apr 2012 22:12:56 +0000 (15:12 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 25 Apr 2012 22:22:52 +0000 (15:22 -0700)
Following a popular request.

Signed-off-by: Yehuda Sadeh <yehuda@hq.newdream.net>
src/Makefile.am
src/common/RefCountedObj.h [new file with mode: 0644]
src/msg/Message.h

index bfbf5e648a32310a619ebc59cb24c5215f81b2f5..4c584f1505069111fec71ff42803d373714c64fd 100644 (file)
@@ -1198,6 +1198,7 @@ noinst_HEADERS = \
        cls_acl.cc\
        cls_crypto.cc\
        common/BackTrace.h\
+       common/RefCountedObj.h\
        common/HeartbeatMap.h\
        common/LogClient.h\
        common/LogEntry.h\
diff --git a/src/common/RefCountedObj.h b/src/common/RefCountedObj.h
new file mode 100644 (file)
index 0000000..bb556dd
--- /dev/null
@@ -0,0 +1,120 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#ifndef CEPH_REFCOUNTEDOBJ_H
+#define CEPH_REFCOUNTEDOBJ_H
+#include "include/atomic.h"
+
+
+struct RefCountedObject {
+  atomic_t nref;
+  RefCountedObject() : nref(1) {}
+  virtual ~RefCountedObject() {}
+  
+  RefCountedObject *get() {
+    //generic_dout(0) << "RefCountedObject::get " << this << " " << nref.read() << " -> " << (nref.read() + 1) << dendl;
+    nref.inc();
+    return this;
+  }
+  void put() {
+    //generic_dout(0) << "RefCountedObject::put " << this << " " << nref.read() << " -> " << (nref.read() - 1) << dendl;
+    if (nref.dec() == 0)
+      delete this;
+  }
+};
+
+/**
+ * RefCountedCond
+ *
+ *  a refcounted condition, will be removed when all references are dropped
+ */
+
+struct RefCountedCond : public RefCountedObject {
+  Mutex lock;
+  Cond cond;
+  bool complete;
+
+  RefCountedCond() : complete(false), lock("RefCountedCond") {}
+
+  void wait() {
+    Mutex::Locker l(lock);
+    while (!complete) {
+      cond.Wait(lock);
+    }
+  }
+
+  void done() {
+    Mutex::Locker l(lock);
+    complete = true;
+    cond.SignalAll();
+  }
+};
+
+/**
+ * RefCountedWaitObject
+ *
+ * refcounted object that allows waiting for the object's last reference.
+ * Any referrer can either put or put_wait(). A simple put() will return
+ * immediately, a put_wait() will return only when the object is destroyed.
+ * e.g., useful when we want to wait for a specific event completion. We
+ * use RefCountedCond, as the condition can be referenced after the object
+ * destruction. 
+ *    
+ */
+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();
+  }
+};
+
+
+#endif
index 865ea268b917b9ab14b7521c91871234bff7d242..44cc0fea7a50be6c9769d1d2d9c1200272ac21a5 100644 (file)
@@ -141,7 +141,8 @@ using std::list;
 #include "include/buffer.h"
 #include "common/Throttle.h"
 #include "msg_types.h"
-#include "include/atomic.h"
+
+#include "common/RefCountedObj.h"
 
 #include "common/debug.h"
 
@@ -151,85 +152,6 @@ using std::list;
 
 // abstract Connection, for keeping per-connection state
 
-struct RefCountedObject {
-  atomic_t nref;
-  RefCountedObject() : nref(1) {}
-  virtual ~RefCountedObject() {}
-  
-  RefCountedObject *get() {
-    //generic_dout(0) << "RefCountedObject::get " << this << " " << nref.read() << " -> " << (nref.read() + 1) << dendl;
-    nref.inc();
-    return this;
-  }
-  void put() {
-    //generic_dout(0) << "RefCountedObject::put " << this << " " << nref.read() << " -> " << (nref.read() - 1) << dendl;
-    if (nref.dec() == 0)
-      delete this;
-  }
-};
-
-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;