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,
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,
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);
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);
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)
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;
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,
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 */
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);
}
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);
+ }
}
};
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);
}