Add support for statically-built plug-ins
[babeltrace.git] / lib / plugin-system / component-factory.c
index 6601a0a619c00b736533379d3b33c4cbcba6a90a..471b4b877a26b350ce261c83a8a1f345e40019f9 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)
@@ -47,6 +48,8 @@
 #define PLUGIN_SUFFIX_LEN max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \
                sizeof(LIBTOOL_PLUGIN_SUFFIX))
 
+DECLARE_PLUG_IN_SECTIONS;
+
 /* Allocate dirent as recommended by READDIR(3), NOTES on readdir_r */
 static
 struct dirent *alloc_dirent(const char *path)
@@ -64,13 +67,36 @@ struct dirent *alloc_dirent(const char *path)
        return entry;
 }
 
+static
+enum bt_component_factory_status init_plugin(
+               struct bt_component_factory *factory, struct bt_plugin *plugin)
+{
+       enum bt_component_status component_status;
+       enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
+
+       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:
+                       ret = BT_COMPONENT_FACTORY_STATUS_NOMEM;
+                       break;
+               default:
+                       ret = BT_COMPONENT_FACTORY_STATUS_ERROR;
+                       break;
+               }
+       }
+       return ret;
+}
+
 static
 enum bt_component_factory_status
 bt_component_factory_load_file(struct bt_component_factory *factory,
                const char *path)
 {
        enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
-       enum bt_component_status component_status;
        size_t path_len;
        GModule *module;
        struct bt_plugin *plugin;
@@ -106,39 +132,22 @@ 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;
        }
 
-       /* Load plugin and make sure it defines the required entry points */
-       plugin = bt_plugin_create(module, path);
+       /* Load plugin and make sure it defines the required entry points. */
+       plugin = bt_plugin_create_from_module(module, path);
        if (!plugin) {
                ret = BT_COMPONENT_FACTORY_STATUS_INVAL_PLUGIN;
                if (!g_module_close(module)) {
-                       printf_error("Module close error: %s",
+                       printf_error("Module close error: %s\n",
                                g_module_error());
                }
                goto end;
        }
-
-       factory->current_plugin = plugin;
-       component_status = bt_plugin_register_component_classes(plugin,
-                       factory);
-       factory->current_plugin = NULL;
-       if (component_status != BT_COMPONENT_STATUS_OK) {
-               switch (component_status) {
-               case BT_COMPONENT_STATUS_NOMEM:
-                       ret = BT_COMPONENT_FACTORY_STATUS_NOMEM;
-                       break;
-               default:
-                       ret = BT_COMPONENT_FACTORY_STATUS_ERROR;
-                       break;
-               }
-
-               BT_PUT(plugin);
-               goto end;
-       }
+       ret = init_plugin(factory, plugin);
 end:
        return ret;
 }
@@ -318,6 +327,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 +338,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 +349,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;
        }
@@ -394,6 +407,39 @@ enum bt_component_factory_status bt_component_factory_load(
        return _bt_component_factory_load(factory, path, false);
 }
 
+enum bt_component_factory_status bt_component_factory_load_static(
+               struct bt_component_factory *factory)
+{
+       size_t count, i;
+       enum bt_component_factory_status ret = BT_COMPONENT_FACTORY_STATUS_OK;
+
+       PRINT_PLUG_IN_SECTIONS(printf_verbose);
+
+       count = SECTION_ELEMENT_COUNT(__plugin_register_funcs);
+       if (SECTION_ELEMENT_COUNT(__plugin_register_funcs) != count ||
+                       SECTION_ELEMENT_COUNT(__plugin_names) != count ||
+                       SECTION_ELEMENT_COUNT(__plugin_authors) != count ||
+                       SECTION_ELEMENT_COUNT(__plugin_licenses) != count ||
+                       SECTION_ELEMENT_COUNT(__plugin_descriptions) != count) {
+               printf_error("Some statically-linked plug-ins do not define all mandatory symbols\n");
+               ret = BT_COMPONENT_FACTORY_STATUS_INVAL_PLUGIN;
+               goto end;
+       }
+       printf_verbose("Detected %zu statically-linked plug-ins\n", count);
+
+       for (i = 0; i < count; i++) {
+               struct bt_plugin *plugin = bt_plugin_create_from_static(i);
+
+               if (!plugin) {
+                       continue;
+               }
+
+               (void) init_plugin(factory, plugin);
+       }
+end:
+       return ret;
+}
+
 static
 enum bt_component_factory_status
 add_component_class(struct bt_component_factory *factory, const char *name,
@@ -431,7 +477,7 @@ add_component_class(struct bt_component_factory *factory, const char *name,
        }
 
        component_class = bt_component_class_create(type, name, description,
-               init, factory->current_plugin);
+                       init, factory->current_plugin);
        g_ptr_array_add(factory->component_classes, component_class);
 end:
        return ret;
@@ -454,3 +500,12 @@ bt_component_factory_register_sink_component_class(
        return add_component_class(factory, name, description, init,
                        BT_COMPONENT_TYPE_SINK);
 }
+
+enum bt_component_factory_status
+bt_component_factory_register_filter_component_class(
+               struct bt_component_factory *factory, const char *name,
+               const char *description, bt_component_init_cb init)
+{
+       return add_component_class(factory, name, description, init,
+                       BT_COMPONENT_TYPE_FILTER);
+}
This page took 0.026657 seconds and 4 git commands to generate.