#include <babeltrace/plugin/component-factory.h>
#include <babeltrace/plugin/component.h>
#include <babeltrace/plugin/plugin-system.h>
+#include <babeltrace/plugin/plugin.h>
#include <glib.h>
#include <gmodule.h>
-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 */
*/
#include <babeltrace/plugin/component-factory.h>
+#include <babeltrace/plugin/component.h>
+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)\
{
#define BT_PLUGIN_COMPONENT_CLASSES_END\
\
- return BT_STATUS_OK;\
+ return BT_COMPONENT_STATUS_OK;\
}\
\
BT_PLUGIN_INIT(__bt_plugin_register_component_classes);\
#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 */
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,
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;
path_len = strlen(path);
if (path_len <= PLUGIN_SUFFIX_LEN) {
+ ret = BT_COMPONENT_FACTORY_STATUS_INVAL;
goto end;
}
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;
}
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:
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: