]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
objclass: add support for c++ methods
authorSage Weil <sage@newdream.net>
Sat, 6 Jun 2009 04:33:32 +0000 (21:33 -0700)
committerSage Weil <sage@newdream.net>
Sat, 6 Jun 2009 04:33:32 +0000 (21:33 -0700)
src/common/ClassHandler.cc
src/common/ClassHandler.h
src/objclass/class_api.cc
src/objclass/objclass.h

index e3596cb1908b5763f9487cbef3d41f0331b728bb..555cabfb7bae827cf9f889cf51320ef4bab608a5 100644 (file)
@@ -286,9 +286,10 @@ void ClassHandler::ClassData::_add_dependent(ClassData& dependent)
   dependents.push_back(&dependent);
 }
 
-ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname, cls_method_call_t func)
+ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *mname,
+                                                                   cls_method_call_t func)
 {
- /* no need for locking, called under the class_init mutex */
 /* no need for locking, called under the class_init mutex */
   ClassMethod& method = methods_map[mname];
   method.func = func;
   method.name = mname;
@@ -297,6 +298,18 @@ ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *
   return &method;
 }
 
+ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const char *mname,
+                                                                       cls_method_cxx_call_t func)
+{
+  /* no need for locking, called under the class_init mutex */
+  ClassMethod& method = methods_map[mname];
+  method.cxx_func = func;
+  method.name = mname;
+  method.cls = this;
+
+  return &method;
+}
+
 ClassHandler::ClassMethod *ClassHandler::ClassData::get_method(const char *mname)
 {
   Mutex::Locker lock(*mutex);
@@ -353,12 +366,20 @@ void ClassHandler::ClassMethod::unregister()
 
 int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata)
 {
-  char *out = NULL;
-  int olen;
   int ret;
-  ret = func(ctx, indata.c_str(), indata.length(), &out, &olen);
-  if (out)
-    outdata.append(out, olen);
-
+  if (cxx_func) {
+    // C++ call version
+    ret = cxx_func(ctx, &indata, &outdata);
+  } else {
+    // C version
+    char *out = NULL;
+    int olen = 0;
+    ret = func(ctx, indata.c_str(), indata.length(), &out, &olen);
+    if (out) {
+      // assume *out was allocated via cls_alloc (which calls malloc!)
+      buffer::ptr bp = buffer::claim_malloc(olen, out);
+      outdata.push_back(bp);
+    }
+  }
   return ret;
 }
index 38d892612c5338dfd25c5292f8a83590fde45b5a..a8fc0257fb3adccdcc8abfbfca347d92938ff4c1 100644 (file)
@@ -26,9 +26,12 @@ public:
     struct ClassHandler::ClassData *cls;
     string name;
     cls_method_call_t func;
-    int exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata);
+    cls_method_cxx_call_t cxx_func;
 
+    int exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata);
     void unregister();
+
+    ClassMethod() : cls(0), func(0), cxx_func(0) {}
   };
 
   struct ClassData {
@@ -63,8 +66,8 @@ public:
     ClassData() : mutex(NULL), status(CLASS_UNKNOWN), version(), timeout(0), handle(NULL), registered(false)  {}
     ~ClassData() { if (mutex) delete mutex; }
 
-    ClassMethod *register_method(const char *mname,
-                          cls_method_call_t func);
+    ClassMethod *register_method(const char *mname, cls_method_call_t func);
+    ClassMethod *register_cxx_method(const char *mname, cls_method_cxx_call_t func);
     ClassMethod *get_method(const char *mname);
     void unregister_method(ClassMethod *method);
 
index 2285fd3d09fc232511714f5c9c5610dec2de28fa..3f0e5ea75f8d1f9316b6ea1b078c7173ce5be3e2 100644 (file)
@@ -57,12 +57,22 @@ int cls_register_method(cls_handle_t hclass, const char *method,
   cls_method_handle_t hmethod;
 
   cd = (ClassHandler::ClassData *)hclass;
-
   hmethod  = (cls_method_handle_t)cd->register_method(method, class_call);
-
   if (handle)
     *handle = hmethod;
+  return (hmethod != NULL);
+}
+
+int cls_register_cxx_method(cls_handle_t hclass, const char *method,
+                           cls_method_cxx_call_t class_call, cls_method_handle_t *handle)
+{
+  ClassHandler::ClassData *cd;
+  cls_method_handle_t hmethod;
 
+  cd = (ClassHandler::ClassData *)hclass;
+  hmethod  = (cls_method_handle_t)cd->register_cxx_method(method, class_call);
+  if (handle)
+    *handle = hmethod;
   return (hmethod != NULL);
 }
 
@@ -97,6 +107,7 @@ int cls_rdcall(cls_method_handle_t hctx, const char *cls, const char *method,
 
   *outdata = odata.c_str();
   *outdatalen = odata.length();
+#warning use after free!
 
   return r;
 }
@@ -105,21 +116,57 @@ int cls_read(cls_method_handle_t hctx, int ofs, int len,
                                  char **outdata, int *outdatalen)
 {
   ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
-  bufferlist odata;
-  bufferlist idata;
-  vector<ceph_osd_op> nops(1);
-  ceph_osd_op& op = nops[0];
-  int r;
-
-  op.offset = ofs;
-  op.length = len;
-  op.op = CEPH_OSD_OP_READ;
+  vector<ceph_osd_op> ops(1);
+  ops[0].op = CEPH_OSD_OP_READ;
+  ops[0].offset = ofs;
+  ops[0].length = len;
+  bufferlist idata, odata;
   bufferlist::iterator iter = idata.begin();
-  r = (*pctx)->pg->do_osd_ops(*pctx, nops, iter, odata);
+  int r = (*pctx)->pg->do_osd_ops(*pctx, ops, iter, odata);
 
   *outdata = odata.c_str();
   *outdatalen = odata.length();
+#warning use after free!
 
   return r;
 }
 
+int cls_cxx_read(cls_method_handle_t hctx, int ofs, int len, bufferlist *outbl)
+{
+  ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
+  vector<ceph_osd_op> ops(1);
+  ops[0].op = CEPH_OSD_OP_READ;
+  ops[0].offset = ofs;
+  ops[0].length = len;
+  bufferlist idata;
+  bufferlist::iterator iter = idata.begin();
+  return (*pctx)->pg->do_osd_ops(*pctx, ops, iter, *outbl);
+}
+
+int cls_cxx_write(cls_method_handle_t hctx, int ofs, int len, bufferlist *inbl)
+{
+  ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
+  vector<ceph_osd_op> ops(1);
+  ops[0].op = CEPH_OSD_OP_WRITE;
+  ops[0].offset = ofs;
+  ops[0].length = len;
+  bufferlist outbl;
+  bufferlist::iterator iter = inbl->begin();
+  return (*pctx)->pg->do_osd_ops(*pctx, ops, iter, outbl);
+}
+
+int cls_cxx_replace(cls_method_handle_t hctx, int ofs, int len, bufferlist *inbl)
+{
+  ReplicatedPG::OpContext **pctx = (ReplicatedPG::OpContext **)hctx;
+  vector<ceph_osd_op> ops(2);
+  ops[0].op = CEPH_OSD_OP_TRUNCATE;
+  ops[0].offset = 0;
+  ops[0].length = 0;
+  ops[1].op = CEPH_OSD_OP_WRITE;
+  ops[1].offset = ofs;
+  ops[1].length = len;
+  bufferlist outbl;
+  bufferlist::iterator iter = inbl->begin();
+  return (*pctx)->pg->do_osd_ops(*pctx, ops, iter, outbl);
+}
+
index 938cf17b87cae961c9a6578871cbd6efcb549917..20c6520368d1a76dd4574bf87670f5fc43467be8 100644 (file)
@@ -17,7 +17,6 @@ typedef void *cls_method_context_t;
 typedef int (*cls_method_call_t)(cls_method_context_t ctx,
                                 char *indata, int datalen,
                                 char **outdata, int *outdatalen);
-
 typedef struct {
        const char *name;
        const char *ver;
@@ -61,6 +60,18 @@ extern void class_fini(void);
 
 #ifdef __cplusplus
 }
+
+typedef int (*cls_method_cxx_call_t)(cls_method_context_t ctx,
+                                    class buffer::list *inbl, class buffer::list *outbl);
+
+extern int cls_register_cxx_method(cls_handle_t hclass, const char *method,
+                                  cls_method_cxx_call_t class_call, cls_method_handle_t *handle);
+
+extern int cls_cxx_read(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
+extern int cls_cxx_write(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
+extern int cls_cxx_replace(cls_method_handle_t hctx, int ofs, int len, bufferlist *bl);
+
+
 #endif
 
 #endif