]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/ClassHandler: use std::variant for storing func 28363/head
authorKefu Chai <kchai@redhat.com>
Mon, 3 Jun 2019 10:28:34 +0000 (18:28 +0800)
committerKefu Chai <kchai@redhat.com>
Mon, 3 Jun 2019 13:21:52 +0000 (21:21 +0800)
for better readablity, and less error-prone

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/osd/ClassHandler.cc
src/osd/ClassHandler.h

index b84308b1a0ad9c78d54b7808bb4b577b42eb1787..e83dfd08ce700e0346f25fadabc9e804a3111a1a 100644 (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;
 }
 
index deace6011991b59144ccc9257c3d1bd3c2a03243..46f4cc983192f919cbd3a85731c537833186ffa0 100644 (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 {