Sinks own their input iterators
[babeltrace.git] / lib / plugin-system / component-factory.c
index 65840d4cac79e883b6a025846d2405b099b3d9a2..3fb02057c4a042db71c7176a8022c2164234630c 100644 (file)
@@ -39,6 +39,7 @@
 #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)
@@ -106,7 +107,7 @@ bt_component_factory_load_file(struct bt_component_factory *factory,
 
        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;
        }
@@ -122,10 +123,10 @@ bt_component_factory_load_file(struct bt_component_factory *factory,
                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:
@@ -136,7 +137,6 @@ bt_component_factory_load_file(struct bt_component_factory *factory,
                        break;
                }
 
-               BT_PUT(plugin);
                goto end;
        }
 end:
@@ -145,8 +145,8 @@ 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;
@@ -211,9 +211,9 @@ bt_component_factory_load_dir_recursive(struct bt_component_factory *factory,
                        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;
                        }
@@ -318,6 +318,7 @@ struct bt_component_class *bt_component_factory_get_component_class(
                if (type != BT_COMPONENT_TYPE_UNKNOWN) {
                        if (type != bt_component_class_get_type(
                                        component_class)) {
+                               bt_put(plugin);
                                continue;
                        }
                }
@@ -328,6 +329,7 @@ struct bt_component_class *bt_component_factory_get_component_class(
 
                        assert(cur_plugin_name);
                        if (strcmp(plugin_name, cur_plugin_name)) {
+                               bt_put(plugin);
                                continue;
                        }
                }
@@ -338,10 +340,12 @@ struct bt_component_class *bt_component_factory_get_component_class(
 
                        assert(cur_cc_name);
                        if (strcmp(component_name, cur_cc_name)) {
+                               bt_put(plugin);
                                continue;
                        }
                }
 
+               bt_put(plugin);
                /* All criteria met. */
                goto match;
        }
@@ -352,8 +356,10 @@ 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;
 
@@ -368,7 +374,7 @@ enum bt_component_factory_status bt_component_factory_load(
        }
 
        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);
@@ -380,23 +386,57 @@ end:
        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;
 }
This page took 0.035543 seconds and 4 git commands to generate.