osd/ClassHandler: use std::variant for storing func

for better readablity, and less error-prone

Signed-off-by: Kefu Chai <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2019-06-03 18:28:34 +08:00
parent 7a9830323c
commit 11689c0e88
2 changed files with 32 additions and 32 deletions

View File

@ -232,12 +232,8 @@ ClassHandler::ClassMethod *ClassHandler::ClassData::register_method(const char *
return NULL;
}
ldout(handler->cct, 10) << "register_method " << name << "." << mname << " flags " << flags << " " << (void*)func << dendl;
ClassMethod& method = methods_map[mname];
method.func = func;
method.name = mname;
method.flags = flags;
method.cls = this;
return &method;
[[maybe_unused]] auto [method, added] = methods_map.try_emplace(mname, mname, func, flags, this);
return &method->second;
}
ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const char *mname,
@ -246,12 +242,8 @@ ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const ch
{
/* no need for locking, called under the class_init mutex */
ldout(handler->cct, 10) << "register_cxx_method " << name << "." << mname << " flags " << flags << " " << (void*)func << dendl;
ClassMethod& method = methods_map[mname];
method.cxx_func = func;
method.name = mname;
method.flags = flags;
method.cls = this;
return &method;
[[maybe_unused]] auto [method, added] = methods_map.try_emplace(mname, mname, func, flags, this);
return &method->second;
}
ClassHandler::ClassFilter *ClassHandler::ClassData::register_cxx_filter(
@ -312,21 +304,26 @@ void ClassHandler::ClassFilter::unregister()
int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata)
{
int ret;
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);
int ret = 0;
std::visit([&](auto method) {
using method_t = decltype(method);
if constexpr (std::is_same_v<method_t, cls_method_cxx_call_t>) {
// C++ call version
ret = method(ctx, &indata, &outdata);
} else if constexpr (std::is_same_v<method_t, cls_method_call_t>) {
// C version
char *out = nullptr;
int olen = 0;
ret = method(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);
}
} else {
static_assert(std::is_same_v<method_t, void>);
}
}
}, func);
return ret;
}

View File

@ -3,6 +3,8 @@
#ifndef CEPH_CLASSHANDLER_H
#define CEPH_CLASSHANDLER_H
#include <variant>
#include "include/types.h"
#include "common/ceph_mutex.h"
#include "objclass/objclass.h"
@ -18,11 +20,11 @@ public:
struct ClassData;
struct ClassMethod {
const std::string name;
using func_t = std::variant<cls_method_cxx_call_t, cls_method_call_t>;
func_t func;
int flags = 0;
ClassData *cls = nullptr;
std::string name;
int flags;
cls_method_call_t func;
cls_method_cxx_call_t cxx_func;
int exec(cls_method_context_t ctx,
ceph::bufferlist& indata,
@ -33,8 +35,9 @@ public:
std::lock_guard l(cls->handler->mutex);
return flags;
}
ClassMethod() : flags(0), func(0), cxx_func(0) {}
ClassMethod(const char* name, func_t call, int flags, ClassData* cls)
: name{name}, func{call}, flags{flags}, cls{cls}
{}
};
struct ClassFilter {