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/common.h"
12 #include "lib/graph/component-class.h"
13 #include <babeltrace2/plugin/plugin-loading.h>
14 #include <babeltrace2/plugin/plugin-dev.h>
15 #include "lib/object.h"
16 #include <babeltrace2/types.h>
17 #include "common/assert.h"
21 #include "plugin-so.h"
22 #include "lib/func-status.h"
24 /* Protection: this file uses BT_LIB_LOG*() macros directly */
25 #ifndef BT_LIB_LOG_SUPPORTED
26 # error Please include "lib/logging.h" before including this file.
30 BT_PLUGIN_TYPE_SO
= 0,
31 BT_PLUGIN_TYPE_PYTHON
= 1,
35 struct bt_object base
;
36 enum bt_plugin_type type
;
38 /* Arrays of `struct bt_component_class *` (owned by this) */
39 GPtrArray
*src_comp_classes
;
40 GPtrArray
*flt_comp_classes
;
41 GPtrArray
*sink_comp_classes
;
43 /* Info (owned by this) */
64 /* Value depends on the specific plugin type */
66 void (*destroy_spec_data
)(struct bt_plugin
*);
69 struct bt_plugin_set
{
70 struct bt_object base
;
72 /* Array of struct bt_plugin * */
77 const char *bt_plugin_type_string(enum bt_plugin_type type
)
80 case BT_PLUGIN_TYPE_SO
:
82 case BT_PLUGIN_TYPE_PYTHON
:
90 void bt_plugin_destroy(struct bt_object
*obj
)
92 struct bt_plugin
*plugin
;
95 plugin
= container_of(obj
, struct bt_plugin
, base
);
96 BT_LIB_LOGI("Destroying plugin object: %!+l", plugin
);
98 if (plugin
->destroy_spec_data
) {
99 plugin
->destroy_spec_data(plugin
);
102 if (plugin
->src_comp_classes
) {
103 BT_LOGD_STR("Putting source component classes.");
104 g_ptr_array_free(plugin
->src_comp_classes
, TRUE
);
105 plugin
->src_comp_classes
= NULL
;
108 if (plugin
->flt_comp_classes
) {
109 BT_LOGD_STR("Putting filter component classes.");
110 g_ptr_array_free(plugin
->flt_comp_classes
, TRUE
);
111 plugin
->flt_comp_classes
= NULL
;
114 if (plugin
->sink_comp_classes
) {
115 BT_LOGD_STR("Putting sink component classes.");
116 g_ptr_array_free(plugin
->sink_comp_classes
, TRUE
);
117 plugin
->sink_comp_classes
= NULL
;
120 if (plugin
->info
.name
) {
121 g_string_free(plugin
->info
.name
, TRUE
);
122 plugin
->info
.name
= NULL
;
125 if (plugin
->info
.path
) {
126 g_string_free(plugin
->info
.path
, TRUE
);
127 plugin
->info
.path
= NULL
;
130 if (plugin
->info
.description
) {
131 g_string_free(plugin
->info
.description
, TRUE
);
132 plugin
->info
.description
= NULL
;
135 if (plugin
->info
.author
) {
136 g_string_free(plugin
->info
.author
, TRUE
);
137 plugin
->info
.author
= NULL
;
140 if (plugin
->info
.license
) {
141 g_string_free(plugin
->info
.license
, TRUE
);
142 plugin
->info
.license
= NULL
;
145 if (plugin
->info
.version
.extra
) {
146 g_string_free(plugin
->info
.version
.extra
, TRUE
);
147 plugin
->info
.version
.extra
= NULL
;
154 struct bt_plugin
*bt_plugin_create_empty(enum bt_plugin_type type
)
156 struct bt_plugin
*plugin
= NULL
;
158 BT_LOGD("Creating empty plugin object: type=%s",
159 bt_plugin_type_string(type
));
161 plugin
= g_new0(struct bt_plugin
, 1);
163 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one plugin.");
167 bt_object_init_shared(&plugin
->base
, bt_plugin_destroy
);
170 /* Create empty arrays of component classes */
171 plugin
->src_comp_classes
=
172 g_ptr_array_new_with_free_func(
173 (GDestroyNotify
) bt_object_put_ref
);
174 if (!plugin
->src_comp_classes
) {
175 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
179 plugin
->flt_comp_classes
=
180 g_ptr_array_new_with_free_func(
181 (GDestroyNotify
) bt_object_put_ref
);
182 if (!plugin
->flt_comp_classes
) {
183 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
187 plugin
->sink_comp_classes
=
188 g_ptr_array_new_with_free_func(
189 (GDestroyNotify
) bt_object_put_ref
);
190 if (!plugin
->sink_comp_classes
) {
191 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
195 /* Create empty info */
196 plugin
->info
.name
= g_string_new(NULL
);
197 if (!plugin
->info
.name
) {
198 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
202 plugin
->info
.path
= g_string_new(NULL
);
203 if (!plugin
->info
.path
) {
204 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
208 plugin
->info
.description
= g_string_new(NULL
);
209 if (!plugin
->info
.description
) {
210 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
214 plugin
->info
.author
= g_string_new(NULL
);
215 if (!plugin
->info
.author
) {
216 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
220 plugin
->info
.license
= g_string_new(NULL
);
221 if (!plugin
->info
.license
) {
222 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
226 plugin
->info
.version
.extra
= g_string_new(NULL
);
227 if (!plugin
->info
.version
.extra
) {
228 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
232 BT_LIB_LOGD("Created empty plugin object: %!+l", plugin
);
236 BT_OBJECT_PUT_REF_AND_RESET(plugin
);
243 void bt_plugin_set_path(struct bt_plugin
*plugin
, const char *path
)
247 g_string_assign(plugin
->info
.path
, path
);
248 plugin
->info
.path_set
= BT_TRUE
;
249 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, path=\"%s\"",
254 void bt_plugin_set_name(struct bt_plugin
*plugin
, const char *name
)
258 g_string_assign(plugin
->info
.name
, name
);
259 plugin
->info
.name_set
= BT_TRUE
;
260 BT_LIB_LOGD("Set plugin's name: %![plugin-]+l, name=\"%s\"",
265 void bt_plugin_set_description(struct bt_plugin
*plugin
,
266 const char *description
)
269 BT_ASSERT(description
);
270 g_string_assign(plugin
->info
.description
, description
);
271 plugin
->info
.description_set
= BT_TRUE
;
272 BT_LIB_LOGD("Set plugin's description: %![plugin-]+l", plugin
);
276 void bt_plugin_set_author(struct bt_plugin
*plugin
, const char *author
)
280 g_string_assign(plugin
->info
.author
, author
);
281 plugin
->info
.author_set
= BT_TRUE
;
282 BT_LIB_LOGD("Set plugin's author: %![plugin-]+l, author=\"%s\"",
287 void bt_plugin_set_license(struct bt_plugin
*plugin
, const char *license
)
291 g_string_assign(plugin
->info
.license
, license
);
292 plugin
->info
.license_set
= BT_TRUE
;
293 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, license=\"%s\"",
298 void bt_plugin_set_version(struct bt_plugin
*plugin
, unsigned int major
,
299 unsigned int minor
, unsigned int patch
, const char *extra
)
302 plugin
->info
.version
.major
= major
;
303 plugin
->info
.version
.minor
= minor
;
304 plugin
->info
.version
.patch
= patch
;
307 g_string_assign(plugin
->info
.version
.extra
, extra
);
310 plugin
->info
.version_set
= BT_TRUE
;
311 BT_LIB_LOGD("Set plugin's version: %![plugin-]+l, "
312 "major=%u, minor=%u, patch=%u, extra=\"%s\"",
313 plugin
, major
, minor
, patch
, extra
);
317 int bt_plugin_add_component_class(
318 struct bt_plugin
*plugin
, struct bt_component_class
*comp_class
)
320 GPtrArray
*comp_classes
;
323 BT_ASSERT(comp_class
);
325 switch (comp_class
->type
) {
326 case BT_COMPONENT_CLASS_TYPE_SOURCE
:
327 comp_classes
= plugin
->src_comp_classes
;
329 case BT_COMPONENT_CLASS_TYPE_FILTER
:
330 comp_classes
= plugin
->flt_comp_classes
;
332 case BT_COMPONENT_CLASS_TYPE_SINK
:
333 comp_classes
= plugin
->sink_comp_classes
;
339 /* Set component class's original plugin name */
340 BT_ASSERT(comp_class
->plugin_name
);
341 BT_ASSERT(plugin
->info
.name
);
342 g_string_assign(comp_class
->plugin_name
, plugin
->info
.name
->str
);
344 /* Add new component class */
345 bt_object_get_ref(comp_class
);
346 g_ptr_array_add(comp_classes
, comp_class
);
348 /* Special case for a shared object plugin */
349 if (plugin
->type
== BT_PLUGIN_TYPE_SO
) {
350 bt_plugin_so_on_add_component_class(plugin
, comp_class
);
353 BT_LIB_LOGD("Added component class to plugin: "
354 "%![plugin-]+l, %![cc-]+C", plugin
, comp_class
);
355 return BT_FUNC_STATUS_OK
;
359 void bt_plugin_set_destroy(struct bt_object
*obj
)
361 struct bt_plugin_set
*plugin_set
=
362 container_of(obj
, struct bt_plugin_set
, base
);
368 BT_LOGD("Destroying plugin set: addr=%p", plugin_set
);
370 if (plugin_set
->plugins
) {
371 BT_LOGD_STR("Putting plugins.");
372 g_ptr_array_free(plugin_set
->plugins
, TRUE
);
379 struct bt_plugin_set
*bt_plugin_set_create(void)
381 struct bt_plugin_set
*plugin_set
= g_new0(struct bt_plugin_set
, 1);
387 BT_LOGD_STR("Creating empty plugin set.");
388 bt_object_init_shared(&plugin_set
->base
, bt_plugin_set_destroy
);
390 plugin_set
->plugins
= g_ptr_array_new_with_free_func(
391 (GDestroyNotify
) bt_object_put_ref
);
392 if (!plugin_set
->plugins
) {
393 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
394 BT_OBJECT_PUT_REF_AND_RESET(plugin_set
);
398 BT_LOGD("Created empty plugin set: addr=%p", plugin_set
);
405 bool bt_plugin_set_contains_plugin(struct bt_plugin_set
*plugin_set
,
409 bool contains
= false;
411 BT_ASSERT(plugin_set
);
414 for (i
= 0; i
< plugin_set
->plugins
->len
; i
++) {
415 const struct bt_plugin
*plugin
= plugin_set
->plugins
->pdata
[i
];
417 if (strcmp(plugin
->info
.name
->str
, name
) == 0) {
428 void bt_plugin_set_add_plugin(struct bt_plugin_set
*plugin_set
,
429 struct bt_plugin
*plugin
)
431 BT_ASSERT(plugin_set
);
434 if (bt_plugin_set_contains_plugin(plugin_set
,
435 plugin
->info
.name
->str
)) {
439 bt_object_get_ref(plugin
);
440 g_ptr_array_add(plugin_set
->plugins
, plugin
);
441 BT_LIB_LOGD("Added plugin to plugin set: "
442 "plugin-set-addr=%p, %![plugin-]+l",
449 #endif /* BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H */