lib: rename `lib-logging.h` to `logging.h`
[babeltrace.git] / src / lib / plugin / plugin-so.c
CommitLineData
55bb57e0 1/*
e2f7325d 2 * Copyright 2017-2018 Philippe Proulx <pproulx@efficios.com>
55bb57e0 3 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
55bb57e0
PP
4 *
5 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
350ad6c1 26#define BT_LOG_TAG "LIB/PLUGIN-SO"
c2d9d9cf 27#include "lib/logging.h"
3fe0bf43 28
578e048b
MJ
29#include "common/assert.h"
30#include "lib/assert-pre.h"
31#include "compat/compiler.h"
3fadfbc0 32#include <babeltrace2/plugin/plugin-dev.h>
578e048b 33#include "lib/graph/component-class.h"
3fadfbc0
MJ
34#include <babeltrace2/graph/component-class.h>
35#include <babeltrace2/graph/component-class-source.h>
36#include <babeltrace2/graph/component-class-filter.h>
37#include <babeltrace2/graph/component-class-sink.h>
38#include <babeltrace2/types.h>
578e048b 39#include "common/list.h"
55bb57e0 40#include <string.h>
0fbb9a9f 41#include <stdlib.h>
55bb57e0
PP
42#include <glib.h>
43#include <gmodule.h>
44
578e048b
MJ
45#include "plugin.h"
46#include "plugin-so.h"
47
44a3451a 48#define NATIVE_PLUGIN_SUFFIX "." G_MODULE_SUFFIX
55bb57e0
PP
49#define NATIVE_PLUGIN_SUFFIX_LEN sizeof(NATIVE_PLUGIN_SUFFIX)
50#define LIBTOOL_PLUGIN_SUFFIX ".la"
51#define LIBTOOL_PLUGIN_SUFFIX_LEN sizeof(LIBTOOL_PLUGIN_SUFFIX)
52
91d81473 53#define PLUGIN_SUFFIX_LEN bt_max_t(size_t, sizeof(NATIVE_PLUGIN_SUFFIX), \
55bb57e0
PP
54 sizeof(LIBTOOL_PLUGIN_SUFFIX))
55
52238017 56BT_PLUGIN_MODULE();
55bb57e0
PP
57
58/*
bfa9a4be
MD
59 * This list, global to the library, keeps all component classes that
60 * have a reference to their shared library handles. It allows iteration
61 * on all component classes still present when the destructor executes
62 * to release the shared library handle references they might still have.
55bb57e0 63 *
bfa9a4be 64 * The list items are the component classes created with
55bb57e0
PP
65 * bt_plugin_add_component_class(). They keep the shared library handle
66 * object created by their plugin alive so that the plugin's code is
67 * not discarded when it could still be in use by living components
68 * created from those component classes:
69 *
bfa9a4be 70 * [component] --ref-> [component class]-> [shlib handle]
55bb57e0 71 *
bfa9a4be 72 * It allows this use-case:
55bb57e0 73 *
c8db3219 74 * my_plugins = bt_plugin_find_all_from_file("/path/to/my-plugin.so");
55bb57e0
PP
75 * // instantiate components from a plugin's component classes
76 * // put plugins and free my_plugins here
77 * // user code of instantiated components still exists
78 *
bfa9a4be
MD
79 * An entry is removed from this list when a component class is
80 * destroyed thanks to a custom destroy listener. When the entry is
81 * removed, the entry is removed from the list, and we release the
82 * reference on the shlib handle. Assuming the original plugin object
83 * which contained some component classes is put first, when the last
84 * component class is removed from this list, the shared library handle
85 * object's reference count falls to zero and the shared library is
86 * finally closed.
55bb57e0 87 */
bfa9a4be 88
55bb57e0 89static
bfa9a4be 90BT_LIST_HEAD(component_class_list);
55bb57e0
PP
91
92__attribute__((destructor)) static
bfa9a4be
MD
93void fini_comp_class_list(void)
94{
95 struct bt_component_class *comp_class, *tmp;
96
97 bt_list_for_each_entry_safe(comp_class, tmp, &component_class_list, node) {
98 bt_list_del(&comp_class->node);
65300d60 99 BT_OBJECT_PUT_REF_AND_RESET(comp_class->so_handle);
55bb57e0 100 }
d94d92ac 101
bfa9a4be 102 BT_LOGD_STR("Released references from all component classes to shared library handles.");
55bb57e0
PP
103}
104
9724cce9 105static inline
a21d1cb8 106const char *bt_self_plugin_status_string(enum bt_self_plugin_status status)
9724cce9
PP
107{
108 switch (status) {
a21d1cb8
PP
109 case BT_SELF_PLUGIN_STATUS_OK:
110 return "BT_SELF_PLUGIN_STATUS_OK";
111 case BT_SELF_PLUGIN_STATUS_ERROR:
112 return "BT_SELF_PLUGIN_STATUS_ERROR";
113 case BT_SELF_PLUGIN_STATUS_NOMEM:
114 return "BT_SELF_PLUGIN_STATUS_NOMEM";
9724cce9
PP
115 default:
116 return "(unknown)";
117 }
118}
119
55bb57e0
PP
120static
121void bt_plugin_so_shared_lib_handle_destroy(struct bt_object *obj)
122{
123 struct bt_plugin_so_shared_lib_handle *shared_lib_handle;
124
f6ccaed9 125 BT_ASSERT(obj);
55bb57e0
PP
126 shared_lib_handle = container_of(obj,
127 struct bt_plugin_so_shared_lib_handle, base);
3fe0bf43
PP
128 const char *path = shared_lib_handle->path ?
129 shared_lib_handle->path->str : NULL;
130
3f7d4d90 131 BT_LOGI("Destroying shared library handle: addr=%p, path=\"%s\"",
3fe0bf43 132 shared_lib_handle, path);
55bb57e0
PP
133
134 if (shared_lib_handle->init_called && shared_lib_handle->exit) {
3fe0bf43 135 BT_LOGD_STR("Calling user's plugin exit function.");
9724cce9
PP
136 shared_lib_handle->exit();
137 BT_LOGD_STR("User function returned.");
55bb57e0
PP
138 }
139
140 if (shared_lib_handle->module) {
3f3b1761 141#ifndef BT_DEBUG_MODE
f1447220
PP
142 /*
143 * Valgrind shows incomplete stack traces when
144 * dynamically loaded libraries are closed before it
145 * finishes. Use the BABELTRACE_NO_DLCLOSE in a debug
146 * build to avoid this.
147 */
148 const char *var = getenv("BABELTRACE_NO_DLCLOSE");
149
150 if (!var || strcmp(var, "1") != 0) {
151#endif
3f7d4d90 152 BT_LOGI("Closing GModule: path=\"%s\"", path);
3fe0bf43 153
f1447220 154 if (!g_module_close(shared_lib_handle->module)) {
3fe0bf43
PP
155 BT_LOGE("Cannot close GModule: %s: path=\"%s\"",
156 g_module_error(), path);
f1447220 157 }
db5504f9
PP
158
159 shared_lib_handle->module = NULL;
3f3b1761 160#ifndef BT_DEBUG_MODE
3fe0bf43 161 } else {
3f7d4d90 162 BT_LOGI("Not closing GModule because `BABELTRACE_NO_DLCLOSE=1`: "
3fe0bf43 163 "path=\"%s\"", path);
55bb57e0 164 }
f1447220 165#endif
55bb57e0
PP
166 }
167
168 if (shared_lib_handle->path) {
169 g_string_free(shared_lib_handle->path, TRUE);
db5504f9 170 shared_lib_handle->path = NULL;
55bb57e0
PP
171 }
172
173 g_free(shared_lib_handle);
174}
175
176static
177struct bt_plugin_so_shared_lib_handle *bt_plugin_so_shared_lib_handle_create(
178 const char *path)
179{
180 struct bt_plugin_so_shared_lib_handle *shared_lib_handle = NULL;
181
3f7d4d90 182 BT_LOGI("Creating shared library handle: path=\"%s\"", path);
55bb57e0
PP
183 shared_lib_handle = g_new0(struct bt_plugin_so_shared_lib_handle, 1);
184 if (!shared_lib_handle) {
3fe0bf43 185 BT_LOGE_STR("Failed to allocate one shared library handle.");
55bb57e0
PP
186 goto error;
187 }
188
3fea54f6
PP
189 bt_object_init_shared(&shared_lib_handle->base,
190 bt_plugin_so_shared_lib_handle_destroy);
55bb57e0
PP
191
192 if (!path) {
193 goto end;
194 }
195
196 shared_lib_handle->path = g_string_new(path);
197 if (!shared_lib_handle->path) {
3fe0bf43 198 BT_LOGE_STR("Failed to allocate a GString.");
55bb57e0
PP
199 goto error;
200 }
201
424b8c43 202 shared_lib_handle->module = g_module_open(path, G_MODULE_BIND_LOCAL);
55bb57e0 203 if (!shared_lib_handle->module) {
50ad9320 204 /*
3f7d4d90 205 * INFO-level logging because we're only _trying_ to
50ad9320
PP
206 * open this file as a Babeltrace plugin: if it's not,
207 * it's not an error. And because this can be tried
3f7d4d90
PP
208 * during bt_plugin_find_all_from_dir(), it's not even a
209 * warning.
50ad9320 210 */
3f7d4d90 211 BT_LOGI("Cannot open GModule: %s: path=\"%s\"",
3fe0bf43 212 g_module_error(), path);
55bb57e0
PP
213 goto error;
214 }
215
216 goto end;
217
218error:
65300d60 219 BT_OBJECT_PUT_REF_AND_RESET(shared_lib_handle);
55bb57e0
PP
220
221end:
3fe0bf43 222 if (shared_lib_handle) {
3f7d4d90 223 BT_LOGI("Created shared library handle: path=\"%s\", addr=%p",
3fe0bf43
PP
224 path, shared_lib_handle);
225 }
226
55bb57e0
PP
227 return shared_lib_handle;
228}
229
6fbd4105 230static
55bb57e0
PP
231void bt_plugin_so_destroy_spec_data(struct bt_plugin *plugin)
232{
233 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
234
235 if (!plugin->spec_data) {
236 return;
237 }
238
f6ccaed9
PP
239 BT_ASSERT(plugin->type == BT_PLUGIN_TYPE_SO);
240 BT_ASSERT(spec);
65300d60 241 BT_OBJECT_PUT_REF_AND_RESET(spec->shared_lib_handle);
55bb57e0
PP
242 g_free(plugin->spec_data);
243 plugin->spec_data = NULL;
244}
245
246/*
247 * This function does the following:
248 *
249 * 1. Iterate on the plugin descriptor attributes section and set the
250 * plugin's attributes depending on the attribute types. This
251 * includes the name of the plugin, its description, and its
252 * initialization function, for example.
253 *
254 * 2. Iterate on the component class descriptors section and create one
255 * "full descriptor" (temporary structure) for each one that is found
256 * and attached to our plugin descriptor.
257 *
258 * 3. Iterate on the component class descriptor attributes section and
259 * set the corresponding full descriptor's attributes depending on
260 * the attribute types. This includes the description of the
261 * component class, as well as its initialization and destroy
262 * methods.
263 *
264 * 4. Call the user's plugin initialization function, if any is
265 * defined.
266 *
267 * 5. For each full component class descriptor, create a component class
268 * object, set its optional attributes, and add it to the plugin
269 * object.
270 *
271 * 6. Freeze the plugin object.
272 */
273static
274enum bt_plugin_status bt_plugin_so_init(
275 struct bt_plugin *plugin,
276 const struct __bt_plugin_descriptor *descriptor,
277 struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
278 struct __bt_plugin_descriptor_attribute const * const *attrs_end,
279 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
280 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
281 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
282 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
283{
284 /*
285 * This structure's members point to the plugin's memory
286 * (do NOT free).
287 */
288 struct comp_class_full_descriptor {
289 const struct __bt_plugin_component_class_descriptor *descriptor;
290 const char *description;
279b3f15 291 const char *help;
d94d92ac
PP
292
293 union {
294 struct {
0d72b8c3
PP
295 bt_component_class_source_init_method init;
296 bt_component_class_source_finalize_method finalize;
297 bt_component_class_source_query_method query;
298 bt_component_class_source_accept_output_port_connection_method accept_output_port_connection;
299 bt_component_class_source_output_port_connected_method output_port_connected;
d6e69534
PP
300 bt_component_class_source_message_iterator_init_method msg_iter_init;
301 bt_component_class_source_message_iterator_finalize_method msg_iter_finalize;
7474e7d3
PP
302 bt_component_class_source_message_iterator_seek_ns_from_origin_method msg_iter_seek_ns_from_origin;
303 bt_component_class_source_message_iterator_seek_beginning_method msg_iter_seek_beginning;
304 bt_component_class_source_message_iterator_can_seek_ns_from_origin_method msg_iter_can_seek_ns_from_origin;
305 bt_component_class_source_message_iterator_can_seek_beginning_method msg_iter_can_seek_beginning;
d94d92ac
PP
306 } source;
307
308 struct {
0d72b8c3
PP
309 bt_component_class_filter_init_method init;
310 bt_component_class_filter_finalize_method finalize;
311 bt_component_class_filter_query_method query;
312 bt_component_class_filter_accept_input_port_connection_method accept_input_port_connection;
313 bt_component_class_filter_accept_output_port_connection_method accept_output_port_connection;
314 bt_component_class_filter_input_port_connected_method input_port_connected;
315 bt_component_class_filter_output_port_connected_method output_port_connected;
d6e69534
PP
316 bt_component_class_filter_message_iterator_init_method msg_iter_init;
317 bt_component_class_filter_message_iterator_finalize_method msg_iter_finalize;
7474e7d3
PP
318 bt_component_class_filter_message_iterator_seek_ns_from_origin_method msg_iter_seek_ns_from_origin;
319 bt_component_class_filter_message_iterator_seek_beginning_method msg_iter_seek_beginning;
320 bt_component_class_filter_message_iterator_can_seek_ns_from_origin_method msg_iter_can_seek_ns_from_origin;
321 bt_component_class_filter_message_iterator_can_seek_beginning_method msg_iter_can_seek_beginning;
d94d92ac
PP
322 } filter;
323
324 struct {
0d72b8c3
PP
325 bt_component_class_sink_init_method init;
326 bt_component_class_sink_finalize_method finalize;
327 bt_component_class_sink_query_method query;
328 bt_component_class_sink_accept_input_port_connection_method accept_input_port_connection;
329 bt_component_class_sink_input_port_connected_method input_port_connected;
5badd463 330 bt_component_class_sink_graph_is_configured_method graph_is_configured;
d94d92ac
PP
331 } sink;
332 } methods;
55bb57e0
PP
333 };
334
335 enum bt_plugin_status status = BT_PLUGIN_STATUS_OK;
336 struct __bt_plugin_descriptor_attribute const * const *cur_attr_ptr;
337 struct __bt_plugin_component_class_descriptor const * const *cur_cc_descr_ptr;
338 struct __bt_plugin_component_class_descriptor_attribute const * const *cur_cc_descr_attr_ptr;
339 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
340 GArray *comp_class_full_descriptors;
341 size_t i;
342 int ret;
343
3f7d4d90 344 BT_LOGI("Initializing plugin object from descriptors found in sections: "
3fe0bf43
PP
345 "plugin-addr=%p, plugin-path=\"%s\", "
346 "attrs-begin-addr=%p, attrs-end-addr=%p, "
347 "cc-descr-begin-addr=%p, cc-descr-end-addr=%p, "
348 "cc-descr-attrs-begin-addr=%p, cc-descr-attrs-end-addr=%p",
349 plugin,
350 spec->shared_lib_handle->path ?
351 spec->shared_lib_handle->path->str : NULL,
352 attrs_begin, attrs_end,
353 cc_descriptors_begin, cc_descriptors_end,
354 cc_descr_attrs_begin, cc_descr_attrs_end);
55bb57e0
PP
355 comp_class_full_descriptors = g_array_new(FALSE, TRUE,
356 sizeof(struct comp_class_full_descriptor));
357 if (!comp_class_full_descriptors) {
3fe0bf43 358 BT_LOGE_STR("Failed to allocate a GArray.");
55bb57e0
PP
359 status = BT_PLUGIN_STATUS_ERROR;
360 goto end;
361 }
362
363 /* Set mandatory attributes */
364 spec->descriptor = descriptor;
365 bt_plugin_set_name(plugin, descriptor->name);
366
367 /*
368 * Find and set optional attributes attached to this plugin
369 * descriptor.
370 */
371 for (cur_attr_ptr = attrs_begin; cur_attr_ptr != attrs_end; cur_attr_ptr++) {
372 const struct __bt_plugin_descriptor_attribute *cur_attr =
373 *cur_attr_ptr;
374
52238017
MJ
375 if (cur_attr == NULL) {
376 continue;
377 }
378
55bb57e0
PP
379 if (cur_attr->plugin_descriptor != descriptor) {
380 continue;
381 }
382
383 switch (cur_attr->type) {
384 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_INIT:
385 spec->init = cur_attr->value.init;
386 break;
387 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_EXIT:
388 spec->shared_lib_handle->exit = cur_attr->value.exit;
389 break;
390 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_AUTHOR:
391 bt_plugin_set_author(plugin, cur_attr->value.author);
392 break;
393 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_LICENSE:
394 bt_plugin_set_license(plugin, cur_attr->value.license);
395 break;
396 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
397 bt_plugin_set_description(plugin, cur_attr->value.description);
398 break;
399 case BT_PLUGIN_DESCRIPTOR_ATTRIBUTE_TYPE_VERSION:
400 bt_plugin_set_version(plugin,
401 (unsigned int) cur_attr->value.version.major,
402 (unsigned int) cur_attr->value.version.minor,
403 (unsigned int) cur_attr->value.version.patch,
404 cur_attr->value.version.extra);
405 break;
406 default:
50ad9320
PP
407 /*
408 * WARN-level logging because this should not
409 * happen with the appropriate ABI version. If
410 * we're here, we know that for the reported
411 * version of the ABI, this attribute is
412 * unknown.
413 */
3fe0bf43
PP
414 BT_LOGW("Ignoring unknown plugin descriptor attribute: "
415 "plugin-path=\"%s\", plugin-name=\"%s\", "
416 "attr-type-name=\"%s\", attr-type-id=%d",
417 spec->shared_lib_handle->path ?
418 spec->shared_lib_handle->path->str :
419 NULL,
420 descriptor->name, cur_attr->type_name,
421 cur_attr->type);
55bb57e0
PP
422 break;
423 }
424 }
425
426 /*
427 * Find component class descriptors attached to this plugin
428 * descriptor and initialize corresponding full component class
429 * descriptors in the array.
430 */
431 for (cur_cc_descr_ptr = cc_descriptors_begin; cur_cc_descr_ptr != cc_descriptors_end; cur_cc_descr_ptr++) {
432 const struct __bt_plugin_component_class_descriptor *cur_cc_descr =
433 *cur_cc_descr_ptr;
434 struct comp_class_full_descriptor full_descriptor = {0};
435
52238017
MJ
436 if (cur_cc_descr == NULL) {
437 continue;
438 }
439
55bb57e0
PP
440 if (cur_cc_descr->plugin_descriptor != descriptor) {
441 continue;
442 }
443
444 full_descriptor.descriptor = cur_cc_descr;
445 g_array_append_val(comp_class_full_descriptors,
446 full_descriptor);
447 }
448
449 /*
450 * Find component class descriptor attributes attached to this
451 * plugin descriptor and update corresponding full component
452 * class descriptors in the array.
453 */
454 for (cur_cc_descr_attr_ptr = cc_descr_attrs_begin; cur_cc_descr_attr_ptr != cc_descr_attrs_end; cur_cc_descr_attr_ptr++) {
455 const struct __bt_plugin_component_class_descriptor_attribute *cur_cc_descr_attr =
456 *cur_cc_descr_attr_ptr;
d94d92ac 457 enum bt_component_class_type cc_type;
55bb57e0 458
52238017
MJ
459 if (cur_cc_descr_attr == NULL) {
460 continue;
461 }
462
55bb57e0
PP
463 if (cur_cc_descr_attr->comp_class_descriptor->plugin_descriptor !=
464 descriptor) {
465 continue;
466 }
467
d94d92ac
PP
468 cc_type = cur_cc_descr_attr->comp_class_descriptor->type;
469
55bb57e0
PP
470 /* Find the corresponding component class descriptor entry */
471 for (i = 0; i < comp_class_full_descriptors->len; i++) {
472 struct comp_class_full_descriptor *cc_full_descr =
473 &g_array_index(comp_class_full_descriptors,
474 struct comp_class_full_descriptor, i);
475
d94d92ac 476 if (cur_cc_descr_attr->comp_class_descriptor !=
55bb57e0 477 cc_full_descr->descriptor) {
d94d92ac
PP
478 continue;
479 }
480
481 switch (cur_cc_descr_attr->type) {
482 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_DESCRIPTION:
483 cc_full_descr->description =
484 cur_cc_descr_attr->value.description;
485 break;
486 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_HELP:
487 cc_full_descr->help =
488 cur_cc_descr_attr->value.help;
489 break;
490 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INIT_METHOD:
491 switch (cc_type) {
492 case BT_COMPONENT_CLASS_TYPE_SOURCE:
493 cc_full_descr->methods.source.init =
494 cur_cc_descr_attr->value.source_init_method;
55bb57e0 495 break;
d94d92ac
PP
496 case BT_COMPONENT_CLASS_TYPE_FILTER:
497 cc_full_descr->methods.filter.init =
498 cur_cc_descr_attr->value.filter_init_method;
279b3f15 499 break;
d94d92ac
PP
500 case BT_COMPONENT_CLASS_TYPE_SINK:
501 cc_full_descr->methods.sink.init =
502 cur_cc_descr_attr->value.sink_init_method;
55bb57e0 503 break;
d94d92ac
PP
504 default:
505 abort();
506 }
507 break;
508 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_FINALIZE_METHOD:
509 switch (cc_type) {
510 case BT_COMPONENT_CLASS_TYPE_SOURCE:
511 cc_full_descr->methods.source.finalize =
512 cur_cc_descr_attr->value.source_finalize_method;
55bb57e0 513 break;
d94d92ac
PP
514 case BT_COMPONENT_CLASS_TYPE_FILTER:
515 cc_full_descr->methods.filter.finalize =
516 cur_cc_descr_attr->value.filter_finalize_method;
8463eac2 517 break;
d94d92ac
PP
518 case BT_COMPONENT_CLASS_TYPE_SINK:
519 cc_full_descr->methods.sink.finalize =
520 cur_cc_descr_attr->value.sink_finalize_method;
72b913fb 521 break;
d94d92ac
PP
522 default:
523 abort();
524 }
525 break;
526 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_QUERY_METHOD:
527 switch (cc_type) {
528 case BT_COMPONENT_CLASS_TYPE_SOURCE:
529 cc_full_descr->methods.source.query =
530 cur_cc_descr_attr->value.source_query_method;
0d8b4d8e 531 break;
d94d92ac
PP
532 case BT_COMPONENT_CLASS_TYPE_FILTER:
533 cc_full_descr->methods.filter.query =
534 cur_cc_descr_attr->value.filter_query_method;
55bb57e0 535 break;
d94d92ac
PP
536 case BT_COMPONENT_CLASS_TYPE_SINK:
537 cc_full_descr->methods.sink.query =
538 cur_cc_descr_attr->value.sink_query_method;
55bb57e0 539 break;
d94d92ac
PP
540 default:
541 abort();
542 }
543 break;
544 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_INPUT_PORT_CONNECTION_METHOD:
545 switch (cc_type) {
546 case BT_COMPONENT_CLASS_TYPE_FILTER:
547 cc_full_descr->methods.filter.accept_input_port_connection =
548 cur_cc_descr_attr->value.filter_accept_input_port_connection_method;
549 break;
550 case BT_COMPONENT_CLASS_TYPE_SINK:
551 cc_full_descr->methods.sink.accept_input_port_connection =
552 cur_cc_descr_attr->value.sink_accept_input_port_connection_method;
553 break;
554 default:
555 abort();
556 }
557 break;
558 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_ACCEPT_OUTPUT_PORT_CONNECTION_METHOD:
559 switch (cc_type) {
560 case BT_COMPONENT_CLASS_TYPE_SOURCE:
561 cc_full_descr->methods.source.accept_output_port_connection =
562 cur_cc_descr_attr->value.source_accept_output_port_connection_method;
563 break;
564 case BT_COMPONENT_CLASS_TYPE_FILTER:
565 cc_full_descr->methods.filter.accept_output_port_connection =
566 cur_cc_descr_attr->value.filter_accept_output_port_connection_method;
567 break;
568 default:
569 abort();
570 }
571 break;
572 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_INPUT_PORT_CONNECTED_METHOD:
573 switch (cc_type) {
574 case BT_COMPONENT_CLASS_TYPE_FILTER:
575 cc_full_descr->methods.filter.input_port_connected =
576 cur_cc_descr_attr->value.filter_input_port_connected_method;
577 break;
578 case BT_COMPONENT_CLASS_TYPE_SINK:
579 cc_full_descr->methods.sink.input_port_connected =
580 cur_cc_descr_attr->value.sink_input_port_connected_method;
55bb57e0 581 break;
55bb57e0 582 default:
d94d92ac
PP
583 abort();
584 }
585 break;
586 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_OUTPUT_PORT_CONNECTED_METHOD:
587 switch (cc_type) {
588 case BT_COMPONENT_CLASS_TYPE_SOURCE:
589 cc_full_descr->methods.source.output_port_connected =
590 cur_cc_descr_attr->value.source_output_port_connected_method;
591 break;
592 case BT_COMPONENT_CLASS_TYPE_FILTER:
593 cc_full_descr->methods.filter.output_port_connected =
594 cur_cc_descr_attr->value.filter_output_port_connected_method;
55bb57e0 595 break;
d94d92ac
PP
596 default:
597 abort();
55bb57e0 598 }
d94d92ac 599 break;
5badd463
PP
600 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_GRAPH_IS_CONFIGURED_METHOD:
601 switch (cc_type) {
602 case BT_COMPONENT_CLASS_TYPE_SINK:
603 cc_full_descr->methods.sink.graph_is_configured =
604 cur_cc_descr_attr->value.sink_graph_is_configured_method;
605 break;
606 default:
607 abort();
608 }
609 break;
d6e69534 610 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_INIT_METHOD:
d94d92ac
PP
611 switch (cc_type) {
612 case BT_COMPONENT_CLASS_TYPE_SOURCE:
d6e69534
PP
613 cc_full_descr->methods.source.msg_iter_init =
614 cur_cc_descr_attr->value.source_msg_iter_init_method;
d94d92ac
PP
615 break;
616 case BT_COMPONENT_CLASS_TYPE_FILTER:
d6e69534
PP
617 cc_full_descr->methods.filter.msg_iter_init =
618 cur_cc_descr_attr->value.filter_msg_iter_init_method;
d94d92ac
PP
619 break;
620 default:
621 abort();
622 }
623 break;
d6e69534 624 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_FINALIZE_METHOD:
d94d92ac
PP
625 switch (cc_type) {
626 case BT_COMPONENT_CLASS_TYPE_SOURCE:
d6e69534
PP
627 cc_full_descr->methods.source.msg_iter_finalize =
628 cur_cc_descr_attr->value.source_msg_iter_finalize_method;
d94d92ac
PP
629 break;
630 case BT_COMPONENT_CLASS_TYPE_FILTER:
d6e69534
PP
631 cc_full_descr->methods.filter.msg_iter_finalize =
632 cur_cc_descr_attr->value.filter_msg_iter_finalize_method;
d94d92ac
PP
633 break;
634 default:
635 abort();
636 }
637 break;
7474e7d3
PP
638 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_NS_FROM_ORIGIN_METHOD:
639 switch (cc_type) {
640 case BT_COMPONENT_CLASS_TYPE_SOURCE:
641 cc_full_descr->methods.source.msg_iter_seek_ns_from_origin =
642 cur_cc_descr_attr->value.source_msg_iter_seek_ns_from_origin_method;
643 break;
644 case BT_COMPONENT_CLASS_TYPE_FILTER:
645 cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin =
646 cur_cc_descr_attr->value.filter_msg_iter_seek_ns_from_origin_method;
647 break;
648 default:
649 abort();
650 }
651 break;
652 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_SEEK_BEGINNING_METHOD:
653 switch (cc_type) {
654 case BT_COMPONENT_CLASS_TYPE_SOURCE:
655 cc_full_descr->methods.source.msg_iter_seek_beginning =
656 cur_cc_descr_attr->value.source_msg_iter_seek_beginning_method;
657 break;
658 case BT_COMPONENT_CLASS_TYPE_FILTER:
659 cc_full_descr->methods.filter.msg_iter_seek_beginning =
660 cur_cc_descr_attr->value.filter_msg_iter_seek_beginning_method;
661 break;
662 default:
663 abort();
664 }
665 break;
666 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_NS_FROM_ORIGIN_METHOD:
667 switch (cc_type) {
668 case BT_COMPONENT_CLASS_TYPE_SOURCE:
669 cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin =
670 cur_cc_descr_attr->value.source_msg_iter_can_seek_ns_from_origin_method;
671 break;
672 case BT_COMPONENT_CLASS_TYPE_FILTER:
673 cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin =
674 cur_cc_descr_attr->value.filter_msg_iter_can_seek_ns_from_origin_method;
675 break;
676 default:
677 abort();
678 }
679 break;
680 case BT_PLUGIN_COMPONENT_CLASS_DESCRIPTOR_ATTRIBUTE_TYPE_MSG_ITER_CAN_SEEK_BEGINNING_METHOD:
681 switch (cc_type) {
682 case BT_COMPONENT_CLASS_TYPE_SOURCE:
683 cc_full_descr->methods.source.msg_iter_can_seek_beginning =
684 cur_cc_descr_attr->value.source_msg_iter_can_seek_beginning_method;
685 break;
686 case BT_COMPONENT_CLASS_TYPE_FILTER:
687 cc_full_descr->methods.filter.msg_iter_can_seek_beginning =
688 cur_cc_descr_attr->value.filter_msg_iter_can_seek_beginning_method;
689 break;
690 default:
691 abort();
692 }
693 break;
d94d92ac
PP
694 default:
695 /*
696 * WARN-level logging because this
697 * should not happen with the
698 * appropriate ABI version. If we're
699 * here, we know that for the reported
700 * version of the ABI, this attribute is
701 * unknown.
702 */
703 BT_LOGW("Ignoring unknown component class descriptor attribute: "
704 "plugin-path=\"%s\", "
705 "plugin-name=\"%s\", "
706 "comp-class-name=\"%s\", "
707 "comp-class-type=%s, "
708 "attr-type-name=\"%s\", "
709 "attr-type-id=%d",
710 spec->shared_lib_handle->path ?
711 spec->shared_lib_handle->path->str :
712 NULL,
713 descriptor->name,
714 cur_cc_descr_attr->comp_class_descriptor->name,
715 bt_component_class_type_string(
716 cur_cc_descr_attr->comp_class_descriptor->type),
717 cur_cc_descr_attr->type_name,
718 cur_cc_descr_attr->type);
719 break;
55bb57e0
PP
720 }
721 }
722 }
723
724 /* Initialize plugin */
725 if (spec->init) {
a21d1cb8
PP
726 enum bt_self_plugin_status init_status;
727
3fe0bf43 728 BT_LOGD_STR("Calling user's plugin initialization function.");
a21d1cb8 729 init_status = spec->init((void *) plugin);
3fe0bf43 730 BT_LOGD("User function returned: %s",
a21d1cb8 731 bt_self_plugin_status_string(init_status));
3fe0bf43 732
9724cce9 733 if (init_status < 0) {
3fe0bf43 734 BT_LOGW_STR("User's plugin initialization function failed.");
9724cce9 735 status = BT_PLUGIN_STATUS_ERROR;
55bb57e0
PP
736 goto end;
737 }
738 }
739
c55a9f58 740 spec->shared_lib_handle->init_called = BT_TRUE;
55bb57e0
PP
741
742 /* Add described component classes to plugin */
743 for (i = 0; i < comp_class_full_descriptors->len; i++) {
744 struct comp_class_full_descriptor *cc_full_descr =
745 &g_array_index(comp_class_full_descriptors,
746 struct comp_class_full_descriptor, i);
0d72b8c3
PP
747 struct bt_component_class *comp_class = NULL;
748 struct bt_component_class_source *src_comp_class = NULL;
749 struct bt_component_class_filter *flt_comp_class = NULL;
750 struct bt_component_class_sink *sink_comp_class = NULL;
55bb57e0 751
3f7d4d90 752 BT_LOGI("Creating and setting properties of plugin's component class: "
3fe0bf43
PP
753 "plugin-path=\"%s\", plugin-name=\"%s\", "
754 "comp-class-name=\"%s\", comp-class-type=%s",
755 spec->shared_lib_handle->path ?
756 spec->shared_lib_handle->path->str :
757 NULL,
758 descriptor->name,
759 cc_full_descr->descriptor->name,
760 bt_component_class_type_string(
761 cc_full_descr->descriptor->type));
762
55bb57e0
PP
763 switch (cc_full_descr->descriptor->type) {
764 case BT_COMPONENT_CLASS_TYPE_SOURCE:
0d72b8c3 765 src_comp_class = bt_component_class_source_create(
55bb57e0 766 cc_full_descr->descriptor->name,
d6e69534 767 cc_full_descr->descriptor->methods.source.msg_iter_next);
0d72b8c3 768 comp_class = bt_component_class_source_as_component_class(
d94d92ac 769 src_comp_class);
55bb57e0
PP
770 break;
771 case BT_COMPONENT_CLASS_TYPE_FILTER:
0d72b8c3 772 flt_comp_class = bt_component_class_filter_create(
55bb57e0 773 cc_full_descr->descriptor->name,
d6e69534 774 cc_full_descr->descriptor->methods.source.msg_iter_next);
0d72b8c3 775 comp_class = bt_component_class_filter_as_component_class(
d94d92ac 776 flt_comp_class);
55bb57e0
PP
777 break;
778 case BT_COMPONENT_CLASS_TYPE_SINK:
0d72b8c3 779 sink_comp_class = bt_component_class_sink_create(
55bb57e0
PP
780 cc_full_descr->descriptor->name,
781 cc_full_descr->descriptor->methods.sink.consume);
0d72b8c3 782 comp_class = bt_component_class_sink_as_component_class(
d94d92ac 783 sink_comp_class);
55bb57e0
PP
784 break;
785 default:
50ad9320
PP
786 /*
787 * WARN-level logging because this should not
788 * happen with the appropriate ABI version. If
789 * we're here, we know that for the reported
790 * version of the ABI, this component class type
791 * is unknown.
792 */
3fe0bf43
PP
793 BT_LOGW("Ignoring unknown component class type: "
794 "plugin-path=\"%s\", plugin-name=\"%s\", "
795 "comp-class-name=\"%s\", comp-class-type=%d",
796 spec->shared_lib_handle->path->str ?
797 spec->shared_lib_handle->path->str :
798 NULL,
799 descriptor->name,
55bb57e0 800 cc_full_descr->descriptor->name,
3fe0bf43 801 cc_full_descr->descriptor->type);
55bb57e0
PP
802 continue;
803 }
804
805 if (!comp_class) {
3fe0bf43 806 BT_LOGE_STR("Cannot create component class.");
55bb57e0
PP
807 status = BT_PLUGIN_STATUS_ERROR;
808 goto end;
809 }
810
811 if (cc_full_descr->description) {
0d72b8c3 812 ret = bt_component_class_set_description(
d94d92ac 813 comp_class, cc_full_descr->description);
55bb57e0 814 if (ret) {
3fe0bf43 815 BT_LOGE_STR("Cannot set component class's description.");
55bb57e0 816 status = BT_PLUGIN_STATUS_ERROR;
65300d60 817 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
55bb57e0
PP
818 goto end;
819 }
820 }
821
279b3f15 822 if (cc_full_descr->help) {
0d72b8c3 823 ret = bt_component_class_set_help(comp_class,
279b3f15
PP
824 cc_full_descr->help);
825 if (ret) {
3fe0bf43 826 BT_LOGE_STR("Cannot set component class's help string.");
279b3f15 827 status = BT_PLUGIN_STATUS_ERROR;
65300d60 828 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
279b3f15
PP
829 goto end;
830 }
831 }
832
d94d92ac
PP
833 switch (cc_full_descr->descriptor->type) {
834 case BT_COMPONENT_CLASS_TYPE_SOURCE:
835 if (cc_full_descr->methods.source.init) {
0d72b8c3 836 ret = bt_component_class_source_set_init_method(
d94d92ac
PP
837 src_comp_class,
838 cc_full_descr->methods.source.init);
839 if (ret) {
840 BT_LOGE_STR("Cannot set source component class's initialization method.");
841 status = BT_PLUGIN_STATUS_ERROR;
842 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
843 goto end;
844 }
55bb57e0 845 }
55bb57e0 846
d94d92ac 847 if (cc_full_descr->methods.source.finalize) {
0d72b8c3 848 ret = bt_component_class_source_set_finalize_method(
d94d92ac
PP
849 src_comp_class,
850 cc_full_descr->methods.source.finalize);
851 if (ret) {
852 BT_LOGE_STR("Cannot set source component class's finalization method.");
853 status = BT_PLUGIN_STATUS_ERROR;
854 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
855 goto end;
856 }
55bb57e0 857 }
55bb57e0 858
d94d92ac 859 if (cc_full_descr->methods.source.query) {
0d72b8c3 860 ret = bt_component_class_source_set_query_method(
d94d92ac
PP
861 src_comp_class,
862 cc_full_descr->methods.source.query);
863 if (ret) {
864 BT_LOGE_STR("Cannot set source component class's query method.");
865 status = BT_PLUGIN_STATUS_ERROR;
866 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
867 goto end;
868 }
8463eac2 869 }
8463eac2 870
d94d92ac 871 if (cc_full_descr->methods.source.accept_output_port_connection) {
0d72b8c3 872 ret = bt_component_class_source_set_accept_output_port_connection_method(
d94d92ac
PP
873 src_comp_class,
874 cc_full_descr->methods.source.accept_output_port_connection);
875 if (ret) {
876 BT_LOGE_STR("Cannot set source component class's \"accept input output connection\" method.");
877 status = BT_PLUGIN_STATUS_ERROR;
878 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
879 goto end;
880 }
72b913fb 881 }
72b913fb 882
d94d92ac 883 if (cc_full_descr->methods.source.output_port_connected) {
0d72b8c3 884 ret = bt_component_class_source_set_output_port_connected_method(
d94d92ac
PP
885 src_comp_class,
886 cc_full_descr->methods.source.output_port_connected);
887 if (ret) {
888 BT_LOGE_STR("Cannot set source component class's \"output port connected\" method.");
889 status = BT_PLUGIN_STATUS_ERROR;
890 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
891 goto end;
892 }
0d8b4d8e 893 }
0d8b4d8e 894
d6e69534
PP
895 if (cc_full_descr->methods.source.msg_iter_init) {
896 ret = bt_component_class_source_set_message_iterator_init_method(
d94d92ac 897 src_comp_class,
d6e69534 898 cc_full_descr->methods.source.msg_iter_init);
55bb57e0 899 if (ret) {
d6e69534 900 BT_LOGE_STR("Cannot set source component class's message iterator initialization method.");
55bb57e0 901 status = BT_PLUGIN_STATUS_ERROR;
d94d92ac 902 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
55bb57e0
PP
903 goto end;
904 }
905 }
906
d6e69534
PP
907 if (cc_full_descr->methods.source.msg_iter_finalize) {
908 ret = bt_component_class_source_set_message_iterator_finalize_method(
d94d92ac 909 src_comp_class,
d6e69534 910 cc_full_descr->methods.source.msg_iter_finalize);
55bb57e0 911 if (ret) {
d6e69534 912 BT_LOGE_STR("Cannot set source component class's message iterator finalization method.");
55bb57e0 913 status = BT_PLUGIN_STATUS_ERROR;
d94d92ac 914 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
55bb57e0
PP
915 goto end;
916 }
917 }
d94d92ac 918
7474e7d3
PP
919 if (cc_full_descr->methods.source.msg_iter_seek_ns_from_origin) {
920 ret = bt_component_class_source_set_message_iterator_seek_ns_from_origin_method(
921 src_comp_class,
922 cc_full_descr->methods.source.msg_iter_seek_ns_from_origin);
923 if (ret) {
924 BT_LOGE_STR("Cannot set source component class's message iterator \"seek nanoseconds from origin\" method.");
925 status = BT_PLUGIN_STATUS_ERROR;
926 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
927 goto end;
928 }
929 }
930
931 if (cc_full_descr->methods.source.msg_iter_seek_beginning) {
932 ret = bt_component_class_source_set_message_iterator_seek_beginning_method(
933 src_comp_class,
934 cc_full_descr->methods.source.msg_iter_seek_beginning);
935 if (ret) {
936 BT_LOGE_STR("Cannot set source component class's message iterator \"seek beginning\" method.");
937 status = BT_PLUGIN_STATUS_ERROR;
938 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
939 goto end;
940 }
941 }
942
943 if (cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin) {
944 ret = bt_component_class_source_set_message_iterator_can_seek_ns_from_origin_method(
945 src_comp_class,
946 cc_full_descr->methods.source.msg_iter_can_seek_ns_from_origin);
947 if (ret) {
948 BT_LOGE_STR("Cannot set source component class's message iterator \"can seek nanoseconds from origin\" method.");
949 status = BT_PLUGIN_STATUS_ERROR;
950 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
951 goto end;
952 }
953 }
954
955 if (cc_full_descr->methods.source.msg_iter_can_seek_beginning) {
956 ret = bt_component_class_source_set_message_iterator_can_seek_beginning_method(
957 src_comp_class,
958 cc_full_descr->methods.source.msg_iter_can_seek_beginning);
959 if (ret) {
960 BT_LOGE_STR("Cannot set source component class's message iterator \"can seek beginning\" method.");
961 status = BT_PLUGIN_STATUS_ERROR;
962 BT_OBJECT_PUT_REF_AND_RESET(src_comp_class);
963 goto end;
964 }
965 }
966
55bb57e0
PP
967 break;
968 case BT_COMPONENT_CLASS_TYPE_FILTER:
d94d92ac 969 if (cc_full_descr->methods.filter.init) {
0d72b8c3 970 ret = bt_component_class_filter_set_init_method(
d94d92ac
PP
971 flt_comp_class,
972 cc_full_descr->methods.filter.init);
973 if (ret) {
974 BT_LOGE_STR("Cannot set filter component class's initialization method.");
975 status = BT_PLUGIN_STATUS_ERROR;
976 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
977 goto end;
978 }
979 }
980
981 if (cc_full_descr->methods.filter.finalize) {
0d72b8c3 982 ret = bt_component_class_filter_set_finalize_method(
d94d92ac
PP
983 flt_comp_class,
984 cc_full_descr->methods.filter.finalize);
985 if (ret) {
986 BT_LOGE_STR("Cannot set filter component class's finalization method.");
987 status = BT_PLUGIN_STATUS_ERROR;
988 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
989 goto end;
990 }
991 }
992
993 if (cc_full_descr->methods.filter.query) {
0d72b8c3 994 ret = bt_component_class_filter_set_query_method(
d94d92ac
PP
995 flt_comp_class,
996 cc_full_descr->methods.filter.query);
997 if (ret) {
998 BT_LOGE_STR("Cannot set filter component class's query method.");
999 status = BT_PLUGIN_STATUS_ERROR;
1000 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1001 goto end;
1002 }
1003 }
1004
1005 if (cc_full_descr->methods.filter.accept_input_port_connection) {
0d72b8c3 1006 ret = bt_component_class_filter_set_accept_input_port_connection_method(
d94d92ac
PP
1007 flt_comp_class,
1008 cc_full_descr->methods.filter.accept_input_port_connection);
1009 if (ret) {
1010 BT_LOGE_STR("Cannot set filter component class's \"accept input port connection\" method.");
1011 status = BT_PLUGIN_STATUS_ERROR;
1012 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1013 goto end;
1014 }
1015 }
1016
1017 if (cc_full_descr->methods.filter.accept_output_port_connection) {
0d72b8c3 1018 ret = bt_component_class_filter_set_accept_output_port_connection_method(
d94d92ac
PP
1019 flt_comp_class,
1020 cc_full_descr->methods.filter.accept_output_port_connection);
1021 if (ret) {
1022 BT_LOGE_STR("Cannot set filter component class's \"accept input output connection\" method.");
1023 status = BT_PLUGIN_STATUS_ERROR;
1024 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1025 goto end;
1026 }
1027 }
1028
1029 if (cc_full_descr->methods.filter.input_port_connected) {
0d72b8c3 1030 ret = bt_component_class_filter_set_input_port_connected_method(
d94d92ac
PP
1031 flt_comp_class,
1032 cc_full_descr->methods.filter.input_port_connected);
1033 if (ret) {
1034 BT_LOGE_STR("Cannot set filter component class's \"input port connected\" method.");
1035 status = BT_PLUGIN_STATUS_ERROR;
1036 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1037 goto end;
1038 }
1039 }
1040
1041 if (cc_full_descr->methods.filter.output_port_connected) {
0d72b8c3 1042 ret = bt_component_class_filter_set_output_port_connected_method(
d94d92ac
PP
1043 flt_comp_class,
1044 cc_full_descr->methods.filter.output_port_connected);
1045 if (ret) {
1046 BT_LOGE_STR("Cannot set filter component class's \"output port connected\" method.");
1047 status = BT_PLUGIN_STATUS_ERROR;
1048 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1049 goto end;
1050 }
1051 }
1052
d6e69534
PP
1053 if (cc_full_descr->methods.filter.msg_iter_init) {
1054 ret = bt_component_class_filter_set_message_iterator_init_method(
d94d92ac 1055 flt_comp_class,
d6e69534 1056 cc_full_descr->methods.filter.msg_iter_init);
55bb57e0 1057 if (ret) {
d6e69534 1058 BT_LOGE_STR("Cannot set filter component class's message iterator initialization method.");
55bb57e0 1059 status = BT_PLUGIN_STATUS_ERROR;
d94d92ac 1060 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
55bb57e0
PP
1061 goto end;
1062 }
1063 }
1064
d6e69534
PP
1065 if (cc_full_descr->methods.filter.msg_iter_finalize) {
1066 ret = bt_component_class_filter_set_message_iterator_finalize_method(
d94d92ac 1067 flt_comp_class,
d6e69534 1068 cc_full_descr->methods.filter.msg_iter_finalize);
55bb57e0 1069 if (ret) {
d6e69534 1070 BT_LOGE_STR("Cannot set filter component class's message iterator finalization method.");
55bb57e0 1071 status = BT_PLUGIN_STATUS_ERROR;
d94d92ac 1072 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
55bb57e0
PP
1073 goto end;
1074 }
1075 }
d94d92ac 1076
7474e7d3
PP
1077 if (cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin) {
1078 ret = bt_component_class_filter_set_message_iterator_seek_ns_from_origin_method(
1079 flt_comp_class,
1080 cc_full_descr->methods.filter.msg_iter_seek_ns_from_origin);
1081 if (ret) {
1082 BT_LOGE_STR("Cannot set filter component class's message iterator \"seek nanoseconds from origin\" method.");
1083 status = BT_PLUGIN_STATUS_ERROR;
1084 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1085 goto end;
1086 }
1087 }
1088
1089 if (cc_full_descr->methods.filter.msg_iter_seek_beginning) {
1090 ret = bt_component_class_filter_set_message_iterator_seek_beginning_method(
1091 flt_comp_class,
1092 cc_full_descr->methods.filter.msg_iter_seek_beginning);
1093 if (ret) {
1094 BT_LOGE_STR("Cannot set filter component class's message iterator \"seek beginning\" method.");
1095 status = BT_PLUGIN_STATUS_ERROR;
1096 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1097 goto end;
1098 }
1099 }
1100
1101 if (cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin) {
1102 ret = bt_component_class_filter_set_message_iterator_can_seek_ns_from_origin_method(
1103 flt_comp_class,
1104 cc_full_descr->methods.filter.msg_iter_can_seek_ns_from_origin);
1105 if (ret) {
1106 BT_LOGE_STR("Cannot set filter component class's message iterator \"can seek nanoseconds from origin\" method.");
1107 status = BT_PLUGIN_STATUS_ERROR;
1108 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1109 goto end;
1110 }
1111 }
1112
1113 if (cc_full_descr->methods.filter.msg_iter_can_seek_beginning) {
1114 ret = bt_component_class_filter_set_message_iterator_can_seek_beginning_method(
1115 flt_comp_class,
1116 cc_full_descr->methods.filter.msg_iter_can_seek_beginning);
1117 if (ret) {
1118 BT_LOGE_STR("Cannot set filter component class's message iterator \"can seek beginning\" method.");
1119 status = BT_PLUGIN_STATUS_ERROR;
1120 BT_OBJECT_PUT_REF_AND_RESET(flt_comp_class);
1121 goto end;
1122 }
1123 }
1124
55bb57e0
PP
1125 break;
1126 case BT_COMPONENT_CLASS_TYPE_SINK:
d94d92ac 1127 if (cc_full_descr->methods.sink.init) {
0d72b8c3 1128 ret = bt_component_class_sink_set_init_method(
d94d92ac
PP
1129 sink_comp_class,
1130 cc_full_descr->methods.sink.init);
1131 if (ret) {
1132 BT_LOGE_STR("Cannot set sink component class's initialization method.");
1133 status = BT_PLUGIN_STATUS_ERROR;
1134 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1135 goto end;
1136 }
1137 }
1138
1139 if (cc_full_descr->methods.sink.finalize) {
0d72b8c3 1140 ret = bt_component_class_sink_set_finalize_method(
d94d92ac
PP
1141 sink_comp_class,
1142 cc_full_descr->methods.sink.finalize);
1143 if (ret) {
1144 BT_LOGE_STR("Cannot set sink component class's finalization method.");
1145 status = BT_PLUGIN_STATUS_ERROR;
1146 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1147 goto end;
1148 }
1149 }
1150
1151 if (cc_full_descr->methods.sink.query) {
0d72b8c3 1152 ret = bt_component_class_sink_set_query_method(
d94d92ac
PP
1153 sink_comp_class,
1154 cc_full_descr->methods.sink.query);
1155 if (ret) {
1156 BT_LOGE_STR("Cannot set sink component class's query method.");
1157 status = BT_PLUGIN_STATUS_ERROR;
1158 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1159 goto end;
1160 }
1161 }
1162
1163 if (cc_full_descr->methods.sink.accept_input_port_connection) {
0d72b8c3 1164 ret = bt_component_class_sink_set_accept_input_port_connection_method(
d94d92ac
PP
1165 sink_comp_class,
1166 cc_full_descr->methods.sink.accept_input_port_connection);
1167 if (ret) {
1168 BT_LOGE_STR("Cannot set sink component class's \"accept input port connection\" method.");
1169 status = BT_PLUGIN_STATUS_ERROR;
1170 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1171 goto end;
1172 }
1173 }
1174
1175 if (cc_full_descr->methods.sink.input_port_connected) {
0d72b8c3 1176 ret = bt_component_class_sink_set_input_port_connected_method(
d94d92ac
PP
1177 sink_comp_class,
1178 cc_full_descr->methods.sink.input_port_connected);
1179 if (ret) {
1180 BT_LOGE_STR("Cannot set sink component class's \"input port connected\" method.");
1181 status = BT_PLUGIN_STATUS_ERROR;
1182 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1183 goto end;
1184 }
1185 }
1186
5badd463
PP
1187 if (cc_full_descr->methods.sink.graph_is_configured) {
1188 ret = bt_component_class_sink_set_graph_is_configured_method(
1189 sink_comp_class,
1190 cc_full_descr->methods.sink.graph_is_configured);
1191 if (ret) {
1192 BT_LOGE_STR("Cannot set sink component class's \"graph is configured\" method.");
1193 status = BT_PLUGIN_STATUS_ERROR;
1194 BT_OBJECT_PUT_REF_AND_RESET(sink_comp_class);
1195 goto end;
1196 }
1197 }
1198
55bb57e0
PP
1199 break;
1200 default:
0fbb9a9f 1201 abort();
55bb57e0
PP
1202 }
1203
1204 /*
1205 * Add component class to the plugin object.
1206 *
1207 * This will call back
1208 * bt_plugin_so_on_add_component_class() so that we can
d94d92ac
PP
1209 * add a mapping in the component class list when we
1210 * know the component class is successfully added.
55bb57e0
PP
1211 */
1212 status = bt_plugin_add_component_class(plugin,
d94d92ac 1213 (void *) comp_class);
65300d60 1214 BT_OBJECT_PUT_REF_AND_RESET(comp_class);
55bb57e0 1215 if (status < 0) {
3fe0bf43 1216 BT_LOGE("Cannot add component class to plugin.");
55bb57e0
PP
1217 goto end;
1218 }
1219 }
1220
55bb57e0
PP
1221end:
1222 g_array_free(comp_class_full_descriptors, TRUE);
1223 return status;
1224}
1225
1226static
1227struct bt_plugin *bt_plugin_so_create_empty(
1228 struct bt_plugin_so_shared_lib_handle *shared_lib_handle)
1229{
1230 struct bt_plugin *plugin;
1231 struct bt_plugin_so_spec_data *spec;
1232
1233 plugin = bt_plugin_create_empty(BT_PLUGIN_TYPE_SO);
1234 if (!plugin) {
1235 goto error;
1236 }
1237
6fbd4105 1238 plugin->destroy_spec_data = bt_plugin_so_destroy_spec_data;
55bb57e0
PP
1239 plugin->spec_data = g_new0(struct bt_plugin_so_spec_data, 1);
1240 if (!plugin->spec_data) {
3fe0bf43 1241 BT_LOGE_STR("Failed to allocate one SO plugin specific data structure.");
55bb57e0
PP
1242 goto error;
1243 }
1244
1245 spec = plugin->spec_data;
398454ed
PP
1246 spec->shared_lib_handle = shared_lib_handle;
1247 bt_object_get_no_null_check(spec->shared_lib_handle);
55bb57e0
PP
1248 goto end;
1249
1250error:
65300d60 1251 BT_OBJECT_PUT_REF_AND_RESET(plugin);
55bb57e0
PP
1252
1253end:
1254 return plugin;
1255}
1256
52238017
MJ
1257static
1258size_t count_non_null_items_in_section(const void *begin, const void *end)
1259{
1260 size_t count = 0;
1261 const int * const *begin_int = (const int * const *) begin;
1262 const int * const *end_int = (const int * const *) end;
1263 const int * const *iter;
1264
1265 for (iter = begin_int; iter != end_int; iter++) {
1266 if (*iter) {
1267 count++;
1268 }
1269 }
1270
1271 return count;
1272}
1273
55bb57e0 1274static
a8ff38ef 1275struct bt_plugin_set *bt_plugin_so_create_all_from_sections(
55bb57e0
PP
1276 struct bt_plugin_so_shared_lib_handle *shared_lib_handle,
1277 struct __bt_plugin_descriptor const * const *descriptors_begin,
1278 struct __bt_plugin_descriptor const * const *descriptors_end,
1279 struct __bt_plugin_descriptor_attribute const * const *attrs_begin,
1280 struct __bt_plugin_descriptor_attribute const * const *attrs_end,
1281 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin,
1282 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end,
1283 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin,
1284 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end)
1285{
1286 size_t descriptor_count;
1287 size_t attrs_count;
1288 size_t cc_descriptors_count;
1289 size_t cc_descr_attrs_count;
1290 size_t i;
a8ff38ef 1291 struct bt_plugin_set *plugin_set = NULL;
55bb57e0 1292
52238017
MJ
1293 descriptor_count = count_non_null_items_in_section(descriptors_begin, descriptors_end);
1294 attrs_count = count_non_null_items_in_section(attrs_begin, attrs_end);
1295 cc_descriptors_count = count_non_null_items_in_section(cc_descriptors_begin, cc_descriptors_end);
1296 cc_descr_attrs_count = count_non_null_items_in_section(cc_descr_attrs_begin, cc_descr_attrs_end);
3fe0bf43 1297
3f7d4d90 1298 BT_LOGI("Creating all SO plugins from sections: "
3fe0bf43
PP
1299 "plugin-path=\"%s\", "
1300 "descr-begin-addr=%p, descr-end-addr=%p, "
1301 "attrs-begin-addr=%p, attrs-end-addr=%p, "
1302 "cc-descr-begin-addr=%p, cc-descr-end-addr=%p, "
1303 "cc-descr-attrs-begin-addr=%p, cc-descr-attrs-end-addr=%p, "
1304 "descr-count=%zu, attrs-count=%zu, "
1305 "cc-descr-count=%zu, cc-descr-attrs-count=%zu",
1306 shared_lib_handle->path ? shared_lib_handle->path->str : NULL,
1307 descriptors_begin, descriptors_end,
1308 attrs_begin, attrs_end,
1309 cc_descriptors_begin, cc_descriptors_end,
1310 cc_descr_attrs_begin, cc_descr_attrs_end,
1311 descriptor_count, attrs_count,
1312 cc_descriptors_count, cc_descr_attrs_count);
a8ff38ef
PP
1313 plugin_set = bt_plugin_set_create();
1314 if (!plugin_set) {
3fe0bf43 1315 BT_LOGE_STR("Cannot create empty plugin set.");
55bb57e0
PP
1316 goto error;
1317 }
1318
52238017 1319 for (i = 0; i < descriptors_end - descriptors_begin; i++) {
55bb57e0
PP
1320 enum bt_plugin_status status;
1321 const struct __bt_plugin_descriptor *descriptor =
1322 descriptors_begin[i];
1323 struct bt_plugin *plugin;
1324
52238017
MJ
1325 if (descriptor == NULL) {
1326 continue;
1327 }
1328
3f7d4d90 1329 BT_LOGI("Creating plugin object for plugin: "
3fe0bf43
PP
1330 "name=\"%s\", abi-major=%d, abi-minor=%d",
1331 descriptor->name, descriptor->major, descriptor->minor);
55bb57e0
PP
1332
1333 if (descriptor->major > __BT_PLUGIN_VERSION_MAJOR) {
50ad9320 1334 /*
3f7d4d90 1335 * INFO-level logging because we're only
50ad9320
PP
1336 * _trying_ to open this file as a compatible
1337 * Babeltrace plugin: if it's not, it's not an
1338 * error. And because this can be tried during
3f7d4d90
PP
1339 * bt_plugin_find_all_from_dir(), it's not even
1340 * a warning.
50ad9320 1341 */
3f7d4d90 1342 BT_LOGI("Unknown ABI major version: abi-major=%d",
55bb57e0
PP
1343 descriptor->major);
1344 goto error;
1345 }
1346
1347 plugin = bt_plugin_so_create_empty(shared_lib_handle);
1348 if (!plugin) {
3fe0bf43 1349 BT_LOGE_STR("Cannot create empty shared library handle.");
55bb57e0
PP
1350 goto error;
1351 }
1352
1353 if (shared_lib_handle && shared_lib_handle->path) {
1354 bt_plugin_set_path(plugin, shared_lib_handle->path->str);
1355 }
1356
1357 status = bt_plugin_so_init(plugin, descriptor, attrs_begin,
1358 attrs_end, cc_descriptors_begin, cc_descriptors_end,
1359 cc_descr_attrs_begin, cc_descr_attrs_end);
1360 if (status < 0) {
50ad9320
PP
1361 /*
1362 * DEBUG-level logging because we're only
1363 * _trying_ to open this file as a compatible
1364 * Babeltrace plugin: if it's not, it's not an
1365 * error. And because this can be tried during
c8db3219 1366 * bt_plugin_find_all_from_dir(), it's not
50ad9320
PP
1367 * even a warning.
1368 */
1369 BT_LOGD_STR("Cannot initialize SO plugin object from sections.");
65300d60 1370 BT_OBJECT_PUT_REF_AND_RESET(plugin);
55bb57e0
PP
1371 goto error;
1372 }
1373
a8ff38ef
PP
1374 /* Add to plugin set */
1375 bt_plugin_set_add_plugin(plugin_set, plugin);
65300d60 1376 bt_object_put_ref(plugin);
55bb57e0
PP
1377 }
1378
1379 goto end;
1380
1381error:
65300d60 1382 BT_OBJECT_PUT_REF_AND_RESET(plugin_set);
55bb57e0
PP
1383
1384end:
a8ff38ef 1385 return plugin_set;
55bb57e0
PP
1386}
1387
1388BT_HIDDEN
a8ff38ef 1389struct bt_plugin_set *bt_plugin_so_create_all_from_static(void)
55bb57e0 1390{
a8ff38ef 1391 struct bt_plugin_set *plugin_set = NULL;
55bb57e0
PP
1392 struct bt_plugin_so_shared_lib_handle *shared_lib_handle =
1393 bt_plugin_so_shared_lib_handle_create(NULL);
1394
1395 if (!shared_lib_handle) {
1396 goto end;
1397 }
1398
3fe0bf43 1399 BT_LOGD_STR("Creating all SO plugins from built-in plugins.");
a8ff38ef 1400 plugin_set = bt_plugin_so_create_all_from_sections(shared_lib_handle,
52238017
MJ
1401 __bt_get_begin_section_plugin_descriptors(),
1402 __bt_get_end_section_plugin_descriptors(),
1403 __bt_get_begin_section_plugin_descriptor_attributes(),
1404 __bt_get_end_section_plugin_descriptor_attributes(),
1405 __bt_get_begin_section_component_class_descriptors(),
1406 __bt_get_end_section_component_class_descriptors(),
1407 __bt_get_begin_section_component_class_descriptor_attributes(),
1408 __bt_get_end_section_component_class_descriptor_attributes());
55bb57e0
PP
1409
1410end:
65300d60 1411 BT_OBJECT_PUT_REF_AND_RESET(shared_lib_handle);
55bb57e0 1412
a8ff38ef 1413 return plugin_set;
55bb57e0
PP
1414}
1415
1416BT_HIDDEN
a8ff38ef 1417struct bt_plugin_set *bt_plugin_so_create_all_from_file(const char *path)
55bb57e0
PP
1418{
1419 size_t path_len;
a8ff38ef 1420 struct bt_plugin_set *plugin_set = NULL;
55bb57e0
PP
1421 struct __bt_plugin_descriptor const * const *descriptors_begin = NULL;
1422 struct __bt_plugin_descriptor const * const *descriptors_end = NULL;
1423 struct __bt_plugin_descriptor_attribute const * const *attrs_begin = NULL;
1424 struct __bt_plugin_descriptor_attribute const * const *attrs_end = NULL;
1425 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_begin = NULL;
1426 struct __bt_plugin_component_class_descriptor const * const *cc_descriptors_end = NULL;
1427 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_begin = NULL;
1428 struct __bt_plugin_component_class_descriptor_attribute const * const *cc_descr_attrs_end = NULL;
52238017
MJ
1429 struct __bt_plugin_descriptor const * const *(*get_begin_section_plugin_descriptors)(void);
1430 struct __bt_plugin_descriptor const * const *(*get_end_section_plugin_descriptors)(void);
1431 struct __bt_plugin_descriptor_attribute const * const *(*get_begin_section_plugin_descriptor_attributes)(void);
1432 struct __bt_plugin_descriptor_attribute const * const *(*get_end_section_plugin_descriptor_attributes)(void);
1433 struct __bt_plugin_component_class_descriptor const * const *(*get_begin_section_component_class_descriptors)(void);
1434 struct __bt_plugin_component_class_descriptor const * const *(*get_end_section_component_class_descriptors)(void);
1435 struct __bt_plugin_component_class_descriptor_attribute const * const *(*get_begin_section_component_class_descriptor_attributes)(void);
1436 struct __bt_plugin_component_class_descriptor_attribute const * const *(*get_end_section_component_class_descriptor_attributes)(void);
c55a9f58 1437 bt_bool is_libtool_wrapper = BT_FALSE, is_shared_object = BT_FALSE;
55bb57e0
PP
1438 struct bt_plugin_so_shared_lib_handle *shared_lib_handle = NULL;
1439
3f7d4d90 1440 BT_ASSERT(path);
55bb57e0 1441 path_len = strlen(path);
3f7d4d90
PP
1442 BT_ASSERT_PRE(path_len > PLUGIN_SUFFIX_LEN,
1443 "Path length is too short: path-length=%zu, min-length=%zu",
1444 path_len, PLUGIN_SUFFIX_LEN);
1445 BT_LOGI("Trying to create all SO plugins from file: path=\"%s\"", path);
55bb57e0 1446 path_len++;
3f7d4d90 1447
55bb57e0 1448 /*
3f7d4d90
PP
1449 * Check if the file ends with a known plugin file type suffix
1450 * (i.e. .so or .la on Linux).
55bb57e0
PP
1451 */
1452 is_libtool_wrapper = !strncmp(LIBTOOL_PLUGIN_SUFFIX,
1453 path + path_len - LIBTOOL_PLUGIN_SUFFIX_LEN,
1454 LIBTOOL_PLUGIN_SUFFIX_LEN);
1455 is_shared_object = !strncmp(NATIVE_PLUGIN_SUFFIX,
1456 path + path_len - NATIVE_PLUGIN_SUFFIX_LEN,
1457 NATIVE_PLUGIN_SUFFIX_LEN);
1458 if (!is_shared_object && !is_libtool_wrapper) {
3fe0bf43 1459 /* Name indicates this is not a plugin file; not an error */
3f7d4d90 1460 BT_LOGI("File is not a SO plugin file: path=\"%s\"", path);
55bb57e0
PP
1461 goto end;
1462 }
1463
1464 shared_lib_handle = bt_plugin_so_shared_lib_handle_create(path);
1465 if (!shared_lib_handle) {
3f7d4d90 1466 /* bt_plugin_so_shared_lib_handle_create() logs more details */
50ad9320 1467 BT_LOGD_STR("Cannot create shared library handle.");
55bb57e0
PP
1468 goto end;
1469 }
1470
52238017
MJ
1471 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_plugin_descriptors",
1472 (gpointer *) &get_begin_section_plugin_descriptors)) {
1473 descriptors_begin = get_begin_section_plugin_descriptors();
1474 } else {
3f7d4d90 1475 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1476 "symbol=\"%s\"", path,
52238017 1477 "__bt_get_begin_section_plugin_descriptors");
55bb57e0
PP
1478 goto end;
1479 }
1480
52238017
MJ
1481 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_plugin_descriptors",
1482 (gpointer *) &get_end_section_plugin_descriptors)) {
1483 descriptors_end = get_end_section_plugin_descriptors();
1484 } else {
3f7d4d90 1485 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1486 "symbol=\"%s\"", path,
52238017 1487 "__bt_get_end_section_plugin_descriptors");
55bb57e0
PP
1488 goto end;
1489 }
1490
52238017
MJ
1491 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_plugin_descriptor_attributes",
1492 (gpointer *) &get_begin_section_plugin_descriptor_attributes)) {
1493 attrs_begin = get_begin_section_plugin_descriptor_attributes();
1494 } else {
3f7d4d90 1495 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1496 "symbol=\"%s\"", path,
52238017 1497 "__bt_get_begin_section_plugin_descriptor_attributes");
55bb57e0
PP
1498 }
1499
52238017
MJ
1500 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_plugin_descriptor_attributes",
1501 (gpointer *) &get_end_section_plugin_descriptor_attributes)) {
1502 attrs_end = get_end_section_plugin_descriptor_attributes();
1503 } else {
3f7d4d90 1504 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1505 "symbol=\"%s\"", path,
52238017 1506 "__bt_get_end_section_plugin_descriptor_attributes");
55bb57e0
PP
1507 }
1508
1509 if ((!!attrs_begin - !!attrs_end) != 0) {
3f7d4d90 1510 BT_LOGI("Found section start or end symbol, but not both: "
3fe0bf43
PP
1511 "path=\"%s\", symbol-start=\"%s\", "
1512 "symbol-end=\"%s\", symbol-start-addr=%p, "
1513 "symbol-end-addr=%p",
52238017
MJ
1514 path, "__bt_get_begin_section_plugin_descriptor_attributes",
1515 "__bt_get_end_section_plugin_descriptor_attributes",
3fe0bf43 1516 attrs_begin, attrs_end);
55bb57e0
PP
1517 goto end;
1518 }
1519
52238017
MJ
1520 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_component_class_descriptors",
1521 (gpointer *) &get_begin_section_component_class_descriptors)) {
1522 cc_descriptors_begin = get_begin_section_component_class_descriptors();
1523 } else {
3f7d4d90 1524 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1525 "symbol=\"%s\"", path,
52238017 1526 "__bt_get_begin_section_component_class_descriptors");
55bb57e0
PP
1527 }
1528
52238017
MJ
1529 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_component_class_descriptors",
1530 (gpointer *) &get_end_section_component_class_descriptors)) {
1531 cc_descriptors_end = get_end_section_component_class_descriptors();
1532 } else {
3f7d4d90 1533 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1534 "symbol=\"%s\"", path,
52238017 1535 "__bt_get_end_section_component_class_descriptors");
55bb57e0
PP
1536 }
1537
1538 if ((!!cc_descriptors_begin - !!cc_descriptors_end) != 0) {
3f7d4d90 1539 BT_LOGI("Found section start or end symbol, but not both: "
3fe0bf43
PP
1540 "path=\"%s\", symbol-start=\"%s\", "
1541 "symbol-end=\"%s\", symbol-start-addr=%p, "
1542 "symbol-end-addr=%p",
52238017
MJ
1543 path, "__bt_get_begin_section_component_class_descriptors",
1544 "__bt_get_end_section_component_class_descriptors",
3fe0bf43 1545 cc_descriptors_begin, cc_descriptors_end);
55bb57e0
PP
1546 goto end;
1547 }
1548
52238017
MJ
1549 if (g_module_symbol(shared_lib_handle->module, "__bt_get_begin_section_component_class_descriptor_attributes",
1550 (gpointer *) &get_begin_section_component_class_descriptor_attributes)) {
1551 cc_descr_attrs_begin = get_begin_section_component_class_descriptor_attributes();
1552 } else {
3f7d4d90 1553 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1554 "symbol=\"%s\"", path,
52238017 1555 "__bt_get_begin_section_component_class_descriptor_attributes");
55bb57e0
PP
1556 }
1557
52238017
MJ
1558 if (g_module_symbol(shared_lib_handle->module, "__bt_get_end_section_component_class_descriptor_attributes",
1559 (gpointer *) &get_end_section_component_class_descriptor_attributes)) {
1560 cc_descr_attrs_end = get_end_section_component_class_descriptor_attributes();
1561 } else {
3f7d4d90 1562 BT_LOGI("Cannot resolve plugin symbol: path=\"%s\", "
3fe0bf43 1563 "symbol=\"%s\"", path,
52238017 1564 "__bt_get_end_section_component_class_descriptor_attributes");
55bb57e0
PP
1565 }
1566
1567 if ((!!cc_descr_attrs_begin - !!cc_descr_attrs_end) != 0) {
3f7d4d90 1568 BT_LOGI("Found section start or end symbol, but not both: "
3fe0bf43
PP
1569 "path=\"%s\", symbol-start=\"%s\", "
1570 "symbol-end=\"%s\", symbol-start-addr=%p, "
1571 "symbol-end-addr=%p",
52238017
MJ
1572 path, "__bt_get_begin_section_component_class_descriptor_attributes",
1573 "__bt_get_end_section_component_class_descriptor_attributes",
3fe0bf43 1574 cc_descr_attrs_begin, cc_descr_attrs_end);
55bb57e0
PP
1575 goto end;
1576 }
1577
1578 /* Initialize plugin */
3fe0bf43 1579 BT_LOGD_STR("Initializing plugin object.");
a8ff38ef 1580 plugin_set = bt_plugin_so_create_all_from_sections(shared_lib_handle,
55bb57e0
PP
1581 descriptors_begin, descriptors_end, attrs_begin, attrs_end,
1582 cc_descriptors_begin, cc_descriptors_end,
1583 cc_descr_attrs_begin, cc_descr_attrs_end);
1584
1585end:
65300d60 1586 BT_OBJECT_PUT_REF_AND_RESET(shared_lib_handle);
a8ff38ef 1587 return plugin_set;
55bb57e0
PP
1588}
1589
1590static
1591void plugin_comp_class_destroy_listener(struct bt_component_class *comp_class,
1592 void *data)
1593{
bfa9a4be 1594 bt_list_del(&comp_class->node);
65300d60 1595 BT_OBJECT_PUT_REF_AND_RESET(comp_class->so_handle);
3f7d4d90 1596 BT_LOGD("Component class destroyed: removed entry from list: "
3fe0bf43 1597 "comp-cls-addr=%p", comp_class);
55bb57e0
PP
1598}
1599
3230ee6b 1600void bt_plugin_so_on_add_component_class(struct bt_plugin *plugin,
55bb57e0
PP
1601 struct bt_component_class *comp_class)
1602{
55bb57e0
PP
1603 struct bt_plugin_so_spec_data *spec = plugin->spec_data;
1604
f6ccaed9
PP
1605 BT_ASSERT(plugin->spec_data);
1606 BT_ASSERT(plugin->type == BT_PLUGIN_TYPE_SO);
55bb57e0 1607
bfa9a4be 1608 bt_list_add(&comp_class->node, &component_class_list);
398454ed
PP
1609 comp_class->so_handle = spec->shared_lib_handle;
1610 bt_object_get_no_null_check(comp_class->so_handle);
55bb57e0
PP
1611
1612 /* Add our custom destroy listener */
3230ee6b 1613 bt_component_class_add_destroy_listener(comp_class,
55bb57e0 1614 plugin_comp_class_destroy_listener, NULL);
55bb57e0 1615}
This page took 0.119186 seconds and 4 git commands to generate.