BT_GRAPH_STATUS_CANCELED is not an error, thus use a positive value
[babeltrace.git] / lib / graph / component-class.c
CommitLineData
fb2dcc52
JG
1/*
2 * component-class.c
3 *
4 * Babeltrace Plugin Component Class
33b34c43 5 *
3310b217 6 * Copyright 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
fb2dcc52
JG
7 *
8 * Author: Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
3d9990ac 29#include <babeltrace/compiler-internal.h>
b2e0c907 30#include <babeltrace/graph/component-class-internal.h>
b8a06801 31#include <babeltrace/ref.h>
c55a9f58 32#include <babeltrace/types.h>
fb2dcc52
JG
33#include <glib.h>
34
35static
b8a06801 36void bt_component_class_destroy(struct bt_object *obj)
fb2dcc52
JG
37{
38 struct bt_component_class *class;
33b34c43 39 int i;
fb2dcc52 40
b8a06801
JG
41 assert(obj);
42 class = container_of(obj, struct bt_component_class, base);
33b34c43
PP
43
44 /* Call destroy listeners in reverse registration order */
45 for (i = class->destroy_listeners->len - 1; i >= 0; i--) {
d3e4dcd8 46 struct bt_component_class_destroy_listener *listener =
33b34c43 47 &g_array_index(class->destroy_listeners,
d3e4dcd8 48 struct bt_component_class_destroy_listener,
33b34c43
PP
49 i);
50
51 listener->func(class, listener->data);
52 }
53
fb2dcc52
JG
54 if (class->name) {
55 g_string_free(class->name, TRUE);
56 }
7c7c0433
JG
57 if (class->description) {
58 g_string_free(class->description, TRUE);
59 }
5536d9a6
PP
60 if (class->help) {
61 g_string_free(class->help, TRUE);
62 }
33b34c43
PP
63 if (class->destroy_listeners) {
64 g_array_free(class->destroy_listeners, TRUE);
65 }
b8a06801 66
fb2dcc52
JG
67 g_free(class);
68}
69
d3e4dcd8
PP
70static
71int bt_component_class_init(struct bt_component_class *class,
72 enum bt_component_class_type type, const char *name)
fb2dcc52 73{
d3e4dcd8
PP
74 int ret = 0;
75
76 bt_object_init(class, bt_component_class_destroy);
77 class->type = type;
78 class->name = g_string_new(name);
79 if (!class->name) {
80 goto error;
81 }
82
83 class->description = g_string_new(NULL);
84 if (!class->description) {
85 goto error;
86 }
87
5536d9a6
PP
88 class->help = g_string_new(NULL);
89 if (!class->help) {
90 goto error;
91 }
92
d3e4dcd8
PP
93 class->destroy_listeners = g_array_new(FALSE, TRUE,
94 sizeof(struct bt_component_class_destroy_listener));
95 if (!class->destroy_listeners) {
96 goto error;
97 }
98
99 goto end;
6ba0b073 100
d3e4dcd8
PP
101error:
102 BT_PUT(class);
103 ret = -1;
104
105end:
106 return ret;
107}
108
109struct bt_component_class *bt_component_class_source_create(const char *name,
d3eb6e8f 110 bt_component_class_notification_iterator_next_method notification_iterator_next_method)
d3e4dcd8
PP
111{
112 struct bt_component_class_source *source_class = NULL;
113 int ret;
114
41a2b7ae 115 if (!name || !notification_iterator_next_method) {
6ba0b073
PP
116 goto end;
117 }
fb2dcc52 118
d3e4dcd8
PP
119 source_class = g_new0(struct bt_component_class_source, 1);
120 if (!source_class) {
fb2dcc52
JG
121 goto end;
122 }
123
d3e4dcd8
PP
124 ret = bt_component_class_init(&source_class->parent,
125 BT_COMPONENT_CLASS_TYPE_SOURCE, name);
126 if (ret) {
127 /*
128 * If bt_component_class_init() fails, the component
129 * class is put, therefore its memory is already
130 * freed.
131 */
132 source_class = NULL;
133 goto end;
134 }
135
d3eb6e8f 136 source_class->methods.iterator.next = notification_iterator_next_method;
d3e4dcd8
PP
137
138end:
139 return &source_class->parent;
140}
141
142struct bt_component_class *bt_component_class_filter_create(const char *name,
d3eb6e8f 143 bt_component_class_notification_iterator_next_method notification_iterator_next_method)
d3e4dcd8
PP
144{
145 struct bt_component_class_filter *filter_class = NULL;
146 int ret;
147
41a2b7ae 148 if (!name || !notification_iterator_next_method) {
fb2dcc52
JG
149 goto end;
150 }
6ba0b073 151
d3e4dcd8
PP
152 filter_class = g_new0(struct bt_component_class_filter, 1);
153 if (!filter_class) {
154 goto end;
6ba0b073
PP
155 }
156
d3e4dcd8
PP
157 ret = bt_component_class_init(&filter_class->parent,
158 BT_COMPONENT_CLASS_TYPE_FILTER, name);
159 if (ret) {
160 /*
161 * If bt_component_class_init() fails, the component
162 * class is put, therefore its memory is already
163 * freed.
164 */
165 filter_class = NULL;
33b34c43
PP
166 goto end;
167 }
d3e4dcd8 168
d3eb6e8f 169 filter_class->methods.iterator.next = notification_iterator_next_method;
d3e4dcd8 170
fb2dcc52 171end:
d3e4dcd8
PP
172 return &filter_class->parent;
173}
174
175struct bt_component_class *bt_component_class_sink_create(const char *name,
176 bt_component_class_sink_consume_method consume_method)
177{
178 struct bt_component_class_sink *sink_class = NULL;
179 int ret;
180
181 if (!name || !consume_method) {
182 goto end;
183 }
184
185 sink_class = g_new0(struct bt_component_class_sink, 1);
186 if (!sink_class) {
187 goto end;
188 }
189
190 ret = bt_component_class_init(&sink_class->parent,
191 BT_COMPONENT_CLASS_TYPE_SINK, name);
192 if (ret) {
193 /*
194 * If bt_component_class_init() fails, the component
195 * class is put, therefore its memory is already
196 * freed.
197 */
198 sink_class = NULL;
199 goto end;
200 }
201
202 sink_class->methods.consume = consume_method;
203
204end:
205 return &sink_class->parent;
206}
207
208int bt_component_class_set_init_method(
209 struct bt_component_class *component_class,
210 bt_component_class_init_method init_method)
211{
212 int ret = 0;
213
1e4d8103 214 if (!component_class || component_class->frozen || !init_method) {
d3e4dcd8
PP
215 ret = -1;
216 goto end;
217 }
218
219 component_class->methods.init = init_method;
220
221end:
222 return ret;
223}
224
a67681c1 225int bt_component_class_set_query_method(
efa96d5d 226 struct bt_component_class *component_class,
a67681c1 227 bt_component_class_query_method query_method)
efa96d5d
PP
228{
229 int ret = 0;
230
a67681c1 231 if (!component_class || component_class->frozen || !query_method) {
efa96d5d
PP
232 ret = -1;
233 goto end;
234 }
235
a67681c1 236 component_class->methods.query = query_method;
efa96d5d
PP
237
238end:
239 return ret;
240}
241
72b913fb 242int bt_component_class_set_accept_port_connection_method(
2d41b99e 243 struct bt_component_class *component_class,
72b913fb 244 bt_component_class_accept_port_connection_method method)
2d41b99e
JG
245{
246 int ret = 0;
247
72b913fb 248 if (!component_class || component_class->frozen || !method) {
2d41b99e
JG
249 ret = -1;
250 goto end;
251 }
252
72b913fb
PP
253 component_class->methods.accept_port_connection = method;
254
255end:
256 return ret;
257}
258
0d8b4d8e
PP
259int bt_component_class_set_port_connected_method(
260 struct bt_component_class *component_class,
261 bt_component_class_port_connected_method method)
262{
263 int ret = 0;
264
265 if (!component_class || component_class->frozen || !method) {
266 ret = -1;
267 goto end;
268 }
269
270 component_class->methods.port_connected = method;
271
272end:
273 return ret;
274}
275
72b913fb
PP
276int bt_component_class_set_port_disconnected_method(
277 struct bt_component_class *component_class,
278 bt_component_class_port_disconnected_method method)
279{
280 int ret = 0;
281
282 if (!component_class || component_class->frozen || !method) {
283 ret = -1;
284 goto end;
285 }
286
287 component_class->methods.port_disconnected = method;
2d41b99e
JG
288
289end:
290 return ret;
291}
292
64cadc66 293int bt_component_class_set_finalize_method(
d3e4dcd8 294 struct bt_component_class *component_class,
64cadc66 295 bt_component_class_finalize_method finalize_method)
d3e4dcd8
PP
296{
297 int ret = 0;
298
64cadc66 299 if (!component_class || component_class->frozen || !finalize_method) {
d3e4dcd8
PP
300 ret = -1;
301 goto end;
302 }
303
64cadc66 304 component_class->methods.finalize = finalize_method;
d3e4dcd8
PP
305
306end:
307 return ret;
308}
309
d3eb6e8f
PP
310int bt_component_class_source_set_notification_iterator_init_method(
311 struct bt_component_class *component_class,
312 bt_component_class_notification_iterator_init_method notification_iterator_init_method)
313{
314 struct bt_component_class_source *source_class;
315 int ret = 0;
316
317 if (!component_class || component_class->frozen ||
318 !notification_iterator_init_method ||
319 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
320 ret = -1;
321 goto end;
322 }
323
324 source_class = container_of(component_class,
325 struct bt_component_class_source, parent);
326 source_class->methods.iterator.init = notification_iterator_init_method;
327
328end:
329 return ret;
330}
331
64cadc66 332int bt_component_class_source_set_notification_iterator_finalize_method(
d3eb6e8f 333 struct bt_component_class *component_class,
64cadc66 334 bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
d3eb6e8f
PP
335{
336 struct bt_component_class_source *source_class;
337 int ret = 0;
338
339 if (!component_class || component_class->frozen ||
64cadc66 340 !notification_iterator_finalize_method ||
d3eb6e8f
PP
341 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
342 ret = -1;
343 goto end;
344 }
345
346 source_class = container_of(component_class,
347 struct bt_component_class_source, parent);
64cadc66
PP
348 source_class->methods.iterator.finalize =
349 notification_iterator_finalize_method;
d3eb6e8f
PP
350
351end:
352 return ret;
353}
354
355int bt_component_class_source_set_notification_iterator_seek_time_method(
356 struct bt_component_class *component_class,
357 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
358{
359 struct bt_component_class_source *source_class;
360 int ret = 0;
361
362 if (!component_class || component_class->frozen ||
363 !notification_iterator_seek_time_method ||
364 component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) {
365 ret = -1;
366 goto end;
367 }
368
369 source_class = container_of(component_class,
370 struct bt_component_class_source, parent);
371 source_class->methods.iterator.seek_time =
372 notification_iterator_seek_time_method;
373
374end:
375 return ret;
376}
377
378int bt_component_class_filter_set_notification_iterator_init_method(
379 struct bt_component_class *component_class,
380 bt_component_class_notification_iterator_init_method notification_iterator_init_method)
381{
382 struct bt_component_class_filter *filter_class;
383 int ret = 0;
384
385 if (!component_class || component_class->frozen ||
386 !notification_iterator_init_method ||
387 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
388 ret = -1;
389 goto end;
390 }
391
392 filter_class = container_of(component_class,
393 struct bt_component_class_filter, parent);
394 filter_class->methods.iterator.init = notification_iterator_init_method;
395
396end:
397 return ret;
398}
399
64cadc66 400int bt_component_class_filter_set_notification_iterator_finalize_method(
d3eb6e8f 401 struct bt_component_class *component_class,
64cadc66 402 bt_component_class_notification_iterator_finalize_method notification_iterator_finalize_method)
d3eb6e8f
PP
403{
404 struct bt_component_class_filter *filter_class;
405 int ret = 0;
406
407 if (!component_class || component_class->frozen ||
64cadc66 408 !notification_iterator_finalize_method ||
d3eb6e8f
PP
409 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
410 ret = -1;
411 goto end;
412 }
413
414 filter_class = container_of(component_class,
415 struct bt_component_class_filter, parent);
64cadc66
PP
416 filter_class->methods.iterator.finalize =
417 notification_iterator_finalize_method;
d3eb6e8f
PP
418
419end:
420 return ret;
421}
422
423int bt_component_class_filter_set_notification_iterator_seek_time_method(
424 struct bt_component_class *component_class,
425 bt_component_class_notification_iterator_seek_time_method notification_iterator_seek_time_method)
426{
427 struct bt_component_class_filter *filter_class;
428 int ret = 0;
429
430 if (!component_class || component_class->frozen ||
431 !notification_iterator_seek_time_method ||
432 component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) {
433 ret = -1;
434 goto end;
435 }
436
437 filter_class = container_of(component_class,
438 struct bt_component_class_filter, parent);
439 filter_class->methods.iterator.seek_time =
440 notification_iterator_seek_time_method;
441
442end:
443 return ret;
444}
445
446int bt_component_class_set_description(
d3e4dcd8
PP
447 struct bt_component_class *component_class,
448 const char *description)
449{
450 int ret = 0;
451
1e4d8103 452 if (!component_class || component_class->frozen || !description) {
d3e4dcd8
PP
453 ret = -1;
454 goto end;
455 }
456
457 g_string_assign(component_class->description, description);
458
459end:
460 return ret;
fb2dcc52 461}
38b48196 462
5536d9a6
PP
463int bt_component_class_set_help(
464 struct bt_component_class *component_class,
465 const char *help)
466{
467 int ret = 0;
468
469 if (!component_class || component_class->frozen || !help) {
470 ret = -1;
471 goto end;
472 }
473
474 g_string_assign(component_class->help, help);
475
476end:
477 return ret;
478}
479
38b48196
JG
480const char *bt_component_class_get_name(
481 struct bt_component_class *component_class)
482{
483 return component_class ? component_class->name->str : NULL;
484}
485
d3e4dcd8 486enum bt_component_class_type bt_component_class_get_type(
38b48196
JG
487 struct bt_component_class *component_class)
488{
489 return component_class ? component_class->type :
d3e4dcd8 490 BT_COMPONENT_CLASS_TYPE_UNKNOWN;
38b48196
JG
491}
492
33b34c43 493const char *bt_component_class_get_description(
38b48196
JG
494 struct bt_component_class *component_class)
495{
22e22462
PP
496 return component_class && component_class->description &&
497 component_class->description->str[0] != '\0' ?
6ba0b073 498 component_class->description->str : NULL;
38b48196 499}
7c7c0433 500
5536d9a6
PP
501const char *bt_component_class_get_help(
502 struct bt_component_class *component_class)
503{
22e22462
PP
504 return component_class && component_class->help &&
505 component_class->help->str[0] != '\0' ?
5536d9a6
PP
506 component_class->help->str : NULL;
507}
508
33b34c43 509BT_HIDDEN
3230ee6b 510void bt_component_class_add_destroy_listener(struct bt_component_class *class,
33b34c43 511 bt_component_class_destroy_listener_func func, void *data)
7c7c0433 512{
d3e4dcd8 513 struct bt_component_class_destroy_listener listener;
33b34c43 514
3230ee6b
PP
515 assert(class);
516 assert(func);
33b34c43
PP
517 listener.func = func;
518 listener.data = data;
519 g_array_append_val(class->destroy_listeners, listener);
7c7c0433 520}
d3e4dcd8 521
1e4d8103
PP
522int bt_component_class_freeze(
523 struct bt_component_class *component_class)
524{
525 int ret = 0;
526
527 if (!component_class) {
528 ret = -1;
529 goto end;
530 }
531
c55a9f58 532 component_class->frozen = BT_TRUE;
1e4d8103
PP
533
534end:
535 return ret;
536}
efa96d5d 537
a67681c1 538struct bt_value *bt_component_class_query(
efa96d5d 539 struct bt_component_class *component_class,
a67681c1 540 const char *object, struct bt_value *params)
efa96d5d
PP
541{
542 struct bt_value *results = NULL;
543
a67681c1
PP
544 if (!component_class || !object || !params ||
545 !component_class->methods.query) {
efa96d5d
PP
546 goto end;
547 }
548
a67681c1
PP
549 results = component_class->methods.query(component_class,
550 object, params);
efa96d5d
PP
551
552end:
553 return results;
554}
This page took 0.060914 seconds and 4 git commands to generate.