From e749b214e7eb70aa56b61c12de3d988bdf9b3413 Mon Sep 17 00:00:00 2001 From: John Spray Date: Tue, 11 Aug 2015 15:56:59 +0100 Subject: [PATCH] objclass: enable unregistering filter factory Signed-off-by: John Spray --- src/objclass/class_api.cc | 19 +++++++++++++++---- src/objclass/objclass.h | 5 ++++- src/osd/ClassHandler.cc | 22 ++++++++++++++++++++-- src/osd/ClassHandler.h | 25 +++++++++++++++++++++---- src/osd/ReplicatedPG.cc | 6 +++--- 5 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/objclass/class_api.cc b/src/objclass/class_api.cc index 09b7f4f93c218..a3c065cc726ce 100644 --- a/src/objclass/class_api.cc +++ b/src/objclass/class_api.cc @@ -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, diff --git a/src/objclass/objclass.h b/src/objclass/objclass.h index e14d6a6dc4b58..9275ad98b5f1d 100644 --- a/src/objclass/objclass.h +++ b/src/objclass/objclass.h @@ -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); diff --git a/src/osd/ClassHandler.cc b/src/osd/ClassHandler.cc index ea6fed89fd6f3..87d5a75a30122 100644 --- a/src/osd/ClassHandler.cc +++ b/src/osd/ClassHandler.cc @@ -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::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; diff --git a/src/osd/ClassHandler.h b/src/osd/ClassHandler.h index 843214d8d527d..e4bb9991e1205 100644 --- a/src/osd/ClassHandler.h +++ b/src/osd/ClassHandler.h @@ -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 methods_map; - map filters_map; + map filters_map; set dependencies; /* our dependencies */ set 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::iterator i = filters_map.find(name); + if (i == filters_map.end()) { + return NULL; + } else { + return &(i->second); + } } }; diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 20087794d4fdc..e7df89023e86b 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -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); } -- 2.39.5