--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+//
+#include "include/ceph_assert.h"
+
+#include "common/RefCountedObj.h"
+#include "common/ceph_context.h"
+#include "common/dout.h"
+#include "common/valgrind.h"
+
+RefCountedObject::~RefCountedObject()
+{
+ ceph_assert(nref == 0);
+}
+
+void RefCountedObject::put() const {
+ CephContext *local_cct = cct;
+ auto v = --nref;
+ if (local_cct) {
+ lsubdout(local_cct, refs, 1) << "RefCountedObject::put " << this << " "
+ << (v + 1) << " -> " << v
+ << dendl;
+ }
+ if (v == 0) {
+ ANNOTATE_HAPPENS_AFTER(&nref);
+ ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref);
+ delete this;
+ } else {
+ ANNOTATE_HAPPENS_BEFORE(&nref);
+ }
+}
+
+void RefCountedObject::_get() const {
+ auto v = ++nref;
+ ceph_assert(v > 1); /* it should never happen that _get() sees nref == 0 */
+ if (cct) {
+ lsubdout(cct, refs, 1) << "RefCountedObject::get " << this << " "
+ << (v - 1) << " -> " << v << dendl;
+ }
+}
#define CEPH_REFCOUNTEDOBJ_H
#include "common/ceph_mutex.h"
-#include "common/ceph_context.h"
-#include "common/valgrind.h"
-#include "common/debug.h"
+#include "common/ref.h"
-#include <boost/smart_ptr/intrusive_ptr.hpp>
-
-// re-include our assert to clobber the system one; fix dout:
-#include "include/ceph_assert.h"
+#include <atomic>
struct RefCountedObject {
public:
- RefCountedObject(CephContext *c = NULL, int n=1) : nref(n), cct(c) {}
- virtual ~RefCountedObject() {
- ceph_assert(nref == 0);
+ void set_cct(class CephContext *c) {
+ cct = c;
}
-
+
+ uint64_t get_nref() const {
+ return nref;
+ }
+
const RefCountedObject *get() const {
- int v = ++nref;
- if (cct)
- lsubdout(cct, refs, 1) << "RefCountedObject::get " << this << " "
- << (v - 1) << " -> " << v
- << dendl;
+ _get();
return this;
}
RefCountedObject *get() {
- int v = ++nref;
- if (cct)
- lsubdout(cct, refs, 1) << "RefCountedObject::get " << this << " "
- << (v - 1) << " -> " << v
- << dendl;
+ _get();
return this;
}
- void put() const {
- CephContext *local_cct = cct;
- auto v = --nref;
- if (local_cct)
- lsubdout(local_cct, refs, 1) << "RefCountedObject::put " << this << " "
- << (v + 1) << " -> " << v
- << dendl;
- if (v == 0) {
- ANNOTATE_HAPPENS_AFTER(&nref);
- ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&nref);
- delete this;
- } else {
- ANNOTATE_HAPPENS_BEFORE(&nref);
- }
- }
- void set_cct(CephContext *c) {
- cct = c;
- }
+ void put() const;
- uint64_t get_nref() const {
- return nref;
- }
+protected:
+ RefCountedObject() = default;
+ RefCountedObject(const RefCountedObject& o) : cct(o.cct) {}
+ RefCountedObject& operator=(const RefCountedObject& o) = delete;
+ RefCountedObject(RefCountedObject&&) = delete;
+ RefCountedObject& operator=(RefCountedObject&&) = delete;
+ RefCountedObject(class CephContext* c = nullptr, int n = 1) : cct(c), nref(n) {}
+
+ virtual ~RefCountedObject();
private:
+ void _get() const;
+
#ifndef WITH_SEASTAR
- mutable std::atomic<uint64_t> nref;
+ mutable std::atomic<uint64_t> nref{1};
#else
// crimson is single threaded at the moment
- mutable uint64_t nref;
+ mutable uint64_t nref{1};
#endif
- CephContext *cct;
+ class CephContext *cct{nullptr};
};
#ifndef WITH_SEASTAR
*
* a refcounted condition, will be removed when all references are dropped
*/
-
struct RefCountedCond : public RefCountedObject {
- bool complete;
- ceph::mutex lock = ceph::make_mutex("RefCountedCond::lock");
- ceph::condition_variable cond;
- int rval;
-
- RefCountedCond() : complete(false), rval(0) {}
+ RefCountedCond() = default;
+ ~RefCountedCond() = default;
int wait() {
std::unique_lock l(lock);
void done() {
done(0);
}
+
+private:
+ bool complete = false;
+ ceph::mutex lock = ceph::make_mutex("RefCountedCond::lock");
+ ceph::condition_variable cond;
+ int rval = 0;
};
/**
p->put();
}
-using RefCountedPtr = boost::intrusive_ptr<RefCountedObject>;
+using RefCountedPtr = ceph::ref_t<RefCountedObject>;
#endif