X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fplugin%2Fplugin.c;h=9f0bc2ac22efdba4f4299e89690de6575b6224a1;hb=a12f3d624772f543137e60252101871cd6017a06;hp=31e78c3bacef87da9779e1184548949af095af43;hpb=8c1a31877fff7db51d0d852923e2c3ab90b50622;p=babeltrace.git diff --git a/lib/plugin/plugin.c b/lib/plugin/plugin.c index 31e78c3b..9f0bc2ac 100644 --- a/lib/plugin/plugin.c +++ b/lib/plugin/plugin.c @@ -1,10 +1,6 @@ /* - * plugin.c - * - * Babeltrace Plugin (generic) - * + * Copyright 2017-2018 Philippe Proulx * Copyright 2016 Jérémie Galarneau - * Copyright 2017 Philippe Proulx * * Author: Jérémie Galarneau * @@ -30,13 +26,15 @@ #define BT_LOG_TAG "PLUGIN" #include +#include +#include #include #include -#include #include #include #include -#include +#include +#include #include #include #include @@ -45,31 +43,41 @@ #include #include #include -#include +#include +#include -#define PYTHON_PLUGIN_PROVIDER_FILENAME "libbabeltrace-python-plugin-provider." G_MODULE_SUFFIX +#define PYTHON_PLUGIN_PROVIDER_FILENAME "libbabeltrace2-python-plugin-provider." G_MODULE_SUFFIX #define PYTHON_PLUGIN_PROVIDER_SYM_NAME bt_plugin_python_create_all_from_file #define PYTHON_PLUGIN_PROVIDER_SYM_NAME_STR TOSTRING(PYTHON_PLUGIN_PROVIDER_SYM_NAME) +#define APPEND_ALL_FROM_DIR_NFDOPEN_MAX 8 + #ifdef BT_BUILT_IN_PYTHON_PLUGIN_SUPPORT #include + static struct bt_plugin_set *(*bt_plugin_python_create_all_from_file_sym)(const char *path) = bt_plugin_python_create_all_from_file; + +static +void init_python_plugin_provider(void) {} #else /* BT_BUILT_IN_PYTHON_PLUGIN_SUPPORT */ static GModule *python_plugin_provider_module; static struct bt_plugin_set *(*bt_plugin_python_create_all_from_file_sym)(const char *path); -__attribute__((constructor)) static +static void init_python_plugin_provider(void) { + if (bt_plugin_python_create_all_from_file_sym != NULL) { + return; + } + BT_LOGD_STR("Loading Python plugin provider module."); python_plugin_provider_module = - g_module_open(PYTHON_PLUGIN_PROVIDER_FILENAME, - G_MODULE_BIND_LOCAL); + g_module_open(PYTHON_PLUGIN_PROVIDER_FILENAME, 0); if (!python_plugin_provider_module) { - BT_LOGI("Cannot find `%s`: continuing without Python plugin support.", - PYTHON_PLUGIN_PROVIDER_FILENAME); + BT_LOGI("Cannot open `%s`: %s: continuing without Python plugin support.", + PYTHON_PLUGIN_PROVIDER_FILENAME, g_module_error()); return; } @@ -83,7 +91,7 @@ void init_python_plugin_provider(void) { return; } - BT_LOGD("Loaded Python plugin provider module: addr=%p", + BT_LOGI("Loaded Python plugin provider module: addr=%p", python_plugin_provider_module); } @@ -102,61 +110,31 @@ void fini_python_plugin_provider(void) { } #endif -extern -int64_t bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set) +uint64_t bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set) { - int64_t count = -1; - - if (!plugin_set) { - BT_LOGW_STR("Invalid parameter: plugin set is NULL."); - goto end; - } - - count = (int64_t) plugin_set->plugins->len; - -end: - return count; + BT_ASSERT_PRE_NON_NULL(plugin_set, "Plugin set"); + return (uint64_t) plugin_set->plugins->len; } -extern -struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set, - uint64_t index) +const struct bt_plugin *bt_plugin_set_borrow_plugin_by_index_const( + const struct bt_plugin_set *plugin_set, uint64_t index) { - struct bt_plugin *plugin = NULL; - - if (!plugin_set) { - BT_LOGW_STR("Invalid parameter: plugin set is NULL."); - goto end; - } - - if (index >= plugin_set->plugins->len) { - BT_LOGW("Invalid parameter: index is out of bounds: " - "addr=%p, index=%" PRIu64 ", count=%u", - plugin_set, index, plugin_set->plugins->len); - goto end; - } - - plugin = bt_get(g_ptr_array_index(plugin_set->plugins, index)); - -end: - return plugin; + BT_ASSERT_PRE_NON_NULL(plugin_set, "Plugin set"); + BT_ASSERT_PRE_VALID_INDEX(index, plugin_set->plugins->len); + return g_ptr_array_index(plugin_set->plugins, index); } -struct bt_plugin_set *bt_plugin_create_all_from_static(void) +const struct bt_plugin_set *bt_plugin_find_all_from_static(void) { /* bt_plugin_so_create_all_from_static() logs errors */ return bt_plugin_so_create_all_from_static(); } -struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path) +const struct bt_plugin_set *bt_plugin_find_all_from_file(const char *path) { struct bt_plugin_set *plugin_set = NULL; - if (!path) { - BT_LOGW_STR("Invalid parameter: path is NULL."); - goto end; - } - + BT_ASSERT_PRE_NON_NULL(path, "Path"); BT_LOGD("Creating plugins from file: path=\"%s\"", path); /* Try shared object plugins */ @@ -166,6 +144,7 @@ struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path) } /* Try Python plugins if support is available */ + init_python_plugin_provider(); if (bt_plugin_python_create_all_from_file_sym) { plugin_set = bt_plugin_python_create_all_from_file_sym(path); if (plugin_set) { @@ -191,22 +170,18 @@ static void destroy_gstring(void *data) g_string_free(data, TRUE); } -struct bt_plugin *bt_plugin_find(const char *plugin_name) +const 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_set *plugin_set = NULL; + const struct bt_plugin *plugin = NULL; + const struct bt_plugin_set *plugin_set = NULL; GPtrArray *dirs = NULL; int ret; size_t i, j; - if (!plugin_name) { - BT_LOGW_STR("Invalid parameter: plugin name is NULL."); - goto end; - } - + BT_ASSERT_PRE_NON_NULL(plugin_name, "Name"); BT_LOGD("Finding named plugin in standard directories and built-in plugins: " "name=\"%s\"", plugin_name); dirs = g_ptr_array_new_with_free_func((GDestroyNotify) destroy_gstring); @@ -267,10 +242,20 @@ struct bt_plugin *bt_plugin_find(const char *plugin_name) for (i = 0; i < dirs->len; i++) { GString *dir = g_ptr_array_index(dirs, i); - BT_PUT(plugin_set); + BT_OBJECT_PUT_REF_AND_RESET(plugin_set); + + /* + * Skip this if the directory does not exist because + * bt_plugin_find_all_from_dir() would log a warning. + */ + if (!g_file_test(dir->str, G_FILE_TEST_IS_DIR)) { + BT_LOGV("Skipping nonexistent directory path: " + "path=\"%s\"", dir->str); + continue; + } - /* bt_plugin_create_all_from_dir() logs details/errors */ - plugin_set = bt_plugin_create_all_from_dir(dir->str, BT_FALSE); + /* bt_plugin_find_all_from_dir() logs details/errors */ + plugin_set = bt_plugin_find_all_from_dir(dir->str, BT_FALSE); if (!plugin_set) { BT_LOGD("No plugins found in directory: path=\"%s\"", dir->str); @@ -278,14 +263,15 @@ struct bt_plugin *bt_plugin_find(const char *plugin_name) } for (j = 0; j < plugin_set->plugins->len; j++) { - struct bt_plugin *candidate_plugin = + const struct bt_plugin *candidate_plugin = g_ptr_array_index(plugin_set->plugins, j); if (strcmp(bt_plugin_get_name(candidate_plugin), plugin_name) == 0) { BT_LOGD("Plugin found in directory: name=\"%s\", path=\"%s\"", plugin_name, dir->str); - plugin = bt_get(candidate_plugin); + plugin = candidate_plugin; + bt_object_get_no_null_check(plugin); goto end; } } @@ -294,18 +280,19 @@ struct bt_plugin *bt_plugin_find(const char *plugin_name) plugin_name, dir->str); } - bt_put(plugin_set); - plugin_set = bt_plugin_create_all_from_static(); + bt_object_put_ref(plugin_set); + plugin_set = bt_plugin_find_all_from_static(); if (plugin_set) { for (j = 0; j < plugin_set->plugins->len; j++) { - struct bt_plugin *candidate_plugin = + const struct bt_plugin *candidate_plugin = g_ptr_array_index(plugin_set->plugins, j); if (strcmp(bt_plugin_get_name(candidate_plugin), plugin_name) == 0) { BT_LOGD("Plugin found in built-in plugins: " "name=\"%s\"", plugin_name); - plugin = bt_get(candidate_plugin); + plugin = candidate_plugin; + bt_object_get_no_null_check(plugin); goto end; } } @@ -313,16 +300,15 @@ struct bt_plugin *bt_plugin_find(const char *plugin_name) end: free(home_plugin_dir); - bt_put(plugin_set); + bt_object_put_ref(plugin_set); if (dirs) { g_ptr_array_free(dirs, TRUE); } if (plugin) { - BT_LOGD("Found plugin in standard directories and built-in plugins: " - "addr=%p, name=\"%s\", path=\"%s\"", - plugin, plugin_name, bt_plugin_get_path(plugin)); + BT_LIB_LOGD("Found plugin in standard directories and built-in plugins: " + "%!+l", plugin); } else { BT_LOGD("No plugin found in standard directories and built-in plugins: " "name=\"%s\"", plugin_name); @@ -331,60 +317,70 @@ end: return plugin; } -struct bt_component_class *bt_plugin_find_component_class( - const char *plugin_name, const char *comp_cls_name, - enum bt_component_class_type comp_cls_type) +static struct { + pthread_mutex_t lock; + struct bt_plugin_set *plugin_set; + bool recurse; +} append_all_from_dir_info = { + .lock = PTHREAD_MUTEX_INITIALIZER +}; + +static +int nftw_append_all_from_dir(const char *file, const struct stat *sb, int flag, + struct FTW *s) { - struct bt_plugin *plugin = NULL; - struct bt_component_class *comp_cls = NULL; + int ret = 0; + const char *name = file + s->base; - if (!plugin_name) { - BT_LOGW_STR("Invalid parameter: plugin name is NULL."); + /* Check for recursion */ + if (!append_all_from_dir_info.recurse && s->level > 1) { goto end; } - if (!comp_cls_name) { - BT_LOGW_STR("Invalid parameter: component class name is NULL."); - goto end; - } + switch (flag) { + case FTW_F: + { + const struct bt_plugin_set *plugins_from_file; - BT_LOGD("Finding named plugin and component class in standard directories and built-in plugins: " - "plugin-name=\"%s\", comp-class-name=\"%s\"", - plugin_name, comp_cls_name); - plugin = bt_plugin_find(plugin_name); - if (!plugin) { - BT_LOGD_STR("Plugin not found."); - goto end; - } + if (name[0] == '.') { + /* Skip hidden files */ + BT_LOGV("Skipping hidden file: path=\"%s\"", file); + goto end; + } - comp_cls = bt_plugin_get_component_class_by_name_and_type( - plugin, comp_cls_name, comp_cls_type); - if (!comp_cls) { - BT_LOGD("Component class not found in plugin: " - "plugin-addr=%p, plugin-path=\"%s\"", - plugin, bt_plugin_get_path(plugin)); - } + plugins_from_file = bt_plugin_find_all_from_file(file); -end: - bt_put(plugin); - return comp_cls; -} + if (plugins_from_file) { + size_t j; -/* Allocate dirent as recommended by READDIR(3), NOTES on readdir_r */ -static -struct dirent *alloc_dirent(const char *path) -{ - size_t len; - long name_max; - struct dirent *entry; + for (j = 0; j < plugins_from_file->plugins->len; j++) { + struct bt_plugin *plugin = + g_ptr_array_index(plugins_from_file->plugins, j); + + BT_LIB_LOGD("Adding plugin to plugin set: " + "plugin-path=\"%s\", %![plugin-]+l", + file, plugin); + bt_plugin_set_add_plugin( + append_all_from_dir_info.plugin_set, + plugin); + } - name_max = pathconf(path, _PC_NAME_MAX); - if (name_max == -1) { - name_max = PATH_MAX; + bt_object_put_ref(plugins_from_file); + } + break; + } + case FTW_DNR: + /* Continue to next file / directory. */ + BT_LOGW("Cannot enter directory: continuing: path=\"%s\"", file); + break; + case FTW_NS: + /* Continue to next file / directory. */ + BT_LOGD("Cannot get file information: continuing: path=\"%s\"", file); + break; } - len = offsetof(struct dirent, d_name) + name_max + 1; - entry = zmalloc(len); - return entry; + +end: + return ret; } static @@ -392,152 +388,27 @@ enum bt_plugin_status bt_plugin_create_append_all_from_dir( struct bt_plugin_set *plugin_set, const char *path, bt_bool recurse) { - DIR *directory = NULL; - struct dirent *entry = NULL, *result = NULL; - char *file_path = NULL; - size_t path_len; + int nftw_flags = FTW_PHYS; enum bt_plugin_status ret = BT_PLUGIN_STATUS_OK; - if (!path) { - BT_LOGW_STR("Invalid parameter: path is NULL."); - ret = BT_PLUGIN_STATUS_ERROR; - goto end; - } - - path_len = strlen(path); - if (path_len >= PATH_MAX) { - BT_LOGW("Invalid parameter: path length is too large: " - "path-length=%zu", path_len); - ret = BT_PLUGIN_STATUS_ERROR; - goto end; - } - - entry = alloc_dirent(path); - if (!entry) { - BT_LOGE_STR("Failed to allocate a directory entry."); - ret = BT_PLUGIN_STATUS_ERROR; - goto end; - } - - file_path = zmalloc(PATH_MAX); - if (!file_path) { - BT_LOGE("Failed to allocate %zu bytes.", (size_t) PATH_MAX); - ret = BT_PLUGIN_STATUS_NOMEM; - goto end; - } - - strncpy(file_path, path, path_len); - /* Append a trailing '/' to the path */ - if (file_path[path_len - 1] != '/') { - file_path[path_len++] = '/'; - } - - directory = opendir(file_path); - if (!directory) { - if (errno == EACCES) { - BT_LOGD("Cannot open directory: %s: continuing: " - "path=\"%s\", errno=%d", - strerror(errno), file_path, errno); - goto end; - } - - BT_LOGE("Cannot open directory: %s: " - "path=\"%s\", errno=%d", - strerror(errno), file_path, errno); + BT_ASSERT(plugin_set); + BT_ASSERT(path); + BT_ASSERT(strlen(path) < PATH_MAX); + pthread_mutex_lock(&append_all_from_dir_info.lock); + append_all_from_dir_info.plugin_set = plugin_set; + append_all_from_dir_info.recurse = recurse; + ret = nftw(path, nftw_append_all_from_dir, + APPEND_ALL_FROM_DIR_NFDOPEN_MAX, nftw_flags); + pthread_mutex_unlock(&append_all_from_dir_info.lock); + if (ret != 0) { + BT_LOGW_ERRNO("Cannot open directory", ": path=\"%s\"", path); ret = BT_PLUGIN_STATUS_ERROR; - goto end; - } - - /* Recursively walk directory */ - while (!readdir_r(directory, entry, &result) && result) { - struct stat st; - int stat_ret; - size_t file_name_len; - - if (strcmp(result->d_name, ".") == 0 || - strcmp(result->d_name, "..") == 0) { - continue; - } - - if (result->d_name[0] == '.') { - /* Skip hidden files, . and .. */ - BT_LOGV("Skipping hidden file: path=\"%s/%s\"", - path, result->d_name); - continue; - } - - file_name_len = strlen(result->d_name); - - if (path_len + file_name_len >= PATH_MAX) { - BT_LOGD("Skipping file because its path length is too large: continuing: " - "path=\"%s/%s\", length=%zu", - path, result->d_name, - (size_t) (path_len + file_name_len)); - continue; - } - - strncpy(file_path + path_len, result->d_name, file_name_len); - file_path[path_len + file_name_len] = '\0'; - stat_ret = stat(file_path, &st); - if (stat_ret < 0) { - /* Continue to next file / directory. */ - BT_LOGD("Cannot get file information: %s: continuing: " - "path=\"%s\", errno=%d", - strerror(errno), file_path, errno); - continue; - } - - if (S_ISDIR(st.st_mode) && recurse) { - ret = bt_plugin_create_append_all_from_dir(plugin_set, - file_path, BT_TRUE); - if (ret < 0) { - BT_LOGW("Cannot recurse into directory to find plugins: " - "path=\"%s\", ret=%d", file_path, ret); - goto end; - } - } else if (S_ISREG(st.st_mode)) { - struct bt_plugin_set *plugins_from_file = - bt_plugin_create_all_from_file(file_path); - - if (plugins_from_file) { - 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); - - BT_LOGD("Adding plugin to plugin set: " - "plugin-path=\"%s\", plugin-addr=%p, plugin-name=\"%s\"", - file_path, plugin, - bt_plugin_get_name(plugin)); - bt_plugin_set_add_plugin(plugin_set, - plugin); - } - - bt_put(plugins_from_file); - } - } } -end: - if (directory) { - if (closedir(directory)) { - /* - * We don't want to override the error since there is - * nothing could do. - */ - BT_LOGE("Cannot close directory entry: %s: " - "path=\"%s\", errno=%d", - strerror(errno), path, errno); - } - } - - free(entry); - free(file_path); return ret; } -struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path, +const struct bt_plugin_set *bt_plugin_find_all_from_dir(const char *path, bt_bool recurse) { struct bt_plugin_set *plugin_set; @@ -556,7 +427,8 @@ struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path, recurse); if (status < 0) { BT_LOGW("Cannot append plugins found in directory: " - "status=%s", bt_plugin_status_string(status)); + "path=\"%s\", status=%s", + path, bt_plugin_status_string(status)); goto error; } @@ -565,112 +437,55 @@ struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path, goto end; error: - BT_PUT(plugin_set); + BT_OBJECT_PUT_REF_AND_RESET(plugin_set); end: return plugin_set; } -const char *bt_plugin_get_name(struct bt_plugin *plugin) +const char *bt_plugin_get_name(const struct bt_plugin *plugin) { - const char *val = NULL; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto end; - } - - if (plugin->info.name_set) { - val = plugin->info.name->str; - } - -end: - return val; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return plugin->info.name_set ? plugin->info.name->str : NULL; } -const char *bt_plugin_get_author(struct bt_plugin *plugin) +const char *bt_plugin_get_author(const struct bt_plugin *plugin) { - const char *val = NULL; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto end; - } - - if (plugin->info.author_set) { - val = plugin->info.author->str; - } - -end: - return val; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return plugin->info.author_set ? plugin->info.author->str : NULL; } -const char *bt_plugin_get_license(struct bt_plugin *plugin) +const char *bt_plugin_get_license(const struct bt_plugin *plugin) { - const char *val = NULL; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto end; - } - - if (plugin->info.license_set) { - val = plugin->info.license->str; - } - -end: - return val; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return plugin->info.license_set ? plugin->info.license->str : NULL; } -const char *bt_plugin_get_path(struct bt_plugin *plugin) +const char *bt_plugin_get_path(const struct bt_plugin *plugin) { - const char *val = NULL; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto end; - } - - if (plugin->info.path_set) { - val = plugin->info.path->str; - } - -end: - return val; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return plugin->info.path_set ? plugin->info.path->str : NULL; } -const char *bt_plugin_get_description(struct bt_plugin *plugin) +const char *bt_plugin_get_description(const struct bt_plugin *plugin) { - const char *val = NULL; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto end; - } - - if (plugin->info.description_set) { - val = plugin->info.description->str; - } - -end: - return val; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return plugin->info.description_set ? + plugin->info.description->str : NULL; } -enum bt_plugin_status bt_plugin_get_version(struct bt_plugin *plugin, +enum bt_property_availability bt_plugin_get_version(const struct bt_plugin *plugin, unsigned int *major, unsigned int *minor, unsigned int *patch, const char **extra) { - enum bt_plugin_status status = BT_PLUGIN_STATUS_OK; + enum bt_property_availability avail = + BT_PROPERTY_AVAILABILITY_AVAILABLE; - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - status = BT_PLUGIN_STATUS_ERROR; - goto end; - } + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); if (!plugin->info.version_set) { - BT_LOGV("Plugin's version is not set: addr=%p", plugin); - status = BT_PLUGIN_STATUS_ERROR; + BT_LIB_LOGV("Plugin's version is not set: %!+l", plugin); + avail = BT_PROPERTY_AVAILABILITY_NOT_AVAILABLE; goto end; } @@ -691,156 +506,129 @@ enum bt_plugin_status bt_plugin_get_version(struct bt_plugin *plugin, } end: - return status; + return avail; } -int64_t bt_plugin_get_component_class_count(struct bt_plugin *plugin) +uint64_t bt_plugin_get_source_component_class_count(const struct bt_plugin *plugin) { - return plugin ? plugin->comp_classes->len : (int64_t) -1; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return (uint64_t) plugin->src_comp_classes->len; } -struct bt_component_class *bt_plugin_get_component_class_by_index( - struct bt_plugin *plugin, uint64_t index) +uint64_t bt_plugin_get_filter_component_class_count(const struct bt_plugin *plugin) { - struct bt_component_class *comp_class = NULL; + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return (uint64_t) plugin->flt_comp_classes->len; +} - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto error; - } +uint64_t bt_plugin_get_sink_component_class_count(const struct bt_plugin *plugin) +{ + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + return (uint64_t) plugin->sink_comp_classes->len; +} - if (index >= plugin->comp_classes->len) { - BT_LOGW("Invalid parameter: index is out of bounds: " - "addr=%p, index=%" PRIu64 ", count=%u", - plugin, index, plugin->comp_classes->len); - goto error; - } +static inline +struct bt_component_class *borrow_component_class_by_index( + const struct bt_plugin *plugin, GPtrArray *comp_classes, + uint64_t index) +{ + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + BT_ASSERT_PRE_VALID_INDEX(index, comp_classes->len); + return g_ptr_array_index(comp_classes, index); +} - comp_class = g_ptr_array_index(plugin->comp_classes, index); - bt_get(comp_class); - goto end; +const struct bt_component_class_source * +bt_plugin_borrow_source_component_class_by_index_const( + const struct bt_plugin *plugin, uint64_t index) +{ + return (const void *) borrow_component_class_by_index(plugin, + plugin->src_comp_classes, index); +} -error: - BT_PUT(comp_class); +const struct bt_component_class_filter * +bt_plugin_borrow_filter_component_class_by_index_const( + const struct bt_plugin *plugin, uint64_t index) +{ + return (const void *) borrow_component_class_by_index(plugin, + plugin->flt_comp_classes, index); +} -end: - return comp_class; +const struct bt_component_class_sink * +bt_plugin_borrow_sink_component_class_by_index_const( + const struct bt_plugin *plugin, uint64_t index) +{ + return (const void *) borrow_component_class_by_index(plugin, + plugin->sink_comp_classes, index); } -struct bt_component_class *bt_plugin_get_component_class_by_name_and_type( - struct bt_plugin *plugin, const char *name, - enum bt_component_class_type type) +static inline +struct bt_component_class *borrow_component_class_by_name( + const struct bt_plugin *plugin, GPtrArray *comp_classes, + const char *name) { struct bt_component_class *comp_class = NULL; size_t i; - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto error; - } + BT_ASSERT_PRE_NON_NULL(plugin, "Plugin"); + BT_ASSERT_PRE_NON_NULL(name, "Name"); - if (!name) { - BT_LOGW_STR("Invalid parameter: name is NULL."); - goto error; - } - - for (i = 0; i < plugin->comp_classes->len; i++) { + for (i = 0; i < comp_classes->len; i++) { struct bt_component_class *comp_class_candidate = - g_ptr_array_index(plugin->comp_classes, i); + g_ptr_array_index(comp_classes, i); const char *comp_class_cand_name = bt_component_class_get_name(comp_class_candidate); - enum bt_component_class_type comp_class_cand_type = - bt_component_class_get_type(comp_class_candidate); - assert(comp_class_cand_name); - assert(comp_class_cand_type >= 0); + BT_ASSERT(comp_class_cand_name); - if (strcmp(name, comp_class_cand_name) == 0 && - comp_class_cand_type == type) { - comp_class = bt_get(comp_class_candidate); + if (strcmp(name, comp_class_cand_name) == 0) { + comp_class = comp_class_candidate; break; } } - goto end; - -error: - BT_PUT(comp_class); - -end: return comp_class; } -enum bt_plugin_status bt_plugin_add_component_class( - struct bt_plugin *plugin, struct bt_component_class *comp_class) +const struct bt_component_class_source * +bt_plugin_borrow_source_component_class_by_name_const( + const struct bt_plugin *plugin, const char *name) { - enum bt_plugin_status status = BT_PLUGIN_STATUS_OK; - struct bt_component_class *comp_class_dup = NULL; - int comp_class_index = -1; - - if (!plugin) { - BT_LOGW_STR("Invalid parameter: plugin is NULL."); - goto error; - } - - if (!comp_class) { - BT_LOGW_STR("Invalid parameter: component class is NULL."); - goto error; - } - - if (plugin->frozen) { - BT_LOGW("Invalid parameter: plugin is frozen: " - "addr=%p, name=\"%s\"", plugin, - bt_plugin_get_name(plugin)); - goto error; - } - - /* Check for duplicate */ - comp_class_dup = bt_plugin_get_component_class_by_name_and_type(plugin, - bt_component_class_get_name(comp_class), - bt_component_class_get_type(comp_class)); - if (comp_class_dup) { - BT_LOGW("Invalid parameter: a component class with this name and type already exists in the plugin: " - "plugin-addr=%p, plugin-name=\"%s\", plugin-path=\"%s\", " - "comp-class-name=\"%s\", comp-class-type=%s", - plugin, bt_plugin_get_name(plugin), - bt_plugin_get_path(plugin), - bt_component_class_get_name(comp_class), - bt_component_class_type_string( - bt_component_class_get_type(comp_class))); - goto error; - } + return (const void *) borrow_component_class_by_name(plugin, + plugin->src_comp_classes, name); +} - /* Add new component class */ - comp_class_index = plugin->comp_classes->len; - g_ptr_array_add(plugin->comp_classes, bt_get(comp_class)); +const struct bt_component_class_filter * +bt_plugin_borrow_filter_component_class_by_name_const( + const struct bt_plugin *plugin, const char *name) +{ + return (const void *) borrow_component_class_by_name(plugin, + plugin->flt_comp_classes, name); +} - /* Special case for a shared object plugin */ - if (plugin->type == BT_PLUGIN_TYPE_SO) { - bt_plugin_so_on_add_component_class(plugin, comp_class); - } +const struct bt_component_class_sink * +bt_plugin_borrow_sink_component_class_by_name_const( + const struct bt_plugin *plugin, const char *name) +{ + return (const void *) borrow_component_class_by_name(plugin, + plugin->sink_comp_classes, name); +} - BT_LOGD("Added component class to plugin: " - "plugin-addr=%p, plugin-name=\"%s\", plugin-path=\"%s\", " - "comp-class-addr=%p, comp-class-name=\"%s\", comp-class-type=%s", - plugin, bt_plugin_get_name(plugin), - bt_plugin_get_path(plugin), - comp_class, - bt_component_class_get_name(comp_class), - bt_component_class_type_string( - bt_component_class_get_type(comp_class))); - goto end; +void bt_plugin_get_ref(const struct bt_plugin *plugin) +{ + bt_object_get_ref(plugin); +} -error: - /* Remove entry from plugin's component classes (if added) */ - if (comp_class_index >= 0) { - g_ptr_array_remove_index(plugin->comp_classes, - comp_class_index); - } +void bt_plugin_put_ref(const struct bt_plugin *plugin) +{ + bt_object_put_ref(plugin); +} - status = BT_PLUGIN_STATUS_ERROR; +void bt_plugin_set_get_ref(const struct bt_plugin_set *plugin_set) +{ + bt_object_get_ref(plugin_set); +} -end: - bt_put(comp_class_dup); - return status; +void bt_plugin_set_put_ref(const struct bt_plugin_set *plugin_set) +{ + bt_object_put_ref(plugin_set); }