From 732995546409a6d6c279acbcd44d3dbc4a1a3195 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Galarneau?= Date: Fri, 17 Jul 2015 11:32:13 -0400 Subject: [PATCH] Load plugins and components MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérémie Galarneau --- Makefile.am | 2 +- .../plugin/component-factory-internal.h | 28 ++++--- include/babeltrace/plugin/plugin.h | 14 +++- plugins/component-factory.c | 76 ++++++++++++++----- 4 files changed, 87 insertions(+), 33 deletions(-) diff --git a/Makefile.am b/Makefile.am index 2cd22a5b..0544bd16 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ AM_CFLAGS = $(PACKAGE_CFLAGS) -I$(top_srcdir)/include ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = include types compat lib formats converter bindings tests doc extras plugins +SUBDIRS = include types compat lib formats plugins converter bindings tests doc extras dist_doc_DATA = ChangeLog LICENSE mit-license.txt gpl-2.0.txt \ std-ext-lib.txt README diff --git a/include/babeltrace/plugin/component-factory-internal.h b/include/babeltrace/plugin/component-factory-internal.h index 3149bad3..7aed5806 100644 --- a/include/babeltrace/plugin/component-factory-internal.h +++ b/include/babeltrace/plugin/component-factory-internal.h @@ -31,30 +31,40 @@ #include #include #include +#include #include #include -struct component_entry { +struct component_class { enum bt_component_type type; GString *name; }; -struct source_component_entry { - struct component_entry parent; +struct source_component_class { + struct component_class parent; bt_component_source_init_cb init; }; -struct sink_component_entry { - struct component_entry parent; +struct sink_component_class { + struct component_class parent; bt_component_sink_init_cb init; }; -struct bt_component_factory { - /** Array of GModule pointers */ - GPtrArray *modules; - /** Array of pointers to struct component_entry */ +struct plugin { + const char *name; + const char *author; + const char *license; + bt_plugin_init_func init; + bt_plugin_init_func exit; + GModule *module; + /** Array of pointers to struct component_class */ GPtrArray *components; }; +struct bt_component_factory { + /** Array of pointers to struct plugin */ + GPtrArray *plugins; +}; + #endif /* BABELTRACE_PLUGIN_COMPONENT_FACTORY_INTERNAL_H */ diff --git a/include/babeltrace/plugin/plugin.h b/include/babeltrace/plugin/plugin.h index a8e18499..945deb94 100644 --- a/include/babeltrace/plugin/plugin.h +++ b/include/babeltrace/plugin/plugin.h @@ -29,15 +29,21 @@ */ #include +#include +typedef enum bt_component_status (*bt_plugin_init_func)( + struct bt_component_factory *factory); +typedef void (*bt_plugin_exit_func)(void); + +/* A plugin must define the __bt_plugin_init symbol */ #define BT_PLUGIN_NAME(_x) const char *__bt_plugin_name = (_x) #define BT_PLUGIN_AUTHOR(_x) const char *__bt_plugin_author = (_x) #define BT_PLUGIN_LICENSE(_x) const char *__bt_plugin_license = (_x) -#define BT_PLUGIN_INIT(_x) void *__bt_plugin_init = (_x) -#define BT_PLUGIN_EXIT(_x) void *__bt_plugin_exit = (_x) +#define BT_PLUGIN_INIT(_x) bt_plugin_init __bt_plugin_init = (_x) +#define BT_PLUGIN_EXIT(_x) bt_plugin_exit __bt_plugin_exit = (_x) #define BT_PLUGIN_COMPONENT_CLASSES_BEGIN \ - enum bt_status __bt_plugin_register_component_classes(\ + enum bt_component_status __bt_plugin_register_component_classes(\ struct bt_component_factory *factory)\ { @@ -51,7 +57,7 @@ #define BT_PLUGIN_COMPONENT_CLASSES_END\ \ - return BT_STATUS_OK;\ + return BT_COMPONENT_STATUS_OK;\ }\ \ BT_PLUGIN_INIT(__bt_plugin_register_component_classes);\ diff --git a/plugins/component-factory.c b/plugins/component-factory.c index b4ebe3f2..74c6b72c 100644 --- a/plugins/component-factory.c +++ b/plugins/component-factory.c @@ -38,21 +38,48 @@ #define NATIVE_PLUGIN_SUFFIX_LEN sizeof(NATIVE_PLUGIN_SUFFIX) #define LIBTOOL_PLUGIN_SUFFIX ".la" #define LIBTOOL_PLUGIN_SUFFIX_LEN sizeof(LIBTOOL_PLUGIN_SUFFIX) -#define PLUGIN_SUFFIX_LEN max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX),\ - sizeof(LIBTOOL_PLUGIN_SUFFIX)) +#define PLUGIN_SUFFIX_LEN max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \ + sizeof(LIBTOOL_PLUGIN_SUFFIX)) static -void module_close(gpointer data) +void component_destroy(gpointer data) { - if (g_module_close((GModule *) data)) { + g_free(data); +} + +static +void plugin_destroy(gpointer data) +{ + struct plugin *plugin = data; + + if (plugin->module && g_module_close(plugin->module)) { printf_error("Failed to close plugin"); } + + if (plugin->components) { + g_ptr_array_free(plugin->components, TRUE); + } + + g_free(plugin); } static -void factory_destroy(gpointer data) +struct plugin *plugin_create(void) { - bt_component_factory_destroy((struct bt_component_factory *)data); + struct plugin *plugin = g_new0(struct plugin, 1); + + if (!plugin) { + goto end; + } + + plugin->components = g_ptr_array_new_with_free_func(component_destroy); + if (!plugin->components) { + g_free(plugin); + plugin = NULL; + goto end; + } +end: + return plugin; } /* Allocate dirent as recommended by READDIR(3), NOTES on readdir_r */ @@ -72,6 +99,12 @@ struct dirent *alloc_dirent(const char *path) return entry; } +static +struct plugin *load_plugin(GModule *module) +{ + return NULL; +} + static enum bt_component_factory_status bt_component_factory_load_file(struct bt_component_factory *factory, @@ -80,6 +113,7 @@ bt_component_factory_load_file(struct bt_component_factory *factory, enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK; size_t path_len; GModule *module; + struct plugin *plugin; if (!factory || !path) { ret = BT_COMPONENT_FACTORY_STATUS_INVAL; @@ -88,6 +122,7 @@ bt_component_factory_load_file(struct bt_component_factory *factory, path_len = strlen(path); if (path_len <= PLUGIN_SUFFIX_LEN) { + ret = BT_COMPONENT_FACTORY_STATUS_INVAL; goto end; } @@ -102,17 +137,29 @@ bt_component_factory_load_file(struct bt_component_factory *factory, strncmp(LIBTOOL_PLUGIN_SUFFIX, path + path_len - LIBTOOL_PLUGIN_SUFFIX_LEN, LIBTOOL_PLUGIN_SUFFIX_LEN)) { - /* Not a plugin file. */ + /* Name indicates that this is not a plugin file. */ + ret = BT_COMPONENT_FACTORY_STATUS_INVAL; goto end; } module = g_module_open(path, 0); if (!module) { printf_error("Module open error: %s", g_module_error()); + ret = BT_COMPONENT_FACTORY_STATUS_ERROR; goto end; } /* Check if the module defines the appropriate entry points */ + plugin = load_plugin(module); + if (!plugin) { + /* Not a Babeltrace plugin */ + ret = BT_COMPONENT_FACTORY_STATUS_INVAL; + if (!g_module_close(module)) { + printf_error("Module close error: %s", + g_module_error()); + } + goto end; + } end: return ret; } @@ -178,11 +225,7 @@ bt_component_factory_load_dir_recursive(struct bt_component_factory *factory, goto end; } } else if (S_ISREG(st.st_mode)) { - ret = bt_component_factory_load_file(factory, - file_path); - if (ret != BT_COMPONENT_FACTORY_STATUS_OK) { - goto end; - } + bt_component_factory_load_file(factory, file_path); } } end: @@ -210,13 +253,8 @@ bt_component_factory_create(void) goto end; } - factory->modules = g_ptr_array_new_with_free_func(module_close); - if (!factory->modules) { - goto error; - } - - factory->components = g_ptr_array_new_with_free_func(factory_destroy); - if (factory->components) { + factory->plugins = g_ptr_array_new_with_free_func(plugin_destroy); + if (!factory->plugins) { goto error; } end: -- 2.34.1