#include <sys/stat.h>
#include <gmodule.h>
#include <stdbool.h>
+#include <dirent.h>
#define NATIVE_PLUGIN_SUFFIX ".so"
#define NATIVE_PLUGIN_SUFFIX_LEN sizeof(NATIVE_PLUGIN_SUFFIX)
module = g_module_open(path, 0);
if (!module) {
- printf_error("Module open error: %s", g_module_error());
+ printf_verbose("Module open error: %s\n", g_module_error());
ret = BT_COMPONENT_FACTORY_STATUS_ERROR;
goto end;
}
goto end;
}
- factory->current_plugin = plugin;
- component_status = bt_plugin_register_component_classes(plugin,
- factory);
- factory->current_plugin = NULL;
+ BT_MOVE(factory->current_plugin, plugin);
+ component_status = bt_plugin_register_component_classes(
+ factory->current_plugin, factory);
+ BT_PUT(factory->current_plugin);
if (component_status != BT_COMPONENT_STATUS_OK) {
switch (component_status) {
case BT_COMPONENT_STATUS_NOMEM:
break;
}
- BT_PUT(plugin);
goto end;
}
end:
static
enum bt_component_factory_status
-bt_component_factory_load_dir_recursive(struct bt_component_factory *factory,
- const char *path)
+bt_component_factory_load_dir(struct bt_component_factory *factory,
+ const char *path, bool recurse)
{
DIR *directory = NULL;
struct dirent *entry = NULL, *result = NULL;
continue;
}
- if (S_ISDIR(st.st_mode)) {
- ret = bt_component_factory_load_dir_recursive(factory,
- file_path);
+ if (S_ISDIR(st.st_mode) && recurse) {
+ ret = bt_component_factory_load_dir(factory,
+ file_path, true);
if (ret != BT_COMPONENT_FACTORY_STATUS_OK) {
goto end;
}
if (type != BT_COMPONENT_TYPE_UNKNOWN) {
if (type != bt_component_class_get_type(
component_class)) {
+ bt_put(plugin);
continue;
}
}
assert(cur_plugin_name);
if (strcmp(plugin_name, cur_plugin_name)) {
+ bt_put(plugin);
continue;
}
}
assert(cur_cc_name);
if (strcmp(component_name, cur_cc_name)) {
+ bt_put(plugin);
continue;
}
}
+ bt_put(plugin);
/* All criteria met. */
goto match;
}
return bt_get(component_class);
}
-enum bt_component_factory_status bt_component_factory_load(
- struct bt_component_factory *factory, const char *path)
+static
+enum bt_component_factory_status _bt_component_factory_load(
+ struct bt_component_factory *factory, const char *path,
+ bool recursive)
{
enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
}
if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
- ret = bt_component_factory_load_dir_recursive(factory, path);
+ ret = bt_component_factory_load_dir(factory, path, recursive);
} else if (g_file_test(path, G_FILE_TEST_IS_REGULAR) ||
g_file_test(path, G_FILE_TEST_IS_SYMLINK)) {
ret = bt_component_factory_load_file(factory, path);
return ret;
}
+enum bt_component_factory_status bt_component_factory_load_recursive(
+ struct bt_component_factory *factory, const char *path)
+{
+ return _bt_component_factory_load(factory, path, true);
+}
+
+enum bt_component_factory_status bt_component_factory_load(
+ struct bt_component_factory *factory, const char *path)
+{
+ return _bt_component_factory_load(factory, path, false);
+}
+
static
enum bt_component_factory_status
add_component_class(struct bt_component_factory *factory, const char *name,
const char *description, bt_component_init_cb init,
enum bt_component_type type)
{
- struct bt_component_class *class;
+ struct bt_component_class *component_class;
enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
if (!factory || !name || !init) {
ret = BT_COMPONENT_FACTORY_STATUS_INVAL;
goto end;
}
+ assert(factory->current_plugin);
+
+ /*
+ * Ensure this component class does not clash with a currently
+ * registered class.
+ */
+ component_class = bt_component_factory_get_component_class(factory,
+ bt_plugin_get_name(factory->current_plugin), type, name);
+ if (component_class) {
+ struct bt_plugin *plugin = bt_component_class_get_plugin(
+ component_class);
+
+ printf_warning("Duplicate component class registration attempted. Component class %s being registered by plugin %s (path: %s) conflicts with one already registered by plugin %s (path: %s)",
+ name, bt_plugin_get_name(factory->current_plugin),
+ bt_plugin_get_path(factory->current_plugin),
+ bt_plugin_get_name(plugin),
+ bt_plugin_get_path(plugin));
+ ret = BT_COMPONENT_FACTORY_STATUS_DUPLICATE;
+ BT_PUT(component_class);
+ bt_put(plugin);
+ goto end;
+ }
- class = bt_component_class_create(type, name, description,
- factory->current_plugin);
- g_ptr_array_add(factory->component_classes, class);
+ component_class = bt_component_class_create(type, name, description,
+ init, factory->current_plugin);
+ g_ptr_array_add(factory->component_classes, component_class);
end:
return ret;
}