From 0e32cd2f55ff8f941db02a11ef083beed7c02077 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Tue, 1 Mar 2011 04:15:58 -0800 Subject: [PATCH] librados: fix IoCtx::from_rados_ioctx_t IoCtx::from_rados_ioctx_t creates an IoCtx out of a rados_ioctx_t. However, this IoCtx must share ownership of the IoCtxImpl pointer with the C API user who first called rados_ioctx_create. This must be done via a reference count inside the IoCtxImpl. Also add a copy constructor and assignment operator to class IoCtx, since it's now cheap to have them. Signed-off-by: Colin McCabe --- src/include/rados/librados.hpp | 6 +++--- src/librados.cc | 30 ++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index 8a0a66077f7df..c82e4726445e4 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -102,6 +102,8 @@ namespace librados public: IoCtx(); static void from_rados_ioctx_t(rados_ioctx_t p, IoCtx &pool); + IoCtx(const IoCtx& rhs); + IoCtx& operator=(const IoCtx& rhs); // Close our pool handle ~IoCtx(); @@ -186,9 +188,7 @@ namespace librados friend class Rados; // Only Rados can use our private constructor to create IoCtxes. - /* We don't allow assignment or copying */ - IoCtx(const IoCtx& rhs); - const IoCtx& operator=(const IoCtx& rhs); + int ref_cnt; IoCtxImpl *io_ctx_impl; }; diff --git a/src/librados.cc b/src/librados.cc index 817cc233cc6f6..0126bc8196d3e 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -72,6 +72,7 @@ using namespace std; ///////////////////////////// RadosClient ////////////////////////////// struct librados::IoCtxImpl { + int ref_cnt; RadosClient *client; int poolid; string pool_name; @@ -82,8 +83,8 @@ struct librados::IoCtxImpl { uint32_t notify_timeout; IoCtxImpl(RadosClient *c, int pid, const char *pool_name_, snapid_t s = CEPH_NOSNAP) : - client(c), poolid(pid), pool_name(pool_name_), snap_seq(s), assert_ver(0), - notify_timeout(g_conf.client_notify_timeout) {} + ref_cnt(0), client(c), poolid(pid), pool_name(pool_name_), snap_seq(s), + assert_ver(0), notify_timeout(g_conf.client_notify_timeout) {} void set_snap_read(snapid_t s) { if (!s) @@ -2003,12 +2004,30 @@ from_rados_ioctx_t(rados_ioctx_t p, IoCtx &io) IoCtxImpl *io_ctx_impl = (IoCtxImpl*)p; io.io_ctx_impl = io_ctx_impl; + io_ctx_impl->ref_cnt++; +} + +librados::IoCtx:: +IoCtx(const IoCtx& rhs) +{ + io_ctx_impl = rhs.io_ctx_impl; + io_ctx_impl->ref_cnt++; +} + +librados::IoCtx& librados::IoCtx:: +operator=(const IoCtx& rhs) +{ + io_ctx_impl = rhs.io_ctx_impl; + io_ctx_impl->ref_cnt++; + return *this; } librados::IoCtx:: ~IoCtx() { - delete io_ctx_impl; + io_ctx_impl->ref_cnt--; + if (io_ctx_impl->ref_cnt <= 0) + delete io_ctx_impl; io_ctx_impl = 0; } @@ -2614,6 +2633,7 @@ extern "C" int rados_ioctx_create(rados_t cluster, const char *name, rados_ioctx if (!ctx) return -ENOMEM; *io = ctx; + ctx->ref_cnt++; return 0; } return poolid; @@ -2622,7 +2642,9 @@ extern "C" int rados_ioctx_create(rados_t cluster, const char *name, rados_ioctx extern "C" void rados_ioctx_destroy(rados_ioctx_t io) { librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; - delete ctx; + ctx->ref_cnt--; + if (ctx->ref_cnt <= 0) + delete ctx; } extern "C" int rados_ioctx_stat(rados_ioctx_t io, struct rados_ioctx_stat_t *stats) -- 2.39.5