2 * SPDX-License-Identifier: MIT
4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
5 * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
8 #ifndef BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H
9 #define BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H
11 #include "common/macros.h"
12 #include "common/common.h"
13 #include "lib/graph/component-class.h"
14 #include <babeltrace2/plugin/plugin-loading.h>
15 #include <babeltrace2/plugin/plugin-dev.h>
16 #include "lib/object.h"
17 #include <babeltrace2/types.h>
18 #include "common/assert.h"
22 #include "plugin-so.h"
23 #include "lib/func-status.h"
25 /* Protection: this file uses BT_LIB_LOG*() macros directly */
26 #ifndef BT_LIB_LOG_SUPPORTED
27 # error Please include "lib/logging.h" before including this file.
31 BT_PLUGIN_TYPE_SO
= 0,
32 BT_PLUGIN_TYPE_PYTHON
= 1,
36 struct bt_object base
;
37 enum bt_plugin_type type
;
39 /* Arrays of `struct bt_component_class *` (owned by this) */
40 GPtrArray
*src_comp_classes
;
41 GPtrArray
*flt_comp_classes
;
42 GPtrArray
*sink_comp_classes
;
44 /* Info (owned by this) */
65 /* Value depends on the specific plugin type */
67 void (*destroy_spec_data
)(struct bt_plugin
*);
70 struct bt_plugin_set
{
71 struct bt_object base
;
73 /* Array of struct bt_plugin * */
78 const char *bt_plugin_type_string(enum bt_plugin_type type
)
81 case BT_PLUGIN_TYPE_SO
:
83 case BT_PLUGIN_TYPE_PYTHON
:
91 void bt_plugin_destroy(struct bt_object
*obj
)
93 struct bt_plugin
*plugin
;
96 plugin
= container_of(obj
, struct bt_plugin
, base
);
97 BT_LIB_LOGI("Destroying plugin object: %!+l", plugin
);
99 if (plugin
->destroy_spec_data
) {
100 plugin
->destroy_spec_data(plugin
);
103 if (plugin
->src_comp_classes
) {
104 BT_LOGD_STR("Putting source component classes.");
105 g_ptr_array_free(plugin
->src_comp_classes
, TRUE
);
106 plugin
->src_comp_classes
= NULL
;
109 if (plugin
->flt_comp_classes
) {
110 BT_LOGD_STR("Putting filter component classes.");
111 g_ptr_array_free(plugin
->flt_comp_classes
, TRUE
);
112 plugin
->flt_comp_classes
= NULL
;
115 if (plugin
->sink_comp_classes
) {
116 BT_LOGD_STR("Putting sink component classes.");
117 g_ptr_array_free(plugin
->sink_comp_classes
, TRUE
);
118 plugin
->sink_comp_classes
= NULL
;
121 if (plugin
->info
.name
) {
122 g_string_free(plugin
->info
.name
, TRUE
);
123 plugin
->info
.name
= NULL
;
126 if (plugin
->info
.path
) {
127 g_string_free(plugin
->info
.path
, TRUE
);
128 plugin
->info
.path
= NULL
;
131 if (plugin
->info
.description
) {
132 g_string_free(plugin
->info
.description
, TRUE
);
133 plugin
->info
.description
= NULL
;
136 if (plugin
->info
.author
) {
137 g_string_free(plugin
->info
.author
, TRUE
);
138 plugin
->info
.author
= NULL
;
141 if (plugin
->info
.license
) {
142 g_string_free(plugin
->info
.license
, TRUE
);
143 plugin
->info
.license
= NULL
;
146 if (plugin
->info
.version
.extra
) {
147 g_string_free(plugin
->info
.version
.extra
, TRUE
);
148 plugin
->info
.version
.extra
= NULL
;
155 struct bt_plugin
*bt_plugin_create_empty(enum bt_plugin_type type
)
157 struct bt_plugin
*plugin
= NULL
;
159 BT_LOGD("Creating empty plugin object: type=%s",
160 bt_plugin_type_string(type
));
162 plugin
= g_new0(struct bt_plugin
, 1);
164 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one plugin.");
168 bt_object_init_shared(&plugin
->base
, bt_plugin_destroy
);
171 /* Create empty arrays of component classes */
172 plugin
->src_comp_classes
=
173 g_ptr_array_new_with_free_func(
174 (GDestroyNotify
) bt_object_put_ref
);
175 if (!plugin
->src_comp_classes
) {
176 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
180 plugin
->flt_comp_classes
=
181 g_ptr_array_new_with_free_func(
182 (GDestroyNotify
) bt_object_put_ref
);
183 if (!plugin
->flt_comp_classes
) {
184 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
188 plugin
->sink_comp_classes
=
189 g_ptr_array_new_with_free_func(
190 (GDestroyNotify
) bt_object_put_ref
);
191 if (!plugin
->sink_comp_classes
) {
192 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
196 /* Create empty info */
197 plugin
->info
.name
= g_string_new(NULL
);
198 if (!plugin
->info
.name
) {
199 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
203 plugin
->info
.path
= g_string_new(NULL
);
204 if (!plugin
->info
.path
) {
205 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
209 plugin
->info
.description
= g_string_new(NULL
);
210 if (!plugin
->info
.description
) {
211 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
215 plugin
->info
.author
= g_string_new(NULL
);
216 if (!plugin
->info
.author
) {
217 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
221 plugin
->info
.license
= g_string_new(NULL
);
222 if (!plugin
->info
.license
) {
223 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
227 plugin
->info
.version
.extra
= g_string_new(NULL
);
228 if (!plugin
->info
.version
.extra
) {
229 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
233 BT_LIB_LOGD("Created empty plugin object: %!+l", plugin
);
237 BT_OBJECT_PUT_REF_AND_RESET(plugin
);
244 void bt_plugin_set_path(struct bt_plugin
*plugin
, const char *path
)
248 g_string_assign(plugin
->info
.path
, path
);
249 plugin
->info
.path_set
= BT_TRUE
;
250 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, path=\"%s\"",
255 void bt_plugin_set_name(struct bt_plugin
*plugin
, const char *name
)
259 g_string_assign(plugin
->info
.name
, name
);
260 plugin
->info
.name_set
= BT_TRUE
;
261 BT_LIB_LOGD("Set plugin's name: %![plugin-]+l, name=\"%s\"",
266 void bt_plugin_set_description(struct bt_plugin
*plugin
,
267 const char *description
)
270 BT_ASSERT(description
);
271 g_string_assign(plugin
->info
.description
, description
);
272 plugin
->info
.description_set
= BT_TRUE
;
273 BT_LIB_LOGD("Set plugin's description: %![plugin-]+l", plugin
);
277 void bt_plugin_set_author(struct bt_plugin
*plugin
, const char *author
)
281 g_string_assign(plugin
->info
.author
, author
);
282 plugin
->info
.author_set
= BT_TRUE
;
283 BT_LIB_LOGD("Set plugin's author: %![plugin-]+l, author=\"%s\"",
288 void bt_plugin_set_license(struct bt_plugin
*plugin
, const char *license
)
292 g_string_assign(plugin
->info
.license
, license
);
293 plugin
->info
.license_set
= BT_TRUE
;
294 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, license=\"%s\"",
299 void bt_plugin_set_version(struct bt_plugin
*plugin
, unsigned int major
,
300 unsigned int minor
, unsigned int patch
, const char *extra
)
303 plugin
->info
.version
.major
= major
;
304 plugin
->info
.version
.minor
= minor
;
305 plugin
->info
.version
.patch
= patch
;
308 g_string_assign(plugin
->info
.version
.extra
, extra
);
311 plugin
->info
.version_set
= BT_TRUE
;
312 BT_LIB_LOGD("Set plugin's version: %![plugin-]+l, "
313 "major=%u, minor=%u, patch=%u, extra=\"%s\"",
314 plugin
, major
, minor
, patch
, extra
);
318 int bt_plugin_add_component_class(
319 struct bt_plugin
*plugin
, struct bt_component_class
*comp_class
)
321 GPtrArray
*comp_classes
;
324 BT_ASSERT(comp_class
);
326 switch (comp_class
->type
) {
327 case BT_COMPONENT_CLASS_TYPE_SOURCE
:
328 comp_classes
= plugin
->src_comp_classes
;
330 case BT_COMPONENT_CLASS_TYPE_FILTER
:
331 comp_classes
= plugin
->flt_comp_classes
;
333 case BT_COMPONENT_CLASS_TYPE_SINK
:
334 comp_classes
= plugin
->sink_comp_classes
;
340 /* Set component class's original plugin name */
341 BT_ASSERT(comp_class
->plugin_name
);
342 BT_ASSERT(plugin
->info
.name
);
343 g_string_assign(comp_class
->plugin_name
, plugin
->info
.name
->str
);
345 /* Add new component class */
346 bt_object_get_ref(comp_class
);
347 g_ptr_array_add(comp_classes
, comp_class
);
349 /* Special case for a shared object plugin */
350 if (plugin
->type
== BT_PLUGIN_TYPE_SO
) {
351 bt_plugin_so_on_add_component_class(plugin
, comp_class
);
354 BT_LIB_LOGD("Added component class to plugin: "
355 "%![plugin-]+l, %![cc-]+C", plugin
, comp_class
);
356 return BT_FUNC_STATUS_OK
;
360 void bt_plugin_set_destroy(struct bt_object
*obj
)
362 struct bt_plugin_set
*plugin_set
=
363 container_of(obj
, struct bt_plugin_set
, base
);
369 BT_LOGD("Destroying plugin set: addr=%p", plugin_set
);
371 if (plugin_set
->plugins
) {
372 BT_LOGD_STR("Putting plugins.");
373 g_ptr_array_free(plugin_set
->plugins
, TRUE
);
380 struct bt_plugin_set
*bt_plugin_set_create(void)
382 struct bt_plugin_set
*plugin_set
= g_new0(struct bt_plugin_set
, 1);
388 BT_LOGD_STR("Creating empty plugin set.");
389 bt_object_init_shared(&plugin_set
->base
, bt_plugin_set_destroy
);
391 plugin_set
->plugins
= g_ptr_array_new_with_free_func(
392 (GDestroyNotify
) bt_object_put_ref
);
393 if (!plugin_set
->plugins
) {
394 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
395 BT_OBJECT_PUT_REF_AND_RESET(plugin_set
);
399 BT_LOGD("Created empty plugin set: addr=%p", plugin_set
);
406 bool bt_plugin_set_contains_plugin(struct bt_plugin_set
*plugin_set
,
410 bool contains
= false;
412 BT_ASSERT(plugin_set
);
415 for (i
= 0; i
< plugin_set
->plugins
->len
; i
++) {
416 const struct bt_plugin
*plugin
= plugin_set
->plugins
->pdata
[i
];
418 if (strcmp(plugin
->info
.name
->str
, name
) == 0) {
429 void bt_plugin_set_add_plugin(struct bt_plugin_set
*plugin_set
,
430 struct bt_plugin
*plugin
)
432 BT_ASSERT(plugin_set
);
435 if (bt_plugin_set_contains_plugin(plugin_set
,
436 plugin
->info
.name
->str
)) {
440 bt_object_get_ref(plugin
);
441 g_ptr_array_add(plugin_set
->plugins
, plugin
);
442 BT_LIB_LOGD("Added plugin to plugin set: "
443 "plugin-set-addr=%p, %![plugin-]+l",
450 #endif /* BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H */