]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
objclass: enable unregistering filter factory
authorJohn Spray <john.spray@redhat.com>
Tue, 11 Aug 2015 14:56:59 +0000 (15:56 +0100)
committerJohn Spray <john.spray@redhat.com>
Thu, 27 Aug 2015 13:13:46 +0000 (14:13 +0100)
Signed-off-by: John Spray <john.spray@redhat.com>
src/objclass/class_api.cc
src/objclass/objclass.h
src/osd/ClassHandler.cc
src/osd/ClassHandler.h
src/osd/ReplicatedPG.cc

index 09b7f4f93c2184d1c341c8e30876d8ed6bb328ea..a3c065cc726ce6ac370318fae0ab0ff41887724f 100644 (file)
@@ -82,12 +82,23 @@ int cls_unregister_method(cls_method_handle_t handle)
   return 1;
 }
 
-int cls_register_cxx_filter(cls_handle_t hclass, const std::string &filter_name,
-                           cls_cxx_filter_factory_t fn)
+int cls_register_cxx_filter(cls_handle_t hclass,
+                            const std::string &filter_name,
+                            cls_cxx_filter_factory_t fn,
+                            cls_filter_handle_t *handle)
 {
   ClassHandler::ClassData *cls = (ClassHandler::ClassData *)hclass;
-  cls->register_cxx_filter(filter_name, fn);
-  return 0;
+  cls_filter_handle_t hfilter = (cls_filter_handle_t)cls->register_cxx_filter(filter_name, fn);
+  if (handle) {
+    *handle = hfilter;
+  }
+  return (hfilter != NULL);
+}
+
+void cls_unregister_filter(cls_filter_handle_t handle)
+{
+  ClassHandler::ClassFilter *filter = (ClassHandler::ClassFilter *)handle;
+  filter->unregister();
 }
 
 int cls_call(cls_method_context_t hctx, const char *cls, const char *method,
index e14d6a6dc4b58d59d08fed9e9c7a9c1fba0c7f6b..9275ad98b5f1dcaf0dd2539cc2381b6e46ab55eb 100644 (file)
@@ -35,6 +35,7 @@ void __cls_init();
 
 typedef void *cls_handle_t;
 typedef void *cls_method_handle_t;
+typedef void *cls_filter_handle_t;
 typedef void *cls_method_context_t;
 typedef int (*cls_method_call_t)(cls_method_context_t ctx,
                                 char *indata, int datalen,
@@ -71,6 +72,7 @@ extern int cls_unregister(cls_handle_t);
 extern int cls_register_method(cls_handle_t hclass, const char *method, int flags,
                         cls_method_call_t class_call, cls_method_handle_t *handle);
 extern int cls_unregister_method(cls_method_handle_t handle);
+extern void cls_unregister_filter(cls_filter_handle_t handle);
 
 
 
@@ -128,7 +130,8 @@ extern int cls_register_cxx_method(cls_handle_t hclass, const char *method, int
 
 extern int cls_register_cxx_filter(cls_handle_t hclass,
                                    const std::string &filter_name,
-                                  cls_cxx_filter_factory_t fn);
+                                  cls_cxx_filter_factory_t fn,
+                                   cls_filter_handle_t *handle=NULL);
 
 extern int cls_cxx_create(cls_method_context_t hctx, bool exclusive);
 extern int cls_cxx_remove(cls_method_context_t hctx);
index ea6fed89fd6f36873e619533810e3b0a14d87c3e..87d5a75a30122b16b14e5edc2c251c1d16bf6a11 100644 (file)
@@ -221,11 +221,15 @@ ClassHandler::ClassMethod *ClassHandler::ClassData::register_cxx_method(const ch
   return &method;
 }
 
-void ClassHandler::ClassData::register_cxx_filter(
+ClassHandler::ClassFilter *ClassHandler::ClassData::register_cxx_filter(
     const std::string &filter_name,
     cls_cxx_filter_factory_t fn)
 {
-  filters_map[filter_name] = fn;
+  ClassFilter &filter = filters_map[filter_name];
+  filter.fn = fn;
+  filter.name = filter_name;
+  filter.cls = this;
+  return &filter;
 }
 
 ClassHandler::ClassMethod *ClassHandler::ClassData::_get_method(const char *mname)
@@ -259,6 +263,20 @@ void ClassHandler::ClassMethod::unregister()
   cls->unregister_method(this);
 }
 
+void ClassHandler::ClassData::unregister_filter(ClassHandler::ClassFilter *filter)
+{
+  /* no need for locking, called under the class_init mutex */
+   map<string, ClassFilter>::iterator iter = filters_map.find(filter->name);
+   if (iter == filters_map.end())
+     return;
+   filters_map.erase(iter);
+}
+
+void ClassHandler::ClassFilter::unregister()
+{
+  cls->unregister_filter(this);
+}
+
 int ClassHandler::ClassMethod::exec(cls_method_context_t ctx, bufferlist& indata, bufferlist& outdata)
 {
   int ret;
index 843214d8d527dc7395030ce24372cc44fd7d1b61..e4bb9991e12054694c5a0f71f7f28e35faadcc66 100644 (file)
@@ -35,6 +35,17 @@ public:
     ClassMethod() : cls(0), flags(0), func(0), cxx_func(0) {}
   };
 
+  struct ClassFilter {
+    struct ClassHandler::ClassData *cls;
+    std::string name;
+    cls_cxx_filter_factory_t fn;
+
+    void unregister();
+
+    ClassFilter() : fn(0)
+    {}
+  };
+
   struct ClassData {
     enum Status { 
       CLASS_UNKNOWN,
@@ -49,7 +60,7 @@ public:
     void *handle;
 
     map<string, ClassMethod> methods_map;
-    map<string, cls_cxx_filter_factory_t> filters_map;
+    map<string, ClassFilter> filters_map;
 
     set<ClassData *> dependencies;         /* our dependencies */
     set<ClassData *> missing_dependencies; /* only missing dependencies */
@@ -65,9 +76,10 @@ public:
     ClassMethod *register_cxx_method(const char *mname, int flags, cls_method_cxx_call_t func);
     void unregister_method(ClassMethod *method);
 
-    void register_cxx_filter(
+    ClassFilter *register_cxx_filter(
         const std::string &filter_name,
         cls_cxx_filter_factory_t fn);
+    void unregister_filter(ClassFilter *method);
 
     ClassMethod *get_method(const char *mname) {
       Mutex::Locker l(handler->mutex);
@@ -75,10 +87,15 @@ public:
     }
     int get_method_flags(const char *mname);
 
-    cls_cxx_filter_factory_t get_filter(const std::string &filter_name)
+    ClassFilter *get_filter(const std::string &filter_name)
     {
       Mutex::Locker l(handler->mutex);
-      return filters_map[filter_name];
+      std::map<std::string, ClassFilter>::iterator i = filters_map.find(name);
+      if (i == filters_map.end()) {
+        return NULL;
+      } else {
+        return &(i->second);
+      }
     }
   };
 
index 20087794d4fdc51c338c42b76877fb62732db39b..e7df89023e86be6d5d1c821a8fb3f300ffdfad51 100644 (file)
@@ -623,13 +623,13 @@ int ReplicatedPG::get_pgls_filter(bufferlist::iterator& iter, PGLSFilter **pfilt
       assert(cls);
     }
 
-    cls_cxx_filter_factory_t fn = cls->get_filter(filter_name);
-    if (fn == NULL) {
+    ClassHandler::ClassFilter *class_filter = cls->get_filter(filter_name);
+    if (class_filter == NULL) {
       derr << "Error finding filter '" << filter_name << "' in class "
            << class_name << dendl;
       return -EINVAL;
     }
-    filter = fn(&iter);
+    filter = class_filter->fn(&iter);
     assert(filter);
   }