#include <babeltrace/graph/notification-iterator.h>
#include <babeltrace/ref.h>
#include <babeltrace/values.h>
+#include <unistd.h>
#include <stdlib.h>
#include <popt.h>
#include <string.h>
}
static
-void add_to_loaded_plugins(struct bt_plugin **plugins)
+void add_to_loaded_plugins(struct bt_plugin_set *plugin_set)
{
- while (*plugins) {
- struct bt_plugin *plugin = *plugins;
- /* Check if it's already loaded (from another path). */
+ int i;
+ int count;
+
+ count = bt_plugin_set_get_plugin_count(plugin_set);
+ assert(count >= 0);
+
+ for (i = 0; i < count; i++) {
+ struct bt_plugin *plugin =
+ bt_plugin_set_get_plugin(plugin_set, i);
struct bt_plugin *loaded_plugin =
find_plugin(bt_plugin_get_name(plugin));
+ assert(plugin);
+
if (loaded_plugin) {
printf_verbose("Not loading plugin `%s`: already loaded from `%s`\n",
bt_plugin_get_path(plugin),
bt_plugin_get_path(loaded_plugin));
- BT_PUT(loaded_plugin);
- BT_PUT(plugin);
+ bt_put(loaded_plugin);
} else {
- /* Transfer ownership to global array. */
- g_ptr_array_add(loaded_plugins, plugin);
+ /* Add to global array. */
+ g_ptr_array_add(loaded_plugins, bt_get(plugin));
}
- *(plugins++) = NULL;
+
+ bt_put(plugin);
}
}
for (i = 0; i < nr_paths; i++) {
struct bt_value *plugin_path_value = NULL;
const char *plugin_path;
- struct bt_plugin **plugins;
+ struct bt_plugin_set *plugin_set;
plugin_path_value = bt_value_array_get(plugin_paths, i);
if (bt_value_string_get(plugin_path_value,
continue;
}
- plugins = bt_plugin_create_all_from_dir(plugin_path, false);
- if (!plugins) {
+ plugin_set = bt_plugin_create_all_from_dir(plugin_path, false);
+ if (!plugin_set) {
printf_debug("Unable to dynamically load plugins from path %s.\n",
plugin_path);
BT_PUT(plugin_path_value);
continue;
}
- add_to_loaded_plugins(plugins);
- free(plugins);
-
+ add_to_loaded_plugins(plugin_set);
+ bt_put(plugin_set);
BT_PUT(plugin_path_value);
}
end:
int load_static_plugins(void)
{
int ret = 0;
- struct bt_plugin **plugins;
+ struct bt_plugin_set *plugin_set;
- plugins = bt_plugin_create_all_from_static();
- if (!plugins) {
+ plugin_set = bt_plugin_create_all_from_static();
+ if (!plugin_set) {
printf_debug("Unable to load static plugins.\n");
ret = -1;
goto end;
}
- add_to_loaded_plugins(plugins);
- free(plugins);
+ add_to_loaded_plugins(plugin_set);
+ bt_put(plugin_set);
end:
return ret;
}
void (*destroy_spec_data)(struct bt_plugin *);
};
+struct bt_plugin_set {
+ struct bt_object base;
+
+ /* Array of struct bt_plugin * */
+ GPtrArray *plugins;
+};
+
static inline
void bt_plugin_destroy(struct bt_object *obj)
{
plugin->frozen = true;
}
+static
+void bt_plugin_set_destroy(struct bt_object *obj)
+{
+ struct bt_plugin_set *plugin_set =
+ container_of(obj, struct bt_plugin_set, base);
+
+ if (!plugin_set) {
+ return;
+ }
+
+ if (plugin_set->plugins) {
+ g_ptr_array_free(plugin_set->plugins, TRUE);
+ }
+
+ g_free(plugin_set);
+}
+
+static inline
+struct bt_plugin_set *bt_plugin_set_create(void)
+{
+ struct bt_plugin_set *plugin_set = g_new0(struct bt_plugin_set, 1);
+
+ if (!plugin_set) {
+ goto end;
+ }
+
+ bt_object_init(plugin_set, bt_plugin_set_destroy);
+
+ plugin_set->plugins = g_ptr_array_new_with_free_func(
+ (GDestroyNotify) bt_put);
+ if (!plugin_set->plugins) {
+ BT_PUT(plugin_set);
+ goto end;
+ }
+
+end:
+ return plugin_set;
+}
+
+static inline
+void bt_plugin_set_add_plugin(struct bt_plugin_set *plugin_set,
+ struct bt_plugin *plugin)
+{
+ assert(plugin_set);
+ assert(plugin);
+ g_ptr_array_add(plugin_set->plugins, bt_get(plugin));
+}
+
#endif /* BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H */
};
BT_HIDDEN
-struct bt_plugin **bt_plugin_so_create_all_from_file(const char *path);
+struct bt_plugin_set *bt_plugin_so_create_all_from_file(const char *path);
BT_HIDDEN
-struct bt_plugin **bt_plugin_so_create_all_from_static(void);
+struct bt_plugin_set *bt_plugin_so_create_all_from_static(void);
BT_HIDDEN
void bt_plugin_so_on_add_component_class(struct bt_plugin *plugin,
#endif
struct bt_plugin;
+struct bt_plugin_set;
struct bt_component_class;
/**
const char *plugin_name, const char *component_class_name,
enum bt_component_class_type component_class_type);
-extern struct bt_plugin **bt_plugin_create_all_from_file(const char *path);
+extern struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path);
-extern struct bt_plugin **bt_plugin_create_all_from_dir(const char *path,
+extern struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path,
bool recurse);
-extern struct bt_plugin **bt_plugin_create_all_from_static(void);
+extern struct bt_plugin_set *bt_plugin_create_all_from_static(void);
/**
* Get the name of a plug-in.
struct bt_plugin *plugin, const char *name,
enum bt_component_class_type type);
+extern
+int bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set);
+
+extern
+struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set,
+ unsigned int index);
+
#ifdef __cplusplus
}
#endif
#include <babeltrace/plugin/plugin.h>
extern
-struct bt_plugin **bt_plugin_python_create_all_from_file(const char *path);
+struct bt_plugin_set *bt_plugin_python_create_all_from_file(const char *path);
#endif /* BABELTRACE_PLUGIN_PYTHON_PLUGIN_PROVIDER_INTERNAL_H */
}
static
-struct bt_plugin **bt_plugin_so_create_all_from_sections(
+struct bt_plugin_set *bt_plugin_so_create_all_from_sections(
struct bt_plugin_so_shared_lib_handle *shared_lib_handle,
struct __bt_plugin_descriptor const * const *descriptors_begin,
struct __bt_plugin_descriptor const * const *descriptors_end,
size_t cc_descriptors_count;
size_t cc_descr_attrs_count;
size_t i;
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set = NULL;
descriptor_count = descriptors_end - descriptors_begin;
attrs_count = attrs_end - attrs_begin;
cc_descriptors_begin, cc_descriptors_end, cc_descriptors_count);
printf_verbose("Section: Plugin component class descriptor attributes: [%p - %p], (%zu elements)\n",
cc_descr_attrs_begin, cc_descr_attrs_end, cc_descr_attrs_count);
- plugins = calloc(descriptor_count + 1, sizeof(*plugins));
- if (!plugins) {
+ plugin_set = bt_plugin_set_create();
+ if (!plugin_set) {
goto error;
}
goto error;
}
- /* Transfer ownership to the array */
- plugins[i] = plugin;
+ /* Add to plugin set */
+ bt_plugin_set_add_plugin(plugin_set, plugin);
+ bt_put(plugin);
}
goto end;
error:
- g_free(plugins);
- plugins = NULL;
+ BT_PUT(plugin_set);
end:
- return plugins;
+ return plugin_set;
}
BT_HIDDEN
-struct bt_plugin **bt_plugin_so_create_all_from_static(void)
+struct bt_plugin_set *bt_plugin_so_create_all_from_static(void)
{
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set = NULL;
struct bt_plugin_so_shared_lib_handle *shared_lib_handle =
bt_plugin_so_shared_lib_handle_create(NULL);
goto end;
}
- plugins = bt_plugin_so_create_all_from_sections(shared_lib_handle,
+ plugin_set = bt_plugin_so_create_all_from_sections(shared_lib_handle,
SECTION_BEGIN(__bt_plugin_descriptors),
SECTION_END(__bt_plugin_descriptors),
SECTION_BEGIN(__bt_plugin_descriptor_attributes),
end:
BT_PUT(shared_lib_handle);
- return plugins;
+ return plugin_set;
}
BT_HIDDEN
-struct bt_plugin **bt_plugin_so_create_all_from_file(const char *path)
+struct bt_plugin_set *bt_plugin_so_create_all_from_file(const char *path)
{
size_t path_len;
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set = NULL;
struct __bt_plugin_descriptor const * const *descriptors_begin = NULL;
struct __bt_plugin_descriptor const * const *descriptors_end = NULL;
struct __bt_plugin_descriptor_attribute const * const *attrs_begin = NULL;
}
/* Initialize plugin */
- plugins = bt_plugin_so_create_all_from_sections(shared_lib_handle,
+ plugin_set = bt_plugin_so_create_all_from_sections(shared_lib_handle,
descriptors_begin, descriptors_end, attrs_begin, attrs_end,
cc_descriptors_begin, cc_descriptors_end,
cc_descr_attrs_begin, cc_descr_attrs_end);
end:
BT_PUT(shared_lib_handle);
- return plugins;
+ return plugin_set;
}
static
#ifdef BT_BUILT_IN_PYTHON_PLUGIN_SUPPORT
#include <babeltrace/plugin/python-plugin-provider-internal.h>
static
-struct bt_plugin **(*bt_plugin_python_create_all_from_file_sym)(const char *path) =
+struct bt_plugin_set *(*bt_plugin_python_create_all_from_file_sym)(const char *path) =
bt_plugin_python_create_all_from_file;
#else /* BT_BUILT_IN_PYTHON_PLUGIN_SUPPORT */
static GModule *python_plugin_provider_module;
static
-struct bt_plugin **(*bt_plugin_python_create_all_from_file_sym)(const char *path);
+struct bt_plugin_set *(*bt_plugin_python_create_all_from_file_sym)(const char *path);
__attribute__((constructor)) static
void init_python_plugin_provider(void) {
}
#endif
-struct bt_plugin **bt_plugin_create_all_from_static(void)
+extern
+int bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set)
+{
+ int count = -1;
+
+ if (!plugin_set) {
+ goto end;
+ }
+
+ count = plugin_set->plugins->len;
+
+end:
+ return count;
+}
+
+extern
+struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set,
+ unsigned int index)
+{
+ struct bt_plugin *plugin = NULL;
+
+ if (!plugin_set || index >= plugin_set->plugins->len) {
+ goto end;
+ }
+
+ plugin = bt_get(g_ptr_array_index(plugin_set->plugins, index));
+
+end:
+ return plugin;
+}
+
+struct bt_plugin_set *bt_plugin_create_all_from_static(void)
{
return bt_plugin_so_create_all_from_static();
}
-struct bt_plugin **bt_plugin_create_all_from_file(const char *path)
+struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path)
{
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set = NULL;
if (!path) {
goto end;
printf_verbose("Trying to load plugins from `%s`\n", path);
/* Try shared object plugins */
- plugins = bt_plugin_so_create_all_from_file(path);
- if (plugins) {
+ plugin_set = bt_plugin_so_create_all_from_file(path);
+ if (plugin_set) {
goto end;
}
/* Try Python plugins if support is available */
if (bt_plugin_python_create_all_from_file_sym) {
- plugins = bt_plugin_python_create_all_from_file_sym(path);
- if (plugins) {
+ plugin_set = bt_plugin_python_create_all_from_file_sym(path);
+ if (plugin_set) {
goto end;
}
}
end:
- return plugins;
+ return plugin_set;
}
static void destroy_gstring(void *data)
g_string_free(data, TRUE);
}
-void free_plugins(struct bt_plugin **plugins) {
- if (plugins) {
- struct bt_plugin **cur_plugin = plugins;
-
- while (*cur_plugin) {
- bt_put(*cur_plugin);
- cur_plugin++;
- }
-
- free(plugins);
- }
-}
-
struct bt_plugin *bt_plugin_find(const char *plugin_name)
{
const char *system_plugin_dir;
char *home_plugin_dir = NULL;
const char *envvar;
struct bt_plugin *plugin = NULL;
- struct bt_plugin **plugins = NULL;
- struct bt_plugin **cur_plugin;
+ struct bt_plugin_set *plugin_set = NULL;
GPtrArray *dirs = NULL;
int ret;
- size_t i;
+ size_t i, j;
if (!plugin_name) {
goto end;
printf_verbose("Trying to load plugins from directory `%s`\n",
dir->str);
- free_plugins(plugins);
- plugins = bt_plugin_create_all_from_dir(dir->str, false);
- if (!plugins) {
+ BT_PUT(plugin_set);
+ plugin_set = bt_plugin_create_all_from_dir(dir->str, false);
+ if (!plugin_set) {
continue;
}
- cur_plugin = plugins;
+ for (j = 0; j < plugin_set->plugins->len; j++) {
+ struct bt_plugin *candidate_plugin =
+ g_ptr_array_index(plugin_set->plugins, j);
- while (*cur_plugin) {
- if (strcmp(bt_plugin_get_name(*cur_plugin), plugin_name)
- == 0) {
- plugin = bt_get(*cur_plugin);
+ if (strcmp(bt_plugin_get_name(candidate_plugin),
+ plugin_name) == 0) {
+ plugin = bt_get(candidate_plugin);
goto end;
}
-
- cur_plugin++;
}
}
- free_plugins(plugins);
- plugins = bt_plugin_create_all_from_static();
- cur_plugin = plugins;
+ bt_put(plugin_set);
+ plugin_set = bt_plugin_create_all_from_static();
+
+ for (j = 0; j < plugin_set->plugins->len; j++) {
+ struct bt_plugin *candidate_plugin =
+ g_ptr_array_index(plugin_set->plugins, j);
- while (*cur_plugin) {
- if (strcmp(bt_plugin_get_name(*cur_plugin), plugin_name) == 0) {
- plugin = bt_get(*cur_plugin);
+ if (strcmp(bt_plugin_get_name(candidate_plugin),
+ plugin_name) == 0) {
+ plugin = bt_get(candidate_plugin);
goto end;
}
-
- cur_plugin++;
}
end:
free(home_plugin_dir);
- free_plugins(plugins);
+ bt_put(plugin_set);
if (dirs) {
g_ptr_array_free(dirs, TRUE);
static
enum bt_plugin_status bt_plugin_create_append_all_from_dir(
- GPtrArray *plugins, const char *path, bool recurse)
+ struct bt_plugin_set *plugin_set, const char *path,
+ bool recurse)
{
DIR *directory = NULL;
struct dirent *entry = NULL, *result = NULL;
}
if (S_ISDIR(st.st_mode) && recurse) {
- ret = bt_plugin_create_append_all_from_dir(plugins,
+ ret = bt_plugin_create_append_all_from_dir(plugin_set,
file_path, true);
if (ret < 0) {
goto end;
}
} else if (S_ISREG(st.st_mode)) {
- struct bt_plugin **plugins_from_file =
+ struct bt_plugin_set *plugins_from_file =
bt_plugin_create_all_from_file(file_path);
if (plugins_from_file) {
- struct bt_plugin **plugin;
+ size_t j;
+
+ for (j = 0; j < plugins_from_file->plugins->len; j++) {
+ struct bt_plugin *plugin =
+ g_ptr_array_index(plugins_from_file->plugins, j);
- for (plugin = plugins_from_file; *plugin; plugin++) {
- /* Transfer ownership to array */
- g_ptr_array_add(plugins, *plugin);
+ bt_plugin_set_add_plugin(plugin_set,
+ plugin);
}
- free(plugins_from_file);
+ bt_put(plugins_from_file);
}
}
}
return ret;
}
-struct bt_plugin **bt_plugin_create_all_from_dir(const char *path,
+struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path,
bool recurse)
{
- GPtrArray *plugins_array = g_ptr_array_new();
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set;
enum bt_plugin_status status;
+ plugin_set = bt_plugin_set_create();
+ if (!plugin_set) {
+ goto error;
+ }
+
/* Append found plugins to array */
- status = bt_plugin_create_append_all_from_dir(plugins_array, path,
+ status = bt_plugin_create_append_all_from_dir(plugin_set, path,
recurse);
if (status < 0) {
goto error;
}
- /* Add sentinel to array */
- g_ptr_array_add(plugins_array, NULL);
- plugins = (struct bt_plugin **) plugins_array->pdata;
goto end;
error:
- if (plugins_array) {
- g_ptr_array_free(plugins_array, TRUE);
- plugins_array = NULL;
- }
+ BT_PUT(plugin_set);
end:
- if (plugins_array) {
- g_ptr_array_free(plugins_array, FALSE);
- }
-
- return plugins;
+ return plugin_set;
}
const char *bt_plugin_get_name(struct bt_plugin *plugin)
}
G_MODULE_EXPORT
-struct bt_plugin **bt_plugin_python_create_all_from_file(const char *path)
+struct bt_plugin_set *bt_plugin_python_create_all_from_file(const char *path)
{
- struct bt_plugin **plugins = NULL;
+ struct bt_plugin_set *plugin_set = NULL;
+ struct bt_plugin *plugin = NULL;
PyObject *py_plugin_info = NULL;
gchar *basename = NULL;
size_t path_len;
/*
* Get bt_plugin from plugin info object.
- *
- * calloc(2, ...) because a single Python plugin file always
- * provides a single Babeltrace plugin (second item is the
- * sentinel).
*/
- plugins = calloc(2, sizeof(*plugins));
- if (!plugins) {
+ plugin = bt_plugin_from_python_plugin_info(py_plugin_info);
+ if (!plugin) {
goto error;
}
- plugins[0] = bt_plugin_from_python_plugin_info(py_plugin_info);
- if (!plugins[0]) {
+ bt_plugin_set_path(plugin, path);
+ plugin_set = bt_plugin_set_create();
+ if (!plugin_set) {
goto error;
}
- bt_plugin_set_path(plugins[0], path);
+ bt_plugin_set_add_plugin(plugin_set, plugin);
goto end;
error:
- if (plugins) {
- BT_PUT(plugins[0]);
- free(plugins);
- plugins = NULL;
- }
+ BT_PUT(plugin_set);
end:
+ bt_put(plugin);
Py_XDECREF(py_plugin_info);
g_free(basename);
- return plugins;
+ return plugin_set;
}
static void test_invalid(const char *plugin_dir)
{
- struct bt_plugin **plugins;
+ struct bt_plugin_set *plugin_set;
- plugins = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
- ok(!plugins, "bt_plugin_create_all_from_file() fails with a non-existing file");
+ plugin_set = bt_plugin_create_all_from_file(NON_EXISTING_PATH);
+ ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a non-existing file");
- plugins = bt_plugin_create_all_from_file(plugin_dir);
- ok(!plugins, "bt_plugin_create_all_from_file() fails with a directory");
+ plugin_set = bt_plugin_create_all_from_file(plugin_dir);
+ ok(!plugin_set, "bt_plugin_create_all_from_file() fails with a directory");
ok(!bt_plugin_create_all_from_file(NULL),
"bt_plugin_create_all_from_file() handles NULL correctly");
static void test_minimal(const char *plugin_dir)
{
- struct bt_plugin **plugins;
+ struct bt_plugin_set *plugin_set;
struct bt_plugin *plugin;
char *minimal_path = get_test_plugin_path(plugin_dir, "minimal");
diag("minimal plugin test below");
reset_test_plugin_symbols();
- plugins = bt_plugin_create_all_from_file(minimal_path);
- ok(plugins && plugins[0], "bt_plugin_create_all_from_file() succeeds with a valid file");
+ plugin_set = bt_plugin_create_all_from_file(minimal_path);
+ ok(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1,
+ "bt_plugin_create_all_from_file() succeeds with a valid file");
ok(test_plugin_init_called, "plugin's initialization function is called during bt_plugin_create_all_from_file()");
- ok(plugins && plugins[0] && !plugins[1],
+ ok(bt_plugin_set_get_plugin_count(plugin_set) == 1,
"bt_plugin_create_all_from_file() returns the expected number of plugins");
- plugin = plugins[0];
+ plugin = bt_plugin_set_get_plugin(plugin_set, 0);
ok(strcmp(bt_plugin_get_name(plugin), "test_minimal") == 0,
"bt_plugin_get_name() returns the expected name");
ok(strcmp(bt_plugin_get_description(plugin),
"bt_plugin_get_path() returns the expected path");
ok(bt_plugin_get_component_class_count(plugin) == 0,
"bt_plugin_get_component_class_count() returns the expected value");
- BT_PUT(plugin);
+ bt_put(plugin);
+ bt_put(plugin_set);
ok(test_plugin_exit_called, "plugin's exit function is called when the plugin is destroyed");
free(minimal_path);
- free(plugins);
}
static void test_sfs(const char *plugin_dir)
{
- struct bt_plugin **plugins;
+ struct bt_plugin_set *plugin_set;
struct bt_plugin *plugin;
struct bt_component_class *sink_comp_class;
struct bt_component_class *source_comp_class;
assert(sfs_path);
diag("sfs plugin test below");
- plugins = bt_plugin_create_all_from_file(sfs_path);
- assert(plugins && plugins[0]);
- plugin = plugins[0];
+ plugin_set = bt_plugin_create_all_from_file(sfs_path);
+ assert(plugin_set && bt_plugin_set_get_plugin_count(plugin_set) == 1);
+ plugin = bt_plugin_set_get_plugin(plugin_set, 0);
ok(bt_plugin_get_version(plugin, &major, &minor, &patch, &extra) ==
BT_PLUGIN_STATUS_OK,
"bt_plugin_get_version() succeeds when there's a version");
BT_PUT(sink_component);
free(sfs_path);
- free(plugins);
+ bt_put(plugin_set);
bt_put(object);
bt_put(res_params);
bt_put(results);
static void test_create_all_from_dir(const char *plugin_dir)
{
- struct bt_plugin **plugins;
- struct bt_plugin *plugin;
- int i;
+ struct bt_plugin_set *plugin_set;
diag("create from all test below");
- plugins = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false);
- ok(!plugins,
+ plugin_set = bt_plugin_create_all_from_dir(NON_EXISTING_PATH, false);
+ ok(!plugin_set,
"bt_plugin_create_all_from_dir() fails with an invalid path");
- plugins = bt_plugin_create_all_from_dir(plugin_dir, false);
- ok(plugins, "bt_plugin_create_all_from_dir() succeeds with a valid path");
-
- i = 0;
- while ((plugin = plugins[i])) {
- BT_PUT(plugin);
- i++;
- }
+ plugin_set = bt_plugin_create_all_from_dir(plugin_dir, false);
+ ok(plugin_set, "bt_plugin_create_all_from_dir() succeeds with a valid path");
/* 2 or 4, if `.la` files are considered or not */
- ok(i == 2 || i == 4, "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
+ ok(bt_plugin_set_get_plugin_count(plugin_set) == 2 ||
+ bt_plugin_set_get_plugin_count(plugin_set) == 4,
+ "bt_plugin_create_all_from_dir() returns the expected number of plugin objects");
- free(plugins);
+ bt_put(plugin_set);
}
static void test_find(const char *plugin_dir)