bt2: honor self component or query log level when logging
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_graph.i
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
25 /* Output argument typemap for connection output (always appends) */
26 %typemap(in, numinputs=0)
27 (const bt_connection **)
28 (bt_connection *temp_conn = NULL) {
29 $1 = &temp_conn;
30 }
31
32 %typemap(argout)
33 (const bt_connection **) {
34 if (*$1) {
35 /* SWIG_Python_AppendOutput() steals the created object */
36 $result = SWIG_Python_AppendOutput($result,
37 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
38 SWIGTYPE_p_bt_connection, 0));
39 } else {
40 /* SWIG_Python_AppendOutput() steals Py_None */
41 Py_INCREF(Py_None);
42 $result = SWIG_Python_AppendOutput($result, Py_None);
43 }
44 }
45
46 /* Output argument typemap for component output (always appends) */
47 %typemap(in, numinputs=0)
48 (const bt_component_source **)
49 (bt_component_source *temp_comp = NULL) {
50 $1 = &temp_comp;
51 }
52
53 %typemap(in, numinputs=0)
54 (const bt_component_filter **)
55 (bt_component_filter *temp_comp = NULL) {
56 $1 = &temp_comp;
57 }
58
59 %typemap(in, numinputs=0)
60 (const bt_component_sink **)
61 (bt_component_sink *temp_comp = NULL) {
62 $1 = &temp_comp;
63 }
64
65 %typemap(argout) (const bt_component_source **) {
66 if (*$1) {
67 /* SWIG_Python_AppendOutput() steals the created object */
68 $result = SWIG_Python_AppendOutput($result,
69 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
70 SWIGTYPE_p_bt_component_source, 0));
71 } else {
72 /* SWIG_Python_AppendOutput() steals Py_None */
73 Py_INCREF(Py_None);
74 $result = SWIG_Python_AppendOutput($result, Py_None);
75 }
76 }
77
78 %typemap(argout) (const bt_component_filter **) {
79 if (*$1) {
80 /* SWIG_Python_AppendOutput() steals the created object */
81 $result = SWIG_Python_AppendOutput($result,
82 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
83 SWIGTYPE_p_bt_component_filter, 0));
84 } else {
85 /* SWIG_Python_AppendOutput() steals Py_None */
86 Py_INCREF(Py_None);
87 $result = SWIG_Python_AppendOutput($result, Py_None);
88 }
89 }
90
91 %typemap(argout) (const bt_component_sink **) {
92 if (*$1) {
93 /* SWIG_Python_AppendOutput() steals the created object */
94 $result = SWIG_Python_AppendOutput($result,
95 SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
96 SWIGTYPE_p_bt_component_sink, 0));
97 } else {
98 /* SWIG_Python_AppendOutput() steals Py_None */
99 Py_INCREF(Py_None);
100 $result = SWIG_Python_AppendOutput($result, Py_None);
101 }
102 }
103
104 %include <babeltrace2/graph/graph-const.h>
105 %include <babeltrace2/graph/graph.h>
106
107 /* Helper functions for Python */
108
109 %{
110 static
111 void graph_listener_removed(void *py_callable)
112 {
113 BT_ASSERT(py_callable);
114 Py_DECREF(py_callable);
115 }
116
117 static bt_graph_listener_func_status port_added_listener(
118 const void *component,
119 swig_type_info *component_swig_type,
120 bt_component_class_type component_class_type,
121 const void *port,
122 swig_type_info *port_swig_type,
123 bt_port_type port_type,
124 void *py_callable)
125 {
126 PyObject *py_component_ptr = NULL;
127 PyObject *py_port_ptr = NULL;
128 PyObject *py_res = NULL;
129 bt_graph_listener_func_status status;
130
131 py_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component), component_swig_type, 0);
132 if (!py_component_ptr) {
133 BT_LOGF_STR("Failed to create component SWIG pointer object.");
134 status = __BT_FUNC_STATUS_MEMORY_ERROR;
135 goto end;
136 }
137
138 py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port), port_swig_type, 0);
139 if (!py_port_ptr) {
140 BT_LOGF_STR("Failed to create port SWIG pointer object.");
141 status = __BT_FUNC_STATUS_MEMORY_ERROR;
142 goto end;
143 }
144
145 py_res = PyObject_CallFunction(py_callable, "(OiOi)",
146 py_component_ptr, component_class_type, py_port_ptr, port_type);
147 if (!py_res) {
148 loge_exception("Graph's port added listener (Python)",
149 BT_LOG_OUTPUT_LEVEL);
150 PyErr_Clear();
151 status = __BT_FUNC_STATUS_ERROR;
152 goto end;
153 }
154
155 BT_ASSERT(py_res == Py_None);
156 status = __BT_FUNC_STATUS_OK;
157
158 end:
159 Py_XDECREF(py_res);
160 Py_XDECREF(py_port_ptr);
161 Py_XDECREF(py_component_ptr);
162 return status;
163 }
164
165 static
166 bt_graph_listener_func_status
167 source_component_output_port_added_listener(const bt_component_source *component_source,
168 const bt_port_output *port_output, void *py_callable)
169 {
170 return port_added_listener(
171 component_source, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
172 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
173 }
174
175 static
176 bt_graph_listener_func_status
177 filter_component_input_port_added_listener(const bt_component_filter *component_filter,
178 const bt_port_input *port_input, void *py_callable)
179 {
180 return port_added_listener(
181 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
182 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
183 }
184
185 static
186 bt_graph_listener_func_status
187 filter_component_output_port_added_listener(const bt_component_filter *component_filter,
188 const bt_port_output *port_output, void *py_callable)
189 {
190 return port_added_listener(
191 component_filter, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
192 port_output, SWIGTYPE_p_bt_port_output, BT_PORT_TYPE_OUTPUT, py_callable);
193 }
194
195 static
196 bt_graph_listener_func_status
197 sink_component_input_port_added_listener(const bt_component_sink *component_sink,
198 const bt_port_input *port_input, void *py_callable)
199 {
200 return port_added_listener(
201 component_sink, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
202 port_input, SWIGTYPE_p_bt_port_input, BT_PORT_TYPE_INPUT, py_callable);
203 }
204
205 static
206 PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph,
207 PyObject *py_callable)
208 {
209 PyObject *py_listener_ids = NULL;
210 PyObject *py_listener_id = NULL;
211 bt_listener_id listener_id;
212 bt_graph_add_listener_status status;
213 const char * const module_name =
214 "graph_add_port_added_listener() (Python)";
215
216 BT_ASSERT(graph);
217 BT_ASSERT(py_callable);
218
219 /*
220 * Behind the scene, we will be registering 4 different listeners and
221 * return all of their ids.
222 */
223 py_listener_ids = PyTuple_New(4);
224 if (!py_listener_ids) {
225 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
226 "Failed to allocate one PyTuple.");
227 goto error;
228 }
229
230 /* source output port */
231 status = bt_graph_add_source_component_output_port_added_listener(
232 graph, source_component_output_port_added_listener,
233 graph_listener_removed, py_callable, &listener_id);
234 if (status != __BT_FUNC_STATUS_OK) {
235 /*
236 * bt_graph_add_source_component_output_port_added_listener has
237 * already logged/appended an error cause.
238 */
239 goto error;
240 }
241
242 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
243 if (!py_listener_id) {
244 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
245 "Failed to allocate one PyLong.");
246 goto error;
247 }
248
249 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
250 py_listener_id = NULL;
251
252 /* filter input port */
253 status = bt_graph_add_filter_component_input_port_added_listener(
254 graph, filter_component_input_port_added_listener,
255 graph_listener_removed, py_callable, &listener_id);
256 if (status != __BT_FUNC_STATUS_OK) {
257 /*
258 * bt_graph_add_filter_component_input_port_added_listener has
259 * already logged/appended an error cause.
260 */
261 goto error;
262 }
263
264 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
265 if (!py_listener_id) {
266 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
267 "Failed to allocate one PyLong.");
268 goto error;
269 }
270
271 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
272 py_listener_id = NULL;
273
274 /* filter output port */
275 status = bt_graph_add_filter_component_output_port_added_listener(
276 graph, filter_component_output_port_added_listener,
277 graph_listener_removed, py_callable, &listener_id);
278 if (status != __BT_FUNC_STATUS_OK) {
279 /*
280 * bt_graph_add_filter_component_output_port_added_listener has
281 * already logged/appended an error cause.
282 */
283 goto error;
284 }
285
286 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
287 if (!py_listener_id) {
288 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
289 "Failed to allocate one PyLong.");
290 goto error;
291 }
292
293 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
294 py_listener_id = NULL;
295
296 /* sink input port */
297 status = bt_graph_add_sink_component_input_port_added_listener(
298 graph, sink_component_input_port_added_listener,
299 graph_listener_removed, py_callable, &listener_id);
300 if (status != __BT_FUNC_STATUS_OK) {
301 /*
302 * bt_graph_add_sink_component_input_port_added_listener has
303 * already logged/appended an error cause.
304 */
305 goto error;
306 }
307
308 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
309 if (!py_listener_id) {
310 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
311 "Failed to allocate one PyLong.");
312 goto error;
313 }
314
315
316 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
317 py_listener_id = NULL;
318
319 Py_INCREF(py_callable);
320 Py_INCREF(py_callable);
321 Py_INCREF(py_callable);
322 Py_INCREF(py_callable);
323
324 goto end;
325
326 error:
327 Py_XDECREF(py_listener_ids);
328 py_listener_ids = Py_None;
329 Py_INCREF(py_listener_ids);
330
331 end:
332
333 Py_XDECREF(py_listener_id);
334 return py_listener_ids;
335 }
336
337 static
338 bt_graph_listener_func_status ports_connected_listener(
339 const void *upstream_component,
340 swig_type_info *upstream_component_swig_type,
341 bt_component_class_type upstream_component_class_type,
342 const bt_port_output *upstream_port,
343 const void *downstream_component,
344 swig_type_info *downstream_component_swig_type,
345 bt_component_class_type downstream_component_class_type,
346 const bt_port_input *downstream_port,
347 void *py_callable)
348 {
349 PyObject *py_upstream_component_ptr = NULL;
350 PyObject *py_upstream_port_ptr = NULL;
351 PyObject *py_downstream_component_ptr = NULL;
352 PyObject *py_downstream_port_ptr = NULL;
353 PyObject *py_res = NULL;
354 bt_graph_listener_func_status status;
355
356 py_upstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(upstream_component),
357 upstream_component_swig_type, 0);
358 if (!py_upstream_component_ptr) {
359 BT_LOGF_STR("Failed to create upstream component SWIG pointer object.");
360 status = __BT_FUNC_STATUS_MEMORY_ERROR;
361 goto end;
362 }
363
364 py_upstream_port_ptr = SWIG_NewPointerObj(
365 SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port_output, 0);
366 if (!py_upstream_port_ptr) {
367 BT_LOGF_STR("Failed to create upstream port SWIG pointer object.");
368 status = __BT_FUNC_STATUS_MEMORY_ERROR;
369 goto end;
370 }
371
372 py_downstream_component_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(downstream_component),
373 downstream_component_swig_type, 0);
374 if (!py_downstream_component_ptr) {
375 BT_LOGF_STR("Failed to create downstream component SWIG pointer object.");
376 status = __BT_FUNC_STATUS_MEMORY_ERROR;
377 goto end;
378 }
379
380 py_downstream_port_ptr = SWIG_NewPointerObj(
381 SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port_input, 0);
382 if (!py_downstream_port_ptr) {
383 BT_LOGF_STR("Failed to create downstream port SWIG pointer object.");
384 status = __BT_FUNC_STATUS_MEMORY_ERROR;
385 goto end;
386 }
387
388 py_res = PyObject_CallFunction(py_callable, "(OiOOiO)",
389 py_upstream_component_ptr, upstream_component_class_type,
390 py_upstream_port_ptr,
391 py_downstream_component_ptr, downstream_component_class_type,
392 py_downstream_port_ptr);
393 if (!py_res) {
394 loge_exception("Graph's port connected listener (Python)",
395 BT_LOG_OUTPUT_LEVEL);
396 PyErr_Clear();
397 status = __BT_FUNC_STATUS_ERROR;
398 goto end;
399 }
400
401 BT_ASSERT(py_res == Py_None);
402 status = __BT_FUNC_STATUS_OK;
403
404 end:
405 Py_XDECREF(py_upstream_component_ptr);
406 Py_XDECREF(py_upstream_port_ptr);
407 Py_XDECREF(py_downstream_component_ptr);
408 Py_XDECREF(py_downstream_port_ptr);
409 Py_XDECREF(py_res);
410 return status;
411 }
412
413 static
414 bt_graph_listener_func_status source_filter_component_ports_connected_listener(
415 const bt_component_source *source_component,
416 const bt_component_filter *filter_component,
417 const bt_port_output *upstream_port,
418 const bt_port_input *downstream_port, void *py_callable)
419 {
420 return ports_connected_listener(
421 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
422 upstream_port,
423 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
424 downstream_port,
425 py_callable);
426 }
427
428 static
429 bt_graph_listener_func_status source_sink_component_ports_connected_listener(
430 const bt_component_source *source_component,
431 const bt_component_sink *sink_component,
432 const bt_port_output *upstream_port,
433 const bt_port_input *downstream_port, void *py_callable)
434 {
435 return ports_connected_listener(
436 source_component, SWIGTYPE_p_bt_component_source, BT_COMPONENT_CLASS_TYPE_SOURCE,
437 upstream_port,
438 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
439 downstream_port,
440 py_callable);
441 }
442
443 static
444 bt_graph_listener_func_status filter_filter_component_ports_connected_listener(
445 const bt_component_filter *filter_component_left,
446 const bt_component_filter *filter_component_right,
447 const bt_port_output *upstream_port,
448 const bt_port_input *downstream_port, void *py_callable)
449 {
450 return ports_connected_listener(
451 filter_component_left, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
452 upstream_port,
453 filter_component_right, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
454 downstream_port,
455 py_callable);
456 }
457
458 static
459 bt_graph_listener_func_status filter_sink_component_ports_connected_listener(
460 const bt_component_filter *filter_component,
461 const bt_component_sink *sink_component,
462 const bt_port_output *upstream_port,
463 const bt_port_input *downstream_port, void *py_callable)
464 {
465 return ports_connected_listener(
466 filter_component, SWIGTYPE_p_bt_component_filter, BT_COMPONENT_CLASS_TYPE_FILTER,
467 upstream_port,
468 sink_component, SWIGTYPE_p_bt_component_sink, BT_COMPONENT_CLASS_TYPE_SINK,
469 downstream_port,
470 py_callable);
471 }
472
473 static
474 PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph,
475 PyObject *py_callable)
476 {
477 PyObject *py_listener_ids = NULL;
478 PyObject *py_listener_id = NULL;
479 bt_listener_id listener_id;
480 bt_graph_add_listener_status status;
481 const char * const module_name =
482 "graph_add_ports_connected_listener() (Python)";
483
484 BT_ASSERT(graph);
485 BT_ASSERT(py_callable);
486
487 /* Behind the scene, we will be registering 4 different listeners and
488 * return all of their ids. */
489 py_listener_ids = PyTuple_New(4);
490 if (!py_listener_ids) {
491 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
492 "Failed to allocate one PyTuple.");
493 goto error;
494 }
495
496 /* source -> filter connection */
497 status = bt_graph_add_source_filter_component_ports_connected_listener(
498 graph, source_filter_component_ports_connected_listener,
499 graph_listener_removed, py_callable, &listener_id);
500 if (status != __BT_FUNC_STATUS_OK) {
501 /*
502 * bt_graph_add_source_filter_component_ports_connected_listener
503 * has already logged/appended an error cause.
504 */
505 goto error;
506 }
507
508 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
509 if (!py_listener_id) {
510 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
511 "Failed to allocate one PyLong.");
512 goto error;
513 }
514
515 PyTuple_SET_ITEM(py_listener_ids, 0, py_listener_id);
516 py_listener_id = NULL;
517
518 /* source -> sink connection */
519 status = bt_graph_add_source_sink_component_ports_connected_listener(
520 graph, source_sink_component_ports_connected_listener,
521 graph_listener_removed, py_callable, &listener_id);
522 if (status != __BT_FUNC_STATUS_OK) {
523 /*
524 * bt_graph_add_source_sink_component_ports_connected_listener
525 * has already logged/appended an error cause.
526 */
527 goto error;
528 }
529
530 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
531 if (!py_listener_id) {
532 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
533 "Failed to allocate one PyLong.");
534 goto error;
535 }
536
537 PyTuple_SET_ITEM(py_listener_ids, 1, py_listener_id);
538 py_listener_id = NULL;
539
540 /* filter -> filter connection */
541 status = bt_graph_add_filter_filter_component_ports_connected_listener(
542 graph, filter_filter_component_ports_connected_listener,
543 graph_listener_removed, py_callable, &listener_id);
544 if (status != __BT_FUNC_STATUS_OK) {
545 /*
546 * bt_graph_add_filter_filter_component_ports_connected_listener
547 * has already logged/appended an error cause.
548 */
549 goto error;
550 }
551
552 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
553 if (!py_listener_id) {
554 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
555 "Failed to allocate one PyLong.");
556 goto error;
557 }
558
559 PyTuple_SET_ITEM(py_listener_ids, 2, py_listener_id);
560 py_listener_id = NULL;
561
562 /* filter -> sink connection */
563 status = bt_graph_add_filter_sink_component_ports_connected_listener(
564 graph, filter_sink_component_ports_connected_listener,
565 graph_listener_removed, py_callable, &listener_id);
566 if (status != __BT_FUNC_STATUS_OK) {
567 /*
568 * bt_graph_add_filter_sink_component_ports_connected_listener
569 * has already logged/appended an error cause.
570 */
571 goto error;
572 }
573
574 py_listener_id = PyLong_FromUnsignedLongLong(listener_id);
575 if (!py_listener_id) {
576 BT_CURRENT_THREAD_ERROR_APPEND_CAUSE_FROM_UNKNOWN(module_name,
577 "Failed to allocate one PyLong.");
578 goto error;
579 }
580
581 PyTuple_SET_ITEM(py_listener_ids, 3, py_listener_id);
582 py_listener_id = NULL;
583
584 Py_INCREF(py_callable);
585 Py_INCREF(py_callable);
586 Py_INCREF(py_callable);
587 Py_INCREF(py_callable);
588
589 goto end;
590
591 error:
592 Py_XDECREF(py_listener_ids);
593 py_listener_ids = Py_None;
594 Py_INCREF(py_listener_ids);
595
596 end:
597
598 Py_XDECREF(py_listener_id);
599 return py_listener_ids;
600 }
601 %}
602
603 PyObject *bt_bt2_graph_add_port_added_listener(struct bt_graph *graph,
604 PyObject *py_callable);
605 PyObject *bt_bt2_graph_add_ports_connected_listener(struct bt_graph *graph,
606 PyObject *py_callable);
This page took 0.04245 seconds and 5 git commands to generate.