Commit | Line | Data |
---|---|---|
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 | ||
a3aacb6f PP |
29 | #define BT_LOG_TAG "COMP-CLASS" |
30 | #include <babeltrace/lib-logging-internal.h> | |
31 | ||
3d9990ac | 32 | #include <babeltrace/compiler-internal.h> |
b2e0c907 | 33 | #include <babeltrace/graph/component-class-internal.h> |
b8a06801 | 34 | #include <babeltrace/ref.h> |
c55a9f58 | 35 | #include <babeltrace/types.h> |
f6ccaed9 | 36 | #include <babeltrace/assert-internal.h> |
fb2dcc52 JG |
37 | #include <glib.h> |
38 | ||
39 | static | |
b8a06801 | 40 | void bt_component_class_destroy(struct bt_object *obj) |
fb2dcc52 JG |
41 | { |
42 | struct bt_component_class *class; | |
33b34c43 | 43 | int i; |
fb2dcc52 | 44 | |
f6ccaed9 | 45 | BT_ASSERT(obj); |
b8a06801 | 46 | class = container_of(obj, struct bt_component_class, base); |
33b34c43 | 47 | |
a3aacb6f PP |
48 | BT_LOGD("Destroying component class: " |
49 | "addr=%p, name=\"%s\", type=%s", | |
50 | class, bt_component_class_get_name(class), | |
51 | bt_component_class_type_string(class->type)); | |
52 | ||
33b34c43 PP |
53 | /* Call destroy listeners in reverse registration order */ |
54 | for (i = class->destroy_listeners->len - 1; i >= 0; i--) { | |
d3e4dcd8 | 55 | struct bt_component_class_destroy_listener *listener = |
33b34c43 | 56 | &g_array_index(class->destroy_listeners, |
d3e4dcd8 | 57 | struct bt_component_class_destroy_listener, |
33b34c43 PP |
58 | i); |
59 | ||
a3aacb6f PP |
60 | BT_LOGD("Calling destroy listener: func-addr=%p, data-addr=%p", |
61 | listener->func, listener->data); | |
33b34c43 PP |
62 | listener->func(class, listener->data); |
63 | } | |
64 | ||
fb2dcc52 JG |
65 | if (class->name) { |
66 | g_string_free(class->name, TRUE); | |
67 | } | |
7c7c0433 JG |
68 | if (class->description) { |
69 | g_string_free(class->description, TRUE); | |
70 | } | |
5536d9a6 PP |
71 | if (class->help) { |
72 | g_string_free(class->help, TRUE); | |
73 | } | |
33b34c43 PP |
74 | if (class->destroy_listeners) { |
75 | g_array_free(class->destroy_listeners, TRUE); | |
76 | } | |
b8a06801 | 77 | |
fb2dcc52 JG |
78 | g_free(class); |
79 | } | |
80 | ||
d3e4dcd8 PP |
81 | static |
82 | int bt_component_class_init(struct bt_component_class *class, | |
83 | enum bt_component_class_type type, const char *name) | |
fb2dcc52 | 84 | { |
d3e4dcd8 PP |
85 | int ret = 0; |
86 | ||
3fea54f6 | 87 | bt_object_init_shared(&class->base, bt_component_class_destroy); |
d3e4dcd8 PP |
88 | class->type = type; |
89 | class->name = g_string_new(name); | |
90 | if (!class->name) { | |
a3aacb6f | 91 | BT_LOGE_STR("Failed to allocate a GString."); |
d3e4dcd8 PP |
92 | goto error; |
93 | } | |
94 | ||
95 | class->description = g_string_new(NULL); | |
96 | if (!class->description) { | |
a3aacb6f | 97 | BT_LOGE_STR("Failed to allocate a GString."); |
d3e4dcd8 PP |
98 | goto error; |
99 | } | |
100 | ||
5536d9a6 PP |
101 | class->help = g_string_new(NULL); |
102 | if (!class->help) { | |
a3aacb6f | 103 | BT_LOGE_STR("Failed to allocate a GString."); |
5536d9a6 PP |
104 | goto error; |
105 | } | |
106 | ||
d3e4dcd8 PP |
107 | class->destroy_listeners = g_array_new(FALSE, TRUE, |
108 | sizeof(struct bt_component_class_destroy_listener)); | |
109 | if (!class->destroy_listeners) { | |
a3aacb6f | 110 | BT_LOGE_STR("Failed to allocate a GArray."); |
d3e4dcd8 PP |
111 | goto error; |
112 | } | |
113 | ||
114 | goto end; | |
6ba0b073 | 115 | |
d3e4dcd8 PP |
116 | error: |
117 | BT_PUT(class); | |
118 | ret = -1; | |
119 | ||
120 | end: | |
121 | return ret; | |
122 | } | |
123 | ||
124 | struct bt_component_class *bt_component_class_source_create(const char *name, | |
90157d89 | 125 | bt_component_class_notification_iterator_next_method method) |
d3e4dcd8 PP |
126 | { |
127 | struct bt_component_class_source *source_class = NULL; | |
128 | int ret; | |
129 | ||
a3aacb6f PP |
130 | if (!name) { |
131 | BT_LOGW_STR("Invalid parameter: name is NULL."); | |
132 | goto end; | |
133 | } | |
134 | ||
90157d89 | 135 | if (!method) { |
a3aacb6f | 136 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
6ba0b073 PP |
137 | goto end; |
138 | } | |
fb2dcc52 | 139 | |
a3aacb6f PP |
140 | BT_LOGD("Creating source component class: " |
141 | "name=\"%s\", notif-iter-next-method-addr=%p", | |
90157d89 | 142 | name, method); |
d3e4dcd8 PP |
143 | source_class = g_new0(struct bt_component_class_source, 1); |
144 | if (!source_class) { | |
a3aacb6f | 145 | BT_LOGE_STR("Failed to allocate one source component class."); |
fb2dcc52 JG |
146 | goto end; |
147 | } | |
148 | ||
a3aacb6f | 149 | /* bt_component_class_init() logs errors */ |
d3e4dcd8 PP |
150 | ret = bt_component_class_init(&source_class->parent, |
151 | BT_COMPONENT_CLASS_TYPE_SOURCE, name); | |
152 | if (ret) { | |
153 | /* | |
154 | * If bt_component_class_init() fails, the component | |
155 | * class is put, therefore its memory is already | |
156 | * freed. | |
157 | */ | |
158 | source_class = NULL; | |
159 | goto end; | |
160 | } | |
161 | ||
90157d89 | 162 | source_class->methods.iterator.next = method; |
a3aacb6f PP |
163 | BT_LOGD("Created source component class: " |
164 | "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p", | |
90157d89 | 165 | name, method, &source_class->parent); |
d3e4dcd8 PP |
166 | |
167 | end: | |
168 | return &source_class->parent; | |
169 | } | |
170 | ||
171 | struct bt_component_class *bt_component_class_filter_create(const char *name, | |
90157d89 | 172 | bt_component_class_notification_iterator_next_method method) |
d3e4dcd8 PP |
173 | { |
174 | struct bt_component_class_filter *filter_class = NULL; | |
175 | int ret; | |
176 | ||
a3aacb6f PP |
177 | if (!name) { |
178 | BT_LOGW_STR("Invalid parameter: name is NULL."); | |
fb2dcc52 JG |
179 | goto end; |
180 | } | |
6ba0b073 | 181 | |
90157d89 | 182 | if (!method) { |
a3aacb6f PP |
183 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
184 | goto end; | |
185 | } | |
186 | ||
187 | BT_LOGD("Creating filter component class: " | |
188 | "name=\"%s\", notif-iter-next-method-addr=%p", | |
90157d89 | 189 | name, method); |
d3e4dcd8 PP |
190 | filter_class = g_new0(struct bt_component_class_filter, 1); |
191 | if (!filter_class) { | |
a3aacb6f | 192 | BT_LOGE_STR("Failed to allocate one filter component class."); |
d3e4dcd8 | 193 | goto end; |
6ba0b073 PP |
194 | } |
195 | ||
a3aacb6f | 196 | /* bt_component_class_init() logs errors */ |
d3e4dcd8 PP |
197 | ret = bt_component_class_init(&filter_class->parent, |
198 | BT_COMPONENT_CLASS_TYPE_FILTER, name); | |
199 | if (ret) { | |
200 | /* | |
201 | * If bt_component_class_init() fails, the component | |
202 | * class is put, therefore its memory is already | |
203 | * freed. | |
204 | */ | |
205 | filter_class = NULL; | |
33b34c43 PP |
206 | goto end; |
207 | } | |
d3e4dcd8 | 208 | |
90157d89 | 209 | filter_class->methods.iterator.next = method; |
a3aacb6f PP |
210 | BT_LOGD("Created filter component class: " |
211 | "name=\"%s\", notif-iter-next-method-addr=%p, addr=%p", | |
90157d89 | 212 | name, method, &filter_class->parent); |
d3e4dcd8 | 213 | |
fb2dcc52 | 214 | end: |
d3e4dcd8 PP |
215 | return &filter_class->parent; |
216 | } | |
217 | ||
218 | struct bt_component_class *bt_component_class_sink_create(const char *name, | |
90157d89 | 219 | bt_component_class_sink_consume_method method) |
d3e4dcd8 PP |
220 | { |
221 | struct bt_component_class_sink *sink_class = NULL; | |
222 | int ret; | |
223 | ||
a3aacb6f PP |
224 | if (!name) { |
225 | BT_LOGW_STR("Invalid parameter: name is NULL."); | |
226 | goto end; | |
227 | } | |
228 | ||
90157d89 | 229 | if (!method) { |
a3aacb6f | 230 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
d3e4dcd8 PP |
231 | goto end; |
232 | } | |
233 | ||
a3aacb6f PP |
234 | BT_LOGD("Creating sink component class: " |
235 | "name=\"%s\", consume-method-addr=%p", | |
90157d89 | 236 | name, method); |
d3e4dcd8 PP |
237 | sink_class = g_new0(struct bt_component_class_sink, 1); |
238 | if (!sink_class) { | |
a3aacb6f | 239 | BT_LOGE_STR("Failed to allocate one sink component class."); |
d3e4dcd8 PP |
240 | goto end; |
241 | } | |
242 | ||
a3aacb6f | 243 | /* bt_component_class_init() logs errors */ |
d3e4dcd8 PP |
244 | ret = bt_component_class_init(&sink_class->parent, |
245 | BT_COMPONENT_CLASS_TYPE_SINK, name); | |
246 | if (ret) { | |
247 | /* | |
248 | * If bt_component_class_init() fails, the component | |
249 | * class is put, therefore its memory is already | |
250 | * freed. | |
251 | */ | |
252 | sink_class = NULL; | |
253 | goto end; | |
254 | } | |
255 | ||
90157d89 | 256 | sink_class->methods.consume = method; |
a3aacb6f PP |
257 | BT_LOGD("Created sink component class: " |
258 | "name=\"%s\", consume-method-addr=%p, addr=%p", | |
90157d89 | 259 | name, method, &sink_class->parent); |
d3e4dcd8 PP |
260 | |
261 | end: | |
262 | return &sink_class->parent; | |
263 | } | |
264 | ||
265 | int bt_component_class_set_init_method( | |
266 | struct bt_component_class *component_class, | |
90157d89 | 267 | bt_component_class_init_method method) |
d3e4dcd8 PP |
268 | { |
269 | int ret = 0; | |
270 | ||
a3aacb6f PP |
271 | if (!component_class) { |
272 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
273 | ret = -1; | |
274 | goto end; | |
275 | } | |
276 | ||
90157d89 | 277 | if (!method) { |
a3aacb6f PP |
278 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
279 | ret = -1; | |
280 | goto end; | |
281 | } | |
282 | ||
283 | if (component_class->frozen) { | |
284 | BT_LOGW("Invalid parameter: component class is frozen: " | |
285 | "addr=%p, name=\"%s\", type=%s", | |
286 | component_class, | |
287 | bt_component_class_get_name(component_class), | |
288 | bt_component_class_type_string(component_class->type)); | |
d3e4dcd8 PP |
289 | ret = -1; |
290 | goto end; | |
291 | } | |
292 | ||
90157d89 | 293 | component_class->methods.init = method; |
a3aacb6f PP |
294 | BT_LOGV("Set component class's initialization method: " |
295 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
296 | component_class, | |
297 | bt_component_class_get_name(component_class), | |
298 | bt_component_class_type_string(component_class->type), | |
90157d89 | 299 | method); |
d3e4dcd8 PP |
300 | |
301 | end: | |
302 | return ret; | |
303 | } | |
304 | ||
a67681c1 | 305 | int bt_component_class_set_query_method( |
efa96d5d | 306 | struct bt_component_class *component_class, |
90157d89 | 307 | bt_component_class_query_method method) |
efa96d5d PP |
308 | { |
309 | int ret = 0; | |
310 | ||
a3aacb6f PP |
311 | if (!component_class) { |
312 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
313 | ret = -1; | |
314 | goto end; | |
315 | } | |
316 | ||
90157d89 | 317 | if (!method) { |
a3aacb6f PP |
318 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
319 | ret = -1; | |
320 | goto end; | |
321 | } | |
322 | ||
323 | if (component_class->frozen) { | |
324 | BT_LOGW("Invalid parameter: component class is frozen: " | |
325 | "addr=%p, name=\"%s\", type=%s", | |
326 | component_class, | |
327 | bt_component_class_get_name(component_class), | |
328 | bt_component_class_type_string(component_class->type)); | |
efa96d5d PP |
329 | ret = -1; |
330 | goto end; | |
331 | } | |
332 | ||
90157d89 | 333 | component_class->methods.query = method; |
a3aacb6f PP |
334 | BT_LOGV("Set component class's query method: " |
335 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
336 | component_class, | |
337 | bt_component_class_get_name(component_class), | |
338 | bt_component_class_type_string(component_class->type), | |
90157d89 | 339 | method); |
efa96d5d PP |
340 | |
341 | end: | |
342 | return ret; | |
343 | } | |
344 | ||
72b913fb | 345 | int bt_component_class_set_accept_port_connection_method( |
2d41b99e | 346 | struct bt_component_class *component_class, |
72b913fb | 347 | bt_component_class_accept_port_connection_method method) |
2d41b99e JG |
348 | { |
349 | int ret = 0; | |
350 | ||
a3aacb6f PP |
351 | if (!component_class) { |
352 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
353 | ret = -1; | |
354 | goto end; | |
355 | } | |
356 | ||
357 | if (!method) { | |
358 | BT_LOGW_STR("Invalid parameter: method is NULL."); | |
359 | ret = -1; | |
360 | goto end; | |
361 | } | |
362 | ||
363 | if (component_class->frozen) { | |
364 | BT_LOGW("Invalid parameter: component class is frozen: " | |
365 | "addr=%p, name=\"%s\", type=%s", | |
366 | component_class, | |
367 | bt_component_class_get_name(component_class), | |
368 | bt_component_class_type_string(component_class->type)); | |
2d41b99e JG |
369 | ret = -1; |
370 | goto end; | |
371 | } | |
372 | ||
72b913fb | 373 | component_class->methods.accept_port_connection = method; |
a3aacb6f PP |
374 | BT_LOGV("Set component class's \"accept port connection\" method: " |
375 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
376 | component_class, | |
377 | bt_component_class_get_name(component_class), | |
378 | bt_component_class_type_string(component_class->type), | |
379 | method); | |
72b913fb PP |
380 | |
381 | end: | |
382 | return ret; | |
383 | } | |
384 | ||
0d8b4d8e PP |
385 | int bt_component_class_set_port_connected_method( |
386 | struct bt_component_class *component_class, | |
387 | bt_component_class_port_connected_method method) | |
388 | { | |
389 | int ret = 0; | |
390 | ||
a3aacb6f PP |
391 | if (!component_class) { |
392 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
393 | ret = -1; | |
394 | goto end; | |
395 | } | |
396 | ||
397 | if (!method) { | |
398 | BT_LOGW_STR("Invalid parameter: method is NULL."); | |
399 | ret = -1; | |
400 | goto end; | |
401 | } | |
402 | ||
403 | if (component_class->frozen) { | |
404 | BT_LOGW("Invalid parameter: component class is frozen: " | |
405 | "addr=%p, name=\"%s\", type=%s", | |
406 | component_class, | |
407 | bt_component_class_get_name(component_class), | |
408 | bt_component_class_type_string(component_class->type)); | |
0d8b4d8e PP |
409 | ret = -1; |
410 | goto end; | |
411 | } | |
412 | ||
413 | component_class->methods.port_connected = method; | |
a3aacb6f PP |
414 | BT_LOGV("Set component class's \"port connected\" method: " |
415 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
416 | component_class, | |
417 | bt_component_class_get_name(component_class), | |
418 | bt_component_class_type_string(component_class->type), | |
419 | method); | |
0d8b4d8e PP |
420 | |
421 | end: | |
422 | return ret; | |
423 | } | |
424 | ||
72b913fb PP |
425 | int bt_component_class_set_port_disconnected_method( |
426 | struct bt_component_class *component_class, | |
427 | bt_component_class_port_disconnected_method method) | |
428 | { | |
429 | int ret = 0; | |
430 | ||
a3aacb6f PP |
431 | if (!component_class) { |
432 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
433 | ret = -1; | |
434 | goto end; | |
435 | } | |
436 | ||
437 | if (!method) { | |
438 | BT_LOGW_STR("Invalid parameter: method is NULL."); | |
439 | ret = -1; | |
440 | goto end; | |
441 | } | |
442 | ||
443 | if (component_class->frozen) { | |
444 | BT_LOGW("Invalid parameter: component class is frozen: " | |
445 | "addr=%p, name=\"%s\", type=%s", | |
446 | component_class, | |
447 | bt_component_class_get_name(component_class), | |
448 | bt_component_class_type_string(component_class->type)); | |
72b913fb PP |
449 | ret = -1; |
450 | goto end; | |
451 | } | |
452 | ||
453 | component_class->methods.port_disconnected = method; | |
a3aacb6f PP |
454 | BT_LOGV("Set component class's \"port disconnected\" method: " |
455 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
456 | component_class, | |
457 | bt_component_class_get_name(component_class), | |
458 | bt_component_class_type_string(component_class->type), | |
459 | method); | |
2d41b99e JG |
460 | |
461 | end: | |
462 | return ret; | |
463 | } | |
464 | ||
64cadc66 | 465 | int bt_component_class_set_finalize_method( |
d3e4dcd8 | 466 | struct bt_component_class *component_class, |
90157d89 | 467 | bt_component_class_finalize_method method) |
d3e4dcd8 PP |
468 | { |
469 | int ret = 0; | |
470 | ||
a3aacb6f PP |
471 | if (!component_class) { |
472 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
473 | ret = -1; | |
474 | goto end; | |
475 | } | |
476 | ||
90157d89 | 477 | if (!method) { |
a3aacb6f PP |
478 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
479 | ret = -1; | |
480 | goto end; | |
481 | } | |
482 | ||
483 | if (component_class->frozen) { | |
484 | BT_LOGW("Invalid parameter: component class is frozen: " | |
485 | "addr=%p, name=\"%s\", type=%s", | |
486 | component_class, | |
487 | bt_component_class_get_name(component_class), | |
488 | bt_component_class_type_string(component_class->type)); | |
d3e4dcd8 PP |
489 | ret = -1; |
490 | goto end; | |
491 | } | |
492 | ||
90157d89 | 493 | component_class->methods.finalize = method; |
a3aacb6f PP |
494 | BT_LOGV("Set component class's finalization method: " |
495 | "addr=%p, name=\"%s\", type=%s, method-addr=%p", | |
496 | component_class, | |
497 | bt_component_class_get_name(component_class), | |
498 | bt_component_class_type_string(component_class->type), | |
90157d89 | 499 | method); |
d3e4dcd8 PP |
500 | |
501 | end: | |
502 | return ret; | |
503 | } | |
504 | ||
d3eb6e8f PP |
505 | int bt_component_class_source_set_notification_iterator_init_method( |
506 | struct bt_component_class *component_class, | |
90157d89 | 507 | bt_component_class_notification_iterator_init_method method) |
d3eb6e8f PP |
508 | { |
509 | struct bt_component_class_source *source_class; | |
510 | int ret = 0; | |
511 | ||
a3aacb6f PP |
512 | if (!component_class) { |
513 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
514 | ret = -1; | |
515 | goto end; | |
516 | } | |
517 | ||
90157d89 | 518 | if (!method) { |
a3aacb6f PP |
519 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
520 | ret = -1; | |
521 | goto end; | |
522 | } | |
523 | ||
524 | if (component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { | |
525 | BT_LOGW("Invalid parameter: component class is not a source component class: " | |
526 | "addr=%p, name=\"%s\", type=%s", | |
527 | component_class, | |
528 | bt_component_class_get_name(component_class), | |
529 | bt_component_class_type_string(component_class->type)); | |
530 | ret = -1; | |
531 | goto end; | |
532 | } | |
533 | ||
534 | if (component_class->frozen) { | |
535 | BT_LOGW("Invalid parameter: component class is frozen: " | |
536 | "addr=%p, name=\"%s\", type=%s", | |
537 | component_class, | |
538 | bt_component_class_get_name(component_class), | |
539 | bt_component_class_type_string(component_class->type)); | |
d3eb6e8f PP |
540 | ret = -1; |
541 | goto end; | |
542 | } | |
543 | ||
544 | source_class = container_of(component_class, | |
545 | struct bt_component_class_source, parent); | |
90157d89 | 546 | source_class->methods.iterator.init = method; |
a3aacb6f PP |
547 | BT_LOGV("Set filter component class's notification iterator initialization method: " |
548 | "addr=%p, name=\"%s\", method-addr=%p", | |
549 | component_class, | |
550 | bt_component_class_get_name(component_class), | |
90157d89 | 551 | method); |
d3eb6e8f PP |
552 | |
553 | end: | |
554 | return ret; | |
555 | } | |
556 | ||
64cadc66 | 557 | int bt_component_class_source_set_notification_iterator_finalize_method( |
d3eb6e8f | 558 | struct bt_component_class *component_class, |
90157d89 | 559 | bt_component_class_notification_iterator_finalize_method method) |
d3eb6e8f PP |
560 | { |
561 | struct bt_component_class_source *source_class; | |
562 | int ret = 0; | |
563 | ||
a3aacb6f PP |
564 | if (!component_class) { |
565 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
566 | ret = -1; | |
567 | goto end; | |
568 | } | |
569 | ||
90157d89 | 570 | if (!method) { |
a3aacb6f PP |
571 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
572 | ret = -1; | |
573 | goto end; | |
574 | } | |
575 | ||
576 | if (component_class->type != BT_COMPONENT_CLASS_TYPE_SOURCE) { | |
577 | BT_LOGW("Invalid parameter: component class is not a source component class: " | |
578 | "addr=%p, name=\"%s\", type=%s", | |
579 | component_class, | |
580 | bt_component_class_get_name(component_class), | |
581 | bt_component_class_type_string(component_class->type)); | |
582 | ret = -1; | |
583 | goto end; | |
584 | } | |
585 | ||
586 | if (component_class->frozen) { | |
587 | BT_LOGW("Invalid parameter: component class is frozen: " | |
588 | "addr=%p, name=\"%s\", type=%s", | |
589 | component_class, | |
590 | bt_component_class_get_name(component_class), | |
591 | bt_component_class_type_string(component_class->type)); | |
d3eb6e8f PP |
592 | ret = -1; |
593 | goto end; | |
594 | } | |
595 | ||
596 | source_class = container_of(component_class, | |
597 | struct bt_component_class_source, parent); | |
64cadc66 | 598 | source_class->methods.iterator.finalize = |
90157d89 | 599 | method; |
a3aacb6f PP |
600 | BT_LOGV("Set filter component class's notification iterator finalization method: " |
601 | "addr=%p, name=\"%s\", method-addr=%p", | |
602 | component_class, | |
603 | bt_component_class_get_name(component_class), | |
90157d89 | 604 | method); |
d3eb6e8f PP |
605 | |
606 | end: | |
607 | return ret; | |
608 | } | |
609 | ||
d3eb6e8f PP |
610 | int bt_component_class_filter_set_notification_iterator_init_method( |
611 | struct bt_component_class *component_class, | |
90157d89 | 612 | bt_component_class_notification_iterator_init_method method) |
d3eb6e8f PP |
613 | { |
614 | struct bt_component_class_filter *filter_class; | |
615 | int ret = 0; | |
616 | ||
a3aacb6f PP |
617 | if (!component_class) { |
618 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
619 | ret = -1; | |
620 | goto end; | |
621 | } | |
622 | ||
90157d89 | 623 | if (!method) { |
a3aacb6f PP |
624 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
625 | ret = -1; | |
626 | goto end; | |
627 | } | |
628 | ||
629 | if (component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { | |
630 | BT_LOGW("Invalid parameter: component class is not a filter component class: " | |
631 | "addr=%p, name=\"%s\", type=%s", | |
632 | component_class, | |
633 | bt_component_class_get_name(component_class), | |
634 | bt_component_class_type_string(component_class->type)); | |
635 | ret = -1; | |
636 | goto end; | |
637 | } | |
638 | ||
639 | if (component_class->frozen) { | |
640 | BT_LOGW("Invalid parameter: component class is frozen: " | |
641 | "addr=%p, name=\"%s\", type=%s", | |
642 | component_class, | |
643 | bt_component_class_get_name(component_class), | |
644 | bt_component_class_type_string(component_class->type)); | |
d3eb6e8f PP |
645 | ret = -1; |
646 | goto end; | |
647 | } | |
648 | ||
649 | filter_class = container_of(component_class, | |
650 | struct bt_component_class_filter, parent); | |
90157d89 | 651 | filter_class->methods.iterator.init = method; |
a3aacb6f PP |
652 | BT_LOGV("Set filter component class's notification iterator initialization method: " |
653 | "addr=%p, name=\"%s\", method-addr=%p", | |
654 | component_class, | |
655 | bt_component_class_get_name(component_class), | |
90157d89 | 656 | method); |
d3eb6e8f PP |
657 | |
658 | end: | |
659 | return ret; | |
660 | } | |
661 | ||
64cadc66 | 662 | int bt_component_class_filter_set_notification_iterator_finalize_method( |
d3eb6e8f | 663 | struct bt_component_class *component_class, |
90157d89 | 664 | bt_component_class_notification_iterator_finalize_method method) |
d3eb6e8f PP |
665 | { |
666 | struct bt_component_class_filter *filter_class; | |
667 | int ret = 0; | |
668 | ||
a3aacb6f PP |
669 | if (!component_class) { |
670 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
671 | ret = -1; | |
672 | goto end; | |
673 | } | |
674 | ||
90157d89 | 675 | if (!method) { |
a3aacb6f PP |
676 | BT_LOGW_STR("Invalid parameter: method is NULL."); |
677 | ret = -1; | |
678 | goto end; | |
679 | } | |
680 | ||
681 | if (component_class->type != BT_COMPONENT_CLASS_TYPE_FILTER) { | |
682 | BT_LOGW("Invalid parameter: component class is not a filter component class: " | |
683 | "addr=%p, name=\"%s\", type=%s", | |
684 | component_class, | |
685 | bt_component_class_get_name(component_class), | |
686 | bt_component_class_type_string(component_class->type)); | |
687 | ret = -1; | |
688 | goto end; | |
689 | } | |
690 | ||
691 | if (component_class->frozen) { | |
692 | BT_LOGW("Invalid parameter: component class is frozen: " | |
693 | "addr=%p, name=\"%s\", type=%s", | |
694 | component_class, | |
695 | bt_component_class_get_name(component_class), | |
696 | bt_component_class_type_string(component_class->type)); | |
d3eb6e8f PP |
697 | ret = -1; |
698 | goto end; | |
699 | } | |
700 | ||
701 | filter_class = container_of(component_class, | |
702 | struct bt_component_class_filter, parent); | |
64cadc66 | 703 | filter_class->methods.iterator.finalize = |
90157d89 | 704 | method; |
a3aacb6f PP |
705 | BT_LOGV("Set filter component class's notification iterator finalization method: " |
706 | "addr=%p, name=\"%s\", method-addr=%p", | |
707 | component_class, | |
708 | bt_component_class_get_name(component_class), | |
90157d89 | 709 | method); |
d3eb6e8f PP |
710 | |
711 | end: | |
712 | return ret; | |
713 | } | |
714 | ||
d3eb6e8f | 715 | int bt_component_class_set_description( |
d3e4dcd8 PP |
716 | struct bt_component_class *component_class, |
717 | const char *description) | |
718 | { | |
719 | int ret = 0; | |
720 | ||
a3aacb6f PP |
721 | if (!component_class) { |
722 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
723 | ret = -1; | |
724 | goto end; | |
725 | } | |
726 | ||
727 | if (!description) { | |
728 | BT_LOGW_STR("Invalid parameter: description is NULL."); | |
729 | ret = -1; | |
730 | goto end; | |
731 | } | |
732 | ||
733 | if (component_class->frozen) { | |
734 | BT_LOGW("Invalid parameter: component class is frozen: " | |
735 | "addr=%p, name=\"%s\", type=%s", | |
736 | component_class, | |
737 | bt_component_class_get_name(component_class), | |
738 | bt_component_class_type_string(component_class->type)); | |
d3e4dcd8 PP |
739 | ret = -1; |
740 | goto end; | |
741 | } | |
742 | ||
743 | g_string_assign(component_class->description, description); | |
a3aacb6f PP |
744 | BT_LOGV("Set component class's description: " |
745 | "addr=%p, name=\"%s\", type=%s", | |
746 | component_class, | |
747 | bt_component_class_get_name(component_class), | |
748 | bt_component_class_type_string(component_class->type)); | |
d3e4dcd8 PP |
749 | |
750 | end: | |
751 | return ret; | |
fb2dcc52 | 752 | } |
38b48196 | 753 | |
5536d9a6 PP |
754 | int bt_component_class_set_help( |
755 | struct bt_component_class *component_class, | |
756 | const char *help) | |
757 | { | |
758 | int ret = 0; | |
759 | ||
a3aacb6f PP |
760 | if (!component_class) { |
761 | BT_LOGW_STR("Invalid parameter: component class is NULL."); | |
762 | ret = -1; | |
763 | goto end; | |
764 | } | |
765 | ||
766 | if (!help) { | |
767 | BT_LOGW_STR("Invalid parameter: help is NULL."); | |
768 | ret = -1; | |
769 | goto end; | |
770 | } | |
771 | ||
772 | if (component_class->frozen) { | |
773 | BT_LOGW("Invalid parameter: component class is frozen: " | |
774 | "addr=%p, name=\"%s\", type=%s", | |
775 | component_class, | |
776 | bt_component_class_get_name(component_class), | |
777 | bt_component_class_type_string(component_class->type)); | |
5536d9a6 PP |
778 | ret = -1; |
779 | goto end; | |
780 | } | |
781 | ||
782 | g_string_assign(component_class->help, help); | |
a3aacb6f PP |
783 | BT_LOGV("Set component class's help text: " |
784 | "addr=%p, name=\"%s\", type=%s", | |
785 | component_class, | |
786 | bt_component_class_get_name(component_class), | |
787 | bt_component_class_type_string(component_class->type)); | |
5536d9a6 PP |
788 | |
789 | end: | |
790 | return ret; | |
791 | } | |
792 | ||
38b48196 JG |
793 | const char *bt_component_class_get_name( |
794 | struct bt_component_class *component_class) | |
795 | { | |
796 | return component_class ? component_class->name->str : NULL; | |
797 | } | |
798 | ||
d3e4dcd8 | 799 | enum bt_component_class_type bt_component_class_get_type( |
38b48196 JG |
800 | struct bt_component_class *component_class) |
801 | { | |
802 | return component_class ? component_class->type : | |
d3e4dcd8 | 803 | BT_COMPONENT_CLASS_TYPE_UNKNOWN; |
38b48196 JG |
804 | } |
805 | ||
33b34c43 | 806 | const char *bt_component_class_get_description( |
38b48196 JG |
807 | struct bt_component_class *component_class) |
808 | { | |
22e22462 PP |
809 | return component_class && component_class->description && |
810 | component_class->description->str[0] != '\0' ? | |
6ba0b073 | 811 | component_class->description->str : NULL; |
38b48196 | 812 | } |
7c7c0433 | 813 | |
5536d9a6 PP |
814 | const char *bt_component_class_get_help( |
815 | struct bt_component_class *component_class) | |
816 | { | |
22e22462 PP |
817 | return component_class && component_class->help && |
818 | component_class->help->str[0] != '\0' ? | |
5536d9a6 PP |
819 | component_class->help->str : NULL; |
820 | } | |
821 | ||
33b34c43 | 822 | BT_HIDDEN |
3230ee6b | 823 | void bt_component_class_add_destroy_listener(struct bt_component_class *class, |
33b34c43 | 824 | bt_component_class_destroy_listener_func func, void *data) |
7c7c0433 | 825 | { |
d3e4dcd8 | 826 | struct bt_component_class_destroy_listener listener; |
33b34c43 | 827 | |
f6ccaed9 PP |
828 | BT_ASSERT(class); |
829 | BT_ASSERT(func); | |
33b34c43 PP |
830 | listener.func = func; |
831 | listener.data = data; | |
832 | g_array_append_val(class->destroy_listeners, listener); | |
a3aacb6f PP |
833 | BT_LOGV("Component class has no registered query method: " |
834 | "comp-class-addr=%p, comp-class-name=\"%s\", comp-class-type=%s" | |
835 | "func-addr=%p, data-addr=%p", | |
836 | class, | |
837 | bt_component_class_get_name(class), | |
838 | bt_component_class_type_string(class->type), | |
839 | func, data); | |
7c7c0433 | 840 | } |
d3e4dcd8 | 841 | |
1e4d8103 PP |
842 | int bt_component_class_freeze( |
843 | struct bt_component_class *component_class) | |
844 | { | |
845 | int ret = 0; | |
846 | ||
847 | if (!component_class) { | |
a3aacb6f | 848 | BT_LOGW_STR("Invalid parameter: component class is NULL."); |
1e4d8103 PP |
849 | ret = -1; |
850 | goto end; | |
851 | } | |
852 | ||
a3aacb6f PP |
853 | if (component_class->frozen) { |
854 | goto end; | |
855 | } | |
856 | ||
857 | BT_LOGD("Freezing component class: " | |
858 | "addr=%p, name=\"%s\", type=%s", | |
859 | component_class, | |
860 | bt_component_class_get_name(component_class), | |
861 | bt_component_class_type_string(component_class->type)); | |
c55a9f58 | 862 | component_class->frozen = BT_TRUE; |
1e4d8103 PP |
863 | |
864 | end: | |
865 | return ret; | |
866 | } |