cpp-common/bt2c/fmt.hpp: use `wise_enum::string_type` in `EnableIfIsWiseEnum` definition
[babeltrace.git] / src / lib / plugin / plugin.h
CommitLineData
fb2dcc52 1/*
0235b0db
MJ
2 * SPDX-License-Identifier: MIT
3 *
e2f7325d 4 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
fb2dcc52 5 * Copyright 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
fb2dcc52
JG
6 */
7
0235b0db
MJ
8#ifndef BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H
9#define BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H
10
498e7994 11#include "common/common.h"
578e048b 12#include "lib/graph/component-class.h"
43c59509 13#include <babeltrace2/plugin/plugin-loading.h>
3fadfbc0 14#include <babeltrace2/plugin/plugin-dev.h>
578e048b 15#include "lib/object.h"
3fadfbc0 16#include <babeltrace2/types.h>
578e048b 17#include "common/assert.h"
55bb57e0 18#include <glib.h>
c4f23e30 19#include <stdbool.h>
fb2dcc52 20
578e048b 21#include "plugin-so.h"
d24d5663 22#include "lib/func-status.h"
578e048b 23
d3207ebf 24/* Protection: this file uses BT_LIB_LOG*() macros directly */
7151fb67 25#ifndef BT_LIB_LOG_SUPPORTED
c2d9d9cf 26# error Please include "lib/logging.h" before including this file.
d3207ebf
PP
27#endif
28
55bb57e0
PP
29enum bt_plugin_type {
30 BT_PLUGIN_TYPE_SO = 0,
31 BT_PLUGIN_TYPE_PYTHON = 1,
fb2dcc52
JG
32};
33
33b34c43
PP
34struct bt_plugin {
35 struct bt_object base;
55bb57e0 36 enum bt_plugin_type type;
cba174d5 37
d94d92ac
PP
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;
6ba0b073 42
55bb57e0
PP
43 /* Info (owned by this) */
44 struct {
45 GString *path;
46 GString *name;
47 GString *author;
48 GString *license;
49 GString *description;
50 struct {
51 unsigned int major;
52 unsigned int minor;
53 unsigned int patch;
54 GString *extra;
55 } version;
d94d92ac
PP
56 bool path_set;
57 bool name_set;
58 bool author_set;
59 bool license_set;
60 bool description_set;
61 bool version_set;
55bb57e0
PP
62 } info;
63
64 /* Value depends on the specific plugin type */
65 void *spec_data;
6fbd4105 66 void (*destroy_spec_data)(struct bt_plugin *);
33b34c43 67};
fb2dcc52 68
a8ff38ef
PP
69struct bt_plugin_set {
70 struct bt_object base;
71
72 /* Array of struct bt_plugin * */
73 GPtrArray *plugins;
74};
75
3fe0bf43
PP
76static inline
77const char *bt_plugin_type_string(enum bt_plugin_type type)
78{
79 switch (type) {
80 case BT_PLUGIN_TYPE_SO:
8a432889 81 return "SO";
3fe0bf43 82 case BT_PLUGIN_TYPE_PYTHON:
8a432889 83 return "PYTHON";
3fe0bf43
PP
84 default:
85 return "(unknown)";
86 }
87}
88
6fbd4105
PP
89static inline
90void bt_plugin_destroy(struct bt_object *obj)
91{
92 struct bt_plugin *plugin;
93
f6ccaed9 94 BT_ASSERT(obj);
6fbd4105 95 plugin = container_of(obj, struct bt_plugin, base);
3f7d4d90 96 BT_LIB_LOGI("Destroying plugin object: %!+l", plugin);
6fbd4105
PP
97
98 if (plugin->destroy_spec_data) {
99 plugin->destroy_spec_data(plugin);
100 }
101
d94d92ac
PP
102 if (plugin->src_comp_classes) {
103 BT_LOGD_STR("Putting source component classes.");
104 g_ptr_array_free(plugin->src_comp_classes, TRUE);
db5504f9 105 plugin->src_comp_classes = NULL;
d94d92ac
PP
106 }
107
108 if (plugin->flt_comp_classes) {
109 BT_LOGD_STR("Putting filter component classes.");
110 g_ptr_array_free(plugin->flt_comp_classes, TRUE);
db5504f9 111 plugin->flt_comp_classes = NULL;
d94d92ac
PP
112 }
113
114 if (plugin->sink_comp_classes) {
115 BT_LOGD_STR("Putting sink component classes.");
116 g_ptr_array_free(plugin->sink_comp_classes, TRUE);
db5504f9 117 plugin->sink_comp_classes = NULL;
6fbd4105
PP
118 }
119
120 if (plugin->info.name) {
121 g_string_free(plugin->info.name, TRUE);
db5504f9 122 plugin->info.name = NULL;
6fbd4105
PP
123 }
124
125 if (plugin->info.path) {
126 g_string_free(plugin->info.path, TRUE);
db5504f9 127 plugin->info.path = NULL;
6fbd4105
PP
128 }
129
130 if (plugin->info.description) {
131 g_string_free(plugin->info.description, TRUE);
db5504f9 132 plugin->info.description = NULL;
6fbd4105
PP
133 }
134
135 if (plugin->info.author) {
136 g_string_free(plugin->info.author, TRUE);
db5504f9 137 plugin->info.author = NULL;
6fbd4105
PP
138 }
139
140 if (plugin->info.license) {
141 g_string_free(plugin->info.license, TRUE);
db5504f9 142 plugin->info.license = NULL;
6fbd4105
PP
143 }
144
145 if (plugin->info.version.extra) {
146 g_string_free(plugin->info.version.extra, TRUE);
db5504f9 147 plugin->info.version.extra = NULL;
6fbd4105
PP
148 }
149
150 g_free(plugin);
151}
152
153static inline
154struct bt_plugin *bt_plugin_create_empty(enum bt_plugin_type type)
155{
156 struct bt_plugin *plugin = NULL;
157
3fe0bf43
PP
158 BT_LOGD("Creating empty plugin object: type=%s",
159 bt_plugin_type_string(type));
160
6fbd4105
PP
161 plugin = g_new0(struct bt_plugin, 1);
162 if (!plugin) {
870631a2 163 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate one plugin.");
6fbd4105
PP
164 goto error;
165 }
166
3fea54f6 167 bt_object_init_shared(&plugin->base, bt_plugin_destroy);
6fbd4105
PP
168 plugin->type = type;
169
d94d92ac
PP
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) {
870631a2 175 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
d94d92ac
PP
176 goto error;
177 }
178
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) {
870631a2 183 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
d94d92ac
PP
184 goto error;
185 }
186
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) {
870631a2 191 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
6fbd4105
PP
192 goto error;
193 }
194
195 /* Create empty info */
196 plugin->info.name = g_string_new(NULL);
197 if (!plugin->info.name) {
870631a2 198 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
199 goto error;
200 }
201
202 plugin->info.path = g_string_new(NULL);
203 if (!plugin->info.path) {
870631a2 204 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
205 goto error;
206 }
207
208 plugin->info.description = g_string_new(NULL);
209 if (!plugin->info.description) {
870631a2 210 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
211 goto error;
212 }
213
214 plugin->info.author = g_string_new(NULL);
215 if (!plugin->info.author) {
870631a2 216 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
217 goto error;
218 }
219
220 plugin->info.license = g_string_new(NULL);
221 if (!plugin->info.license) {
870631a2 222 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
223 goto error;
224 }
225
226 plugin->info.version.extra = g_string_new(NULL);
227 if (!plugin->info.version.extra) {
870631a2 228 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GString.");
6fbd4105
PP
229 goto error;
230 }
231
d94d92ac 232 BT_LIB_LOGD("Created empty plugin object: %!+l", plugin);
6fbd4105
PP
233 goto end;
234
235error:
65300d60 236 BT_OBJECT_PUT_REF_AND_RESET(plugin);
6fbd4105
PP
237
238end:
239 return plugin;
240}
55bb57e0
PP
241
242static inline
243void bt_plugin_set_path(struct bt_plugin *plugin, const char *path)
244{
f6ccaed9
PP
245 BT_ASSERT(plugin);
246 BT_ASSERT(path);
55bb57e0 247 g_string_assign(plugin->info.path, path);
c55a9f58 248 plugin->info.path_set = BT_TRUE;
3f7d4d90 249 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, path=\"%s\"",
d94d92ac 250 plugin, path);
55bb57e0
PP
251}
252
253static inline
254void bt_plugin_set_name(struct bt_plugin *plugin, const char *name)
255{
f6ccaed9
PP
256 BT_ASSERT(plugin);
257 BT_ASSERT(name);
55bb57e0 258 g_string_assign(plugin->info.name, name);
c55a9f58 259 plugin->info.name_set = BT_TRUE;
3f7d4d90 260 BT_LIB_LOGD("Set plugin's name: %![plugin-]+l, name=\"%s\"",
3fe0bf43 261 plugin, name);
55bb57e0
PP
262}
263
264static inline
265void bt_plugin_set_description(struct bt_plugin *plugin,
266 const char *description)
267{
f6ccaed9
PP
268 BT_ASSERT(plugin);
269 BT_ASSERT(description);
55bb57e0 270 g_string_assign(plugin->info.description, description);
c55a9f58 271 plugin->info.description_set = BT_TRUE;
3f7d4d90 272 BT_LIB_LOGD("Set plugin's description: %![plugin-]+l", plugin);
55bb57e0
PP
273}
274
275static inline
276void bt_plugin_set_author(struct bt_plugin *plugin, const char *author)
277{
f6ccaed9
PP
278 BT_ASSERT(plugin);
279 BT_ASSERT(author);
55bb57e0 280 g_string_assign(plugin->info.author, author);
c55a9f58 281 plugin->info.author_set = BT_TRUE;
3f7d4d90 282 BT_LIB_LOGD("Set plugin's author: %![plugin-]+l, author=\"%s\"",
d94d92ac 283 plugin, author);
55bb57e0
PP
284}
285
286static inline
287void bt_plugin_set_license(struct bt_plugin *plugin, const char *license)
288{
f6ccaed9
PP
289 BT_ASSERT(plugin);
290 BT_ASSERT(license);
55bb57e0 291 g_string_assign(plugin->info.license, license);
c55a9f58 292 plugin->info.license_set = BT_TRUE;
3f7d4d90 293 BT_LIB_LOGD("Set plugin's path: %![plugin-]+l, license=\"%s\"",
d94d92ac 294 plugin, license);
55bb57e0
PP
295}
296
297static inline
298void bt_plugin_set_version(struct bt_plugin *plugin, unsigned int major,
299 unsigned int minor, unsigned int patch, const char *extra)
300{
f6ccaed9 301 BT_ASSERT(plugin);
55bb57e0
PP
302 plugin->info.version.major = major;
303 plugin->info.version.minor = minor;
304 plugin->info.version.patch = patch;
305
306 if (extra) {
307 g_string_assign(plugin->info.version.extra, extra);
308 }
309
c55a9f58 310 plugin->info.version_set = BT_TRUE;
3f7d4d90 311 BT_LIB_LOGD("Set plugin's version: %![plugin-]+l, "
3fe0bf43 312 "major=%u, minor=%u, patch=%u, extra=\"%s\"",
d94d92ac 313 plugin, major, minor, patch, extra);
55bb57e0
PP
314}
315
316static inline
d24d5663 317int bt_plugin_add_component_class(
d94d92ac 318 struct bt_plugin *plugin, struct bt_component_class *comp_class)
55bb57e0 319{
d94d92ac
PP
320 GPtrArray *comp_classes;
321
f6ccaed9 322 BT_ASSERT(plugin);
d94d92ac
PP
323 BT_ASSERT(comp_class);
324
325 switch (comp_class->type) {
326 case BT_COMPONENT_CLASS_TYPE_SOURCE:
327 comp_classes = plugin->src_comp_classes;
328 break;
329 case BT_COMPONENT_CLASS_TYPE_FILTER:
330 comp_classes = plugin->flt_comp_classes;
331 break;
332 case BT_COMPONENT_CLASS_TYPE_SINK:
333 comp_classes = plugin->sink_comp_classes;
334 break;
335 default:
498e7994 336 bt_common_abort();
d94d92ac 337 }
3fe0bf43 338
2ce06c9e
PP
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);
343
d94d92ac 344 /* Add new component class */
398454ed
PP
345 bt_object_get_ref(comp_class);
346 g_ptr_array_add(comp_classes, comp_class);
d94d92ac
PP
347
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);
3fe0bf43
PP
351 }
352
d94d92ac
PP
353 BT_LIB_LOGD("Added component class to plugin: "
354 "%![plugin-]+l, %![cc-]+C", plugin, comp_class);
d24d5663 355 return BT_FUNC_STATUS_OK;
55bb57e0
PP
356}
357
a8ff38ef
PP
358static
359void bt_plugin_set_destroy(struct bt_object *obj)
360{
361 struct bt_plugin_set *plugin_set =
362 container_of(obj, struct bt_plugin_set, base);
363
364 if (!plugin_set) {
365 return;
366 }
367
3fe0bf43
PP
368 BT_LOGD("Destroying plugin set: addr=%p", plugin_set);
369
a8ff38ef 370 if (plugin_set->plugins) {
3fe0bf43 371 BT_LOGD_STR("Putting plugins.");
a8ff38ef
PP
372 g_ptr_array_free(plugin_set->plugins, TRUE);
373 }
374
375 g_free(plugin_set);
376}
377
378static inline
379struct bt_plugin_set *bt_plugin_set_create(void)
380{
381 struct bt_plugin_set *plugin_set = g_new0(struct bt_plugin_set, 1);
382
383 if (!plugin_set) {
384 goto end;
385 }
386
3fe0bf43 387 BT_LOGD_STR("Creating empty plugin set.");
3fea54f6 388 bt_object_init_shared(&plugin_set->base, bt_plugin_set_destroy);
a8ff38ef
PP
389
390 plugin_set->plugins = g_ptr_array_new_with_free_func(
65300d60 391 (GDestroyNotify) bt_object_put_ref);
a8ff38ef 392 if (!plugin_set->plugins) {
870631a2 393 BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
65300d60 394 BT_OBJECT_PUT_REF_AND_RESET(plugin_set);
a8ff38ef
PP
395 goto end;
396 }
397
3fe0bf43
PP
398 BT_LOGD("Created empty plugin set: addr=%p", plugin_set);
399
a8ff38ef
PP
400end:
401 return plugin_set;
402}
403
577fa92f
PP
404static inline
405bool bt_plugin_set_contains_plugin(struct bt_plugin_set *plugin_set,
406 const char *name)
407{
408 uint64_t i;
409 bool contains = false;
410
411 BT_ASSERT(plugin_set);
412 BT_ASSERT(name);
413
414 for (i = 0; i < plugin_set->plugins->len; i++) {
415 const struct bt_plugin *plugin = plugin_set->plugins->pdata[i];
416
417 if (strcmp(plugin->info.name->str, name) == 0) {
418 contains = true;
419 goto end;
420 }
421 }
422
423end:
424 return contains;
425}
426
a8ff38ef
PP
427static inline
428void bt_plugin_set_add_plugin(struct bt_plugin_set *plugin_set,
429 struct bt_plugin *plugin)
430{
f6ccaed9
PP
431 BT_ASSERT(plugin_set);
432 BT_ASSERT(plugin);
577fa92f
PP
433
434 if (bt_plugin_set_contains_plugin(plugin_set,
435 plugin->info.name->str)) {
436 goto end;
437 }
438
398454ed
PP
439 bt_object_get_ref(plugin);
440 g_ptr_array_add(plugin_set->plugins, plugin);
3f7d4d90 441 BT_LIB_LOGD("Added plugin to plugin set: "
d94d92ac
PP
442 "plugin-set-addr=%p, %![plugin-]+l",
443 plugin_set, plugin);
577fa92f
PP
444
445end:
446 return;
8c1a3187
PP
447}
448
33b34c43 449#endif /* BABELTRACE_PLUGIN_PLUGIN_INTERNAL_H */
This page took 0.127039 seconds and 4 git commands to generate.