bt2: make log functions clear error indicator
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_graph.i.h
CommitLineData
4212232c
PP
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25static
26void graph_listener_removed(void *py_callable)
27{
28 BT_ASSERT(py_callable);
29 Py_DECREF(py_callable);
30}
31
32static bt_graph_listener_func_status port_added_listener(
33 const void *component,
34 swig_type_info *component_swig_type,
35 bt_component_class_type component_class_type,
36 const void *port,
37 swig_type_info *port_swig_type,
38 bt_port_type port_type,
39 void *py_callable)
40{
41 PyObject *py_component_ptr = NULL;
42 PyObject *py_port_ptr = NULL;
43 PyObject *py_res = NULL;
44 bt_graph_listener_func_status status;
45
46 py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
47 if (!py_component_ptr) {
48 BT_LOGF_STR("Failed to create component SWIG pointer object.");
49 status = __BT_FUNC_STATUS_MEMORY_ERROR;
50 goto end;
51 }
52
53 py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0);
54 if (!py_port_ptr) {
55 BT_LOGF_STR("Failed to create port SWIG pointer object.");
56 status = __BT_FUNC_STATUS_MEMORY_ERROR;
57 goto end;
58 }
59
60 py_res = PyObject_CallFunction(py_callable, "(OiOi)",
61 py_component_ptr, component_class_type, py_port_ptr, port_type);
62 if (!py_res) {
981f33dd 63 loge_exception_append_cause_clear(
84e438af 64 "Graph's port added listener (Python)",
4212232c 65 BT_LOG_OUTPUT_LEVEL);
4212232c
PP
66 status = __BT_FUNC_STATUS_ERROR;
67 goto end;
68 }
69
70 BT_ASSERT(py_res == Py_None);
71 status = __BT_FUNC_STATUS_OK;
72
73end:
74 Py_XDECREF(py_res);
75 Py_XDECREF(py_port_ptr);
76 Py_XDECREF(py_component_ptr);
77 return status;
78}
79
80static
81bt_graph_listener_func_status
82source_component_output_port_added_listener(const bt_component_source *component_source,
83 const bt_port_output *port_output, void *py_callable)
84{
85 return port_added_listener(
86 component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
87 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
88}
89
90static
91bt_graph_listener_func_status
92filter_component_input_port_added_listener(const bt_component_filter *component_filter,
93 const bt_port_input *port_input, void *py_callable)
94{
95 return port_added_listener(
96 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
97 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
98}
99
100static
101bt_graph_listener_func_status
102filter_component_output_port_added_listener(const bt_component_filter *component_filter,
103 const bt_port_output *port_output, void *py_callable)
104{
105 return port_added_listener(
106 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
107 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
108}
109
110static
111bt_graph_listener_func_status
112sink_component_input_port_added_listener(const bt_component_sink *component_sink,
113 const bt_port_input *port_input, void *py_callable)
114{
115 return port_added_listener(
116 component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
117 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
118}
119
120static
121PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph,
122 PyObject *py_callable)
123{
124 PyObject *py_listener_ids = NULL;
125 PyObject *py_listener_id = NULL;
126 bt_listener_id listener_id;
127 bt_graph_add_listener_status status;
128 const char * const module_name =
129 "graph_add_port_added_listener() (Python)";
130
131 BT_ASSERT(graph);
132 BT_ASSERT(py_callable);
133
134 /*
135 * Behind the scene, we will be registering 4 different listeners and
136 * return all of their ids.
137 */
138 py_listener_ids = PyTuple_New(4);
139 if (!py_listener_ids) {
140 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
141 "Failed to allocate one PyTuple.");
142 goto error;
143 }
144
145 /* source output port */
146 status = bt_graph_add_source_component_output_port_added_listener(
147 graph, source_component_output_port_added_listener,
148 graph_listener_removed, py_callable, &listener_id);
149 if (status != __BT_FUNC_STATUS_OK) {
150 /*
151 * bt_graph_add_source_component_output_port_added_listener has
152 * already logged/appended an error cause.
153 */
154 goto error;
155 }
156
157 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
158 if (!py_listener_id) {
159 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
160 "Failed to allocate one PyLong.");
161 goto error;
162 }
163
164 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
165 py_listener_id = NULL;
166
167 /* filter input port */
168 status = bt_graph_add_filter_component_input_port_added_listener(
169 graph, filter_component_input_port_added_listener,
170 graph_listener_removed, py_callable, &listener_id);
171 if (status != __BT_FUNC_STATUS_OK) {
172 /*
173 * bt_graph_add_filter_component_input_port_added_listener has
174 * already logged/appended an error cause.
175 */
176 goto error;
177 }
178
179 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
180 if (!py_listener_id) {
181 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
182 "Failed to allocate one PyLong.");
183 goto error;
184 }
185
186 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
187 py_listener_id = NULL;
188
189 /* filter output port */
190 status = bt_graph_add_filter_component_output_port_added_listener(
191 graph, filter_component_output_port_added_listener,
192 graph_listener_removed, py_callable, &listener_id);
193 if (status != __BT_FUNC_STATUS_OK) {
194 /*
195 * bt_graph_add_filter_component_output_port_added_listener has
196 * already logged/appended an error cause.
197 */
198 goto error;
199 }
200
201 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
202 if (!py_listener_id) {
203 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
204 "Failed to allocate one PyLong.");
205 goto error;
206 }
207
208 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
209 py_listener_id = NULL;
210
211 /* sink input port */
212 status = bt_graph_add_sink_component_input_port_added_listener(
213 graph, sink_component_input_port_added_listener,
214 graph_listener_removed, py_callable, &listener_id);
215 if (status != __BT_FUNC_STATUS_OK) {
216 /*
217 * bt_graph_add_sink_component_input_port_added_listener has
218 * already logged/appended an error cause.
219 */
220 goto error;
221 }
222
223 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
224 if (!py_listener_id) {
225 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
226 "Failed to allocate one PyLong.");
227 goto error;
228 }
229
4212232c
PP
230 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
231 py_listener_id = NULL;
232
233 Py_INCREF(py_callable);
234 Py_INCREF(py_callable);
235 Py_INCREF(py_callable);
236 Py_INCREF(py_callable);
237
238 goto end;
239
240error:
241 Py_XDECREF(py_listener_ids);
242 py_listener_ids = Py_None;
243 Py_INCREF(py_listener_ids);
244
245end:
4212232c
PP
246 Py_XDECREF(py_listener_id);
247 return py_listener_ids;
248}
249
250static
251bt_graph_listener_func_status ports_connected_listener(
252 const void *upstream_component,
253 swig_type_info *upstream_component_swig_type,
254 bt_component_class_type upstream_component_class_type,
255 const bt_port_output *upstream_port,
256 const void *downstream_component,
257 swig_type_info *downstream_component_swig_type,
258 bt_component_class_type downstream_component_class_type,
259 const bt_port_input *downstream_port,
260 void *py_callable)
261{
262 PyObject *py_upstream_component_ptr = NULL;
263 PyObject *py_upstream_port_ptr = NULL;
264 PyObject *py_downstream_component_ptr = NULL;
265 PyObject *py_downstream_port_ptr = NULL;
266 PyObject *py_res = NULL;
267 bt_graph_listener_func_status status;
268
269 py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component),
270 upstream_component_swig_type, 0);
271 if (!py_upstream_component_ptr) {
272 BT_LOGF_STR("Failed to create upstream component SWIG pointer object.");
273 status = __BT_FUNC_STATUS_MEMORY_ERROR;
274 goto end;
275 }
276
277 py_upstream_port_ptr = SWIG_NewPointerObj(
278 SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
279 if (!py_upstream_port_ptr) {
280 BT_LOGF_STR("Failed to create upstream port SWIG pointer object.");
281 status = __BT_FUNC_STATUS_MEMORY_ERROR;
282 goto end;
283 }
284
285 py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component),
286 downstream_component_swig_type, 0);
287 if (!py_downstream_component_ptr) {
288 BT_LOGF_STR("Failed to create downstream component SWIG pointer object.");
289 status = __BT_FUNC_STATUS_MEMORY_ERROR;
290 goto end;
291 }
292
293 py_downstream_port_ptr = SWIG_NewPointerObj(
294 SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0);
295 if (!py_downstream_port_ptr) {
296 BT_LOGF_STR("Failed to create downstream port SWIG pointer object.");
297 status = __BT_FUNC_STATUS_MEMORY_ERROR;
298 goto end;
299 }
300
301 py_res = PyObject_CallFunction(py_callable, "(OiOOiO)",
302 py_upstream_component_ptr, upstream_component_class_type,
303 py_upstream_port_ptr,
304 py_downstream_component_ptr, downstream_component_class_type,
305 py_downstream_port_ptr);
306 if (!py_res) {
981f33dd 307 loge_exception_append_cause_clear(
84e438af 308 "Graph's port connected listener (Python)",
4212232c 309 BT_LOG_OUTPUT_LEVEL);
4212232c
PP
310 status = __BT_FUNC_STATUS_ERROR;
311 goto end;
312 }
313
314 BT_ASSERT(py_res == Py_None);
315 status = __BT_FUNC_STATUS_OK;
316
317end:
318 Py_XDECREF(py_upstream_component_ptr);
319 Py_XDECREF(py_upstream_port_ptr);
320 Py_XDECREF(py_downstream_component_ptr);
321 Py_XDECREF(py_downstream_port_ptr);
322 Py_XDECREF(py_res);
323 return status;
324}
325
326static
327bt_graph_listener_func_status source_filter_component_ports_connected_listener(
328 const bt_component_source *source_component,
329 const bt_component_filter *filter_component,
330 const bt_port_output *upstream_port,
331 const bt_port_input *downstream_port, void *py_callable)
332{
333 return ports_connected_listener(
334 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
335 upstream_port,
336 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
337 downstream_port,
338 py_callable);
339}
340
341static
342bt_graph_listener_func_status source_sink_component_ports_connected_listener(
343 const bt_component_source *source_component,
344 const bt_component_sink *sink_component,
345 const bt_port_output *upstream_port,
346 const bt_port_input *downstream_port, void *py_callable)
347{
348 return ports_connected_listener(
349 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
350 upstream_port,
351 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
352 downstream_port,
353 py_callable);
354}
355
356static
357bt_graph_listener_func_status filter_filter_component_ports_connected_listener(
358 const bt_component_filter *filter_component_left,
359 const bt_component_filter *filter_component_right,
360 const bt_port_output *upstream_port,
361 const bt_port_input *downstream_port, void *py_callable)
362{
363 return ports_connected_listener(
364 filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
365 upstream_port,
366 filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
367 downstream_port,
368 py_callable);
369}
370
371static
372bt_graph_listener_func_status filter_sink_component_ports_connected_listener(
373 const bt_component_filter *filter_component,
374 const bt_component_sink *sink_component,
375 const bt_port_output *upstream_port,
376 const bt_port_input *downstream_port, void *py_callable)
377{
378 return ports_connected_listener(
379 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
380 upstream_port,
381 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
382 downstream_port,
383 py_callable);
384}
385
386static
387PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph,
388 PyObject *py_callable)
389{
390 PyObject *py_listener_ids = NULL;
391 PyObject *py_listener_id = NULL;
392 bt_listener_id listener_id;
393 bt_graph_add_listener_status status;
394 const char * const module_name =
395 "graph_add_ports_connected_listener() (Python)";
396
397 BT_ASSERT(graph);
398 BT_ASSERT(py_callable);
399
400 /* Behind the scene, we will be registering 4 different listeners and
401 * return all of their ids. */
402 py_listener_ids = PyTuple_New(4);
403 if (!py_listener_ids) {
404 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
405 "Failed to allocate one PyTuple.");
406 goto error;
407 }
408
409 /* source -> filter connection */
410 status = bt_graph_add_source_filter_component_ports_connected_listener(
411 graph, source_filter_component_ports_connected_listener,
412 graph_listener_removed, py_callable, &listener_id);
413 if (status != __BT_FUNC_STATUS_OK) {
414 /*
415 * bt_graph_add_source_filter_component_ports_connected_listener
416 * has already logged/appended an error cause.
417 */
418 goto error;
419 }
420
421 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
422 if (!py_listener_id) {
423 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
424 "Failed to allocate one PyLong.");
425 goto error;
426 }
427
428 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
429 py_listener_id = NULL;
430
431 /* source -> sink connection */
432 status = bt_graph_add_source_sink_component_ports_connected_listener(
433 graph, source_sink_component_ports_connected_listener,
434 graph_listener_removed, py_callable, &listener_id);
435 if (status != __BT_FUNC_STATUS_OK) {
436 /*
437 * bt_graph_add_source_sink_component_ports_connected_listener
438 * has already logged/appended an error cause.
439 */
440 goto error;
441 }
442
443 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
444 if (!py_listener_id) {
445 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
446 "Failed to allocate one PyLong.");
447 goto error;
448 }
449
450 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
451 py_listener_id = NULL;
452
453 /* filter -> filter connection */
454 status = bt_graph_add_filter_filter_component_ports_connected_listener(
455 graph, filter_filter_component_ports_connected_listener,
456 graph_listener_removed, py_callable, &listener_id);
457 if (status != __BT_FUNC_STATUS_OK) {
458 /*
459 * bt_graph_add_filter_filter_component_ports_connected_listener
460 * has already logged/appended an error cause.
461 */
462 goto error;
463 }
464
465 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
466 if (!py_listener_id) {
467 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
468 "Failed to allocate one PyLong.");
469 goto error;
470 }
471
472 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
473 py_listener_id = NULL;
474
475 /* filter -> sink connection */
476 status = bt_graph_add_filter_sink_component_ports_connected_listener(
477 graph, filter_sink_component_ports_connected_listener,
478 graph_listener_removed, py_callable, &listener_id);
479 if (status != __BT_FUNC_STATUS_OK) {
480 /*
481 * bt_graph_add_filter_sink_component_ports_connected_listener
482 * has already logged/appended an error cause.
483 */
484 goto error;
485 }
486
487 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
488 if (!py_listener_id) {
489 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
490 "Failed to allocate one PyLong.");
491 goto error;
492 }
493
494 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
495 py_listener_id = NULL;
496
497 Py_INCREF(py_callable);
498 Py_INCREF(py_callable);
499 Py_INCREF(py_callable);
500 Py_INCREF(py_callable);
501
502 goto end;
503
504error:
505 Py_XDECREF(py_listener_ids);
506 py_listener_ids = Py_None;
507 Py_INCREF(py_listener_ids);
508
509end:
510
511 Py_XDECREF(py_listener_id);
512 return py_listener_ids;
513}
66964f3f
PP
514
515static
516bt_graph_add_component_status
517bt_bt2_graph_add_source_component(
518 bt_graph *graph,
519 const bt_component_class_source *component_class,
520 const char *name, const bt_value *params,
521 PyObject *obj, bt_logging_level log_level,
522 const bt_component_source **component)
523{
21a9f056 524 return bt_graph_add_source_component_with_initialize_method_data(graph,
66964f3f
PP
525 component_class, name, params, obj == Py_None ? NULL : obj,
526 log_level, component);
527}
528
529static
530bt_graph_add_component_status
531bt_bt2_graph_add_filter_component(
532 bt_graph *graph,
533 const bt_component_class_filter *component_class,
534 const char *name, const bt_value *params,
535 PyObject *obj, bt_logging_level log_level,
536 const bt_component_filter **component)
537{
21a9f056 538 return bt_graph_add_filter_component_with_initialize_method_data(graph,
66964f3f
PP
539 component_class, name, params, obj == Py_None ? NULL : obj,
540 log_level, component);
541}
542
543static
544bt_graph_add_component_status
545bt_bt2_graph_add_sink_component(
546 bt_graph *graph,
547 const bt_component_class_sink *component_class,
548 const char *name, const bt_value *params,
549 PyObject *obj, bt_logging_level log_level,
550 const bt_component_sink **component)
551{
21a9f056 552 return bt_graph_add_sink_component_with_initialize_method_data(graph,
66964f3f
PP
553 component_class, name, params, obj == Py_None ? NULL : obj,
554 log_level, component);
555}
This page took 0.0479 seconds and 4 git commands to generate.