]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: fix IoCtx::from_rados_ioctx_t
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 1 Mar 2011 12:15:58 +0000 (04:15 -0800)
committerJosh Durgin <josh.durgin@dreamhost.com>
Fri, 4 Mar 2011 00:04:06 +0000 (16:04 -0800)
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 <colin.mccabe@dreamhost.com>
src/include/rados/librados.hpp
src/librados.cc

index 8a0a66077f7df078c0a77fcea17b196e1cce9827..c82e4726445e4c039411e86281839251e9f1a5eb 100644 (file)
@@ -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;
   };
 
index 817cc233cc6f672b3fb0357ff9eeaf104414d016..0126bc8196d3e72a63a0d1e39ae5d67d76af9029 100644 (file)
@@ -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)