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;
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);
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;
}
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 {
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);
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);
}
*outdata = odata.c_str();
*outdatalen = odata.length();
+#warning use after free!
return r;
}
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);
+}
+
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;
#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