lib: pass log level to bt_query_executor_query()
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_component_class.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 /* From component-class-const.h */
26
27 typedef enum bt_component_class_status {
28 BT_COMPONENT_CLASS_STATUS_OK = 0,
29 BT_COMPONENT_CLASS_STATUS_NOMEM = -12,
30 } bt_component_class_status;
31
32 typedef enum bt_component_class_type {
33 BT_COMPONENT_CLASS_TYPE_SOURCE = 0,
34 BT_COMPONENT_CLASS_TYPE_FILTER = 1,
35 BT_COMPONENT_CLASS_TYPE_SINK = 2,
36 } bt_component_class_type;
37
38 extern const char *bt_component_class_get_name(
39 const bt_component_class *component_class);
40
41 extern const char *bt_component_class_get_description(
42 const bt_component_class *component_class);
43
44 extern const char *bt_component_class_get_help(
45 const bt_component_class *component_class);
46
47 extern bt_component_class_type bt_component_class_get_type(
48 const bt_component_class *component_class);
49
50 bt_bool bt_component_class_is_source(
51 const bt_component_class *component_class);
52
53 bt_bool bt_component_class_is_filter(
54 const bt_component_class *component_class);
55
56 bt_bool bt_component_class_is_sink(
57 const bt_component_class *component_class);
58
59 extern void bt_component_class_get_ref(
60 const bt_component_class *component_class);
61
62 extern void bt_component_class_put_ref(
63 const bt_component_class *component_class);
64
65 /* From component-class-source-const.h */
66
67 const bt_component_class *
68 bt_component_class_source_as_component_class_const(
69 const bt_component_class_source *comp_cls_source);
70
71 extern void bt_component_class_source_get_ref(
72 const bt_component_class_source *component_class_source);
73
74 extern void bt_component_class_source_put_ref(
75 const bt_component_class_source *component_class_source);
76
77 /* From component-class-source.h */
78
79 typedef bt_self_component_status
80 (*bt_component_class_source_init_method)(
81 bt_self_component_source *self_component,
82 const bt_value *params, void *init_method_data);
83
84 typedef void (*bt_component_class_source_finalize_method)(
85 bt_self_component_source *self_component);
86
87 typedef bt_self_message_iterator_status
88 (*bt_component_class_source_message_iterator_init_method)(
89 bt_self_message_iterator *message_iterator,
90 bt_self_component_source *self_component,
91 bt_self_component_port_output *port);
92
93 typedef void
94 (*bt_component_class_source_message_iterator_finalize_method)(
95 bt_self_message_iterator *message_iterator);
96
97 typedef bt_self_message_iterator_status
98 (*bt_component_class_source_message_iterator_next_method)(
99 bt_self_message_iterator *message_iterator,
100 bt_message_array_const msgs, uint64_t capacity,
101 uint64_t *count);
102
103 typedef bt_self_message_iterator_status
104 (*bt_component_class_source_message_iterator_seek_ns_from_origin_method)(
105 bt_self_message_iterator *message_iterator,
106 int64_t ns_from_origin);
107
108 typedef bt_self_message_iterator_status
109 (*bt_component_class_source_message_iterator_seek_beginning_method)(
110 bt_self_message_iterator *message_iterator);
111
112 typedef bt_bool
113 (*bt_component_class_source_message_iterator_can_seek_ns_from_origin_method)(
114 bt_self_message_iterator *message_iterator,
115 int64_t ns_from_origin);
116
117 typedef bt_bool
118 (*bt_component_class_source_message_iterator_can_seek_beginning_method)(
119 bt_self_message_iterator *message_iterator);
120
121 typedef bt_query_status (*bt_component_class_source_query_method)(
122 bt_self_component_class_source *comp_class,
123 const bt_query_executor *query_executor,
124 const char *object, const bt_value *params,
125 bt_logging_level log_level,
126 const bt_value **result);
127
128 typedef bt_self_component_status
129 (*bt_component_class_source_accept_output_port_connection_method)(
130 bt_self_component_source *self_component,
131 bt_self_component_port_output *self_port,
132 const bt_port_input *other_port);
133
134 typedef bt_self_component_status
135 (*bt_component_class_source_output_port_connected_method)(
136 bt_self_component_source *self_component,
137 bt_self_component_port_output *self_port,
138 const bt_port_input *other_port);
139
140 bt_component_class *bt_component_class_source_as_component_class(
141 bt_component_class_source *comp_cls_source);
142
143 extern
144 bt_component_class_source *bt_component_class_source_create(
145 const char *name,
146 bt_component_class_source_message_iterator_next_method method);
147
148 extern bt_component_class_status
149 bt_component_class_source_set_init_method(
150 bt_component_class_source *comp_class,
151 bt_component_class_source_init_method method);
152
153 extern bt_component_class_status
154 bt_component_class_source_set_finalize_method(
155 bt_component_class_source *comp_class,
156 bt_component_class_source_finalize_method method);
157
158 extern bt_component_class_status
159 bt_component_class_source_set_accept_output_port_connection_method(
160 bt_component_class_source *comp_class,
161 bt_component_class_source_accept_output_port_connection_method method);
162
163 extern bt_component_class_status
164 bt_component_class_source_set_output_port_connected_method(
165 bt_component_class_source *comp_class,
166 bt_component_class_source_output_port_connected_method method);
167
168 extern bt_component_class_status
169 bt_component_class_source_set_query_method(
170 bt_component_class_source *comp_class,
171 bt_component_class_source_query_method method);
172
173 extern bt_component_class_status
174 bt_component_class_source_set_message_iterator_init_method(
175 bt_component_class_source *comp_class,
176 bt_component_class_source_message_iterator_init_method method);
177
178 extern bt_component_class_status
179 bt_component_class_source_set_message_iterator_finalize_method(
180 bt_component_class_source *comp_class,
181 bt_component_class_source_message_iterator_finalize_method method);
182
183 extern bt_component_class_status
184 bt_component_class_source_set_message_iterator_seek_ns_from_origin_method(
185 bt_component_class_source *comp_class,
186 bt_component_class_source_message_iterator_seek_ns_from_origin_method method);
187
188 extern bt_component_class_status
189 bt_component_class_source_set_message_iterator_seek_beginning_method(
190 bt_component_class_source *comp_class,
191 bt_component_class_source_message_iterator_seek_beginning_method method);
192
193 extern bt_bool
194 bt_component_class_source_set_message_iterator_can_seek_ns_from_origin_method(
195 bt_component_class_source *comp_class,
196 bt_component_class_source_message_iterator_can_seek_ns_from_origin_method method);
197
198 extern bt_bool
199 bt_component_class_source_set_message_iterator_can_seek_beginning_method(
200 bt_component_class_source *comp_class,
201 bt_component_class_source_message_iterator_can_seek_beginning_method method);
202
203 /* From component-class-filter-const.h */
204
205 const bt_component_class *
206 bt_component_class_filter_as_component_class_const(
207 const bt_component_class_filter *comp_cls_filter);
208
209 extern void bt_component_class_filter_get_ref(
210 const bt_component_class_filter *component_class_filter);
211
212 extern void bt_component_class_filter_put_ref(
213 const bt_component_class_filter *component_class_filter);
214
215 /* From component-class-filter.h */
216
217 typedef bt_self_component_status
218 (*bt_component_class_filter_init_method)(
219 bt_self_component_filter *self_component,
220 const bt_value *params, void *init_method_data);
221
222 typedef void (*bt_component_class_filter_finalize_method)(
223 bt_self_component_filter *self_component);
224
225 typedef bt_self_message_iterator_status
226 (*bt_component_class_filter_message_iterator_init_method)(
227 bt_self_message_iterator *message_iterator,
228 bt_self_component_filter *self_component,
229 bt_self_component_port_output *port);
230
231 typedef void
232 (*bt_component_class_filter_message_iterator_finalize_method)(
233 bt_self_message_iterator *message_iterator);
234
235 typedef bt_self_message_iterator_status
236 (*bt_component_class_filter_message_iterator_next_method)(
237 bt_self_message_iterator *message_iterator,
238 bt_message_array_const msgs, uint64_t capacity,
239 uint64_t *count);
240
241 typedef bt_self_message_iterator_status
242 (*bt_component_class_filter_message_iterator_seek_ns_from_origin_method)(
243 bt_self_message_iterator *message_iterator,
244 int64_t ns_from_origin);
245
246 typedef bt_self_message_iterator_status
247 (*bt_component_class_filter_message_iterator_seek_beginning_method)(
248 bt_self_message_iterator *message_iterator);
249
250 typedef bt_bool
251 (*bt_component_class_filter_message_iterator_can_seek_ns_from_origin_method)(
252 bt_self_message_iterator *message_iterator,
253 int64_t ns_from_origin);
254
255 typedef bt_bool
256 (*bt_component_class_filter_message_iterator_can_seek_beginning_method)(
257 bt_self_message_iterator *message_iterator);
258
259 typedef bt_query_status
260 (*bt_component_class_filter_query_method)(
261 bt_self_component_class_filter *comp_class,
262 const bt_query_executor *query_executor,
263 const char *object, const bt_value *params,
264 bt_logging_level log_level,
265 const bt_value **result);
266
267 typedef bt_self_component_status
268 (*bt_component_class_filter_accept_input_port_connection_method)(
269 bt_self_component_filter *self_component,
270 bt_self_component_port_input *self_port,
271 const bt_port_output *other_port);
272
273 typedef bt_self_component_status
274 (*bt_component_class_filter_accept_output_port_connection_method)(
275 bt_self_component_filter *self_component,
276 bt_self_component_port_output *self_port,
277 const bt_port_input *other_port);
278
279 typedef bt_self_component_status
280 (*bt_component_class_filter_input_port_connected_method)(
281 bt_self_component_filter *self_component,
282 bt_self_component_port_input *self_port,
283 const bt_port_output *other_port);
284
285 typedef bt_self_component_status
286 (*bt_component_class_filter_output_port_connected_method)(
287 bt_self_component_filter *self_component,
288 bt_self_component_port_output *self_port,
289 const bt_port_input *other_port);
290
291 bt_component_class *bt_component_class_filter_as_component_class(
292 bt_component_class_filter *comp_cls_filter);
293
294 extern
295 bt_component_class_filter *bt_component_class_filter_create(
296 const char *name,
297 bt_component_class_filter_message_iterator_next_method method);
298
299 extern bt_component_class_status
300 bt_component_class_filter_set_init_method(
301 bt_component_class_filter *comp_class,
302 bt_component_class_filter_init_method method);
303
304 extern bt_component_class_status
305 bt_component_class_filter_set_finalize_method(
306 bt_component_class_filter *comp_class,
307 bt_component_class_filter_finalize_method method);
308
309 extern bt_component_class_status
310 bt_component_class_filter_set_accept_input_port_connection_method(
311 bt_component_class_filter *comp_class,
312 bt_component_class_filter_accept_input_port_connection_method method);
313
314 extern bt_component_class_status
315 bt_component_class_filter_set_accept_output_port_connection_method(
316 bt_component_class_filter *comp_class,
317 bt_component_class_filter_accept_output_port_connection_method method);
318
319 extern bt_component_class_status
320 bt_component_class_filter_set_input_port_connected_method(
321 bt_component_class_filter *comp_class,
322 bt_component_class_filter_input_port_connected_method method);
323
324 extern bt_component_class_status
325 bt_component_class_filter_set_output_port_connected_method(
326 bt_component_class_filter *comp_class,
327 bt_component_class_filter_output_port_connected_method method);
328
329 extern bt_component_class_status
330 bt_component_class_filter_set_query_method(
331 bt_component_class_filter *comp_class,
332 bt_component_class_filter_query_method method);
333
334 extern bt_component_class_status
335 bt_component_class_filter_set_message_iterator_init_method(
336 bt_component_class_filter *comp_class,
337 bt_component_class_filter_message_iterator_init_method method);
338
339 extern bt_component_class_status
340 bt_component_class_filter_set_message_iterator_finalize_method(
341 bt_component_class_filter *comp_class,
342 bt_component_class_filter_message_iterator_finalize_method method);
343
344 extern bt_component_class_status
345 bt_component_class_filter_set_message_iterator_seek_ns_from_origin_method(
346 bt_component_class_filter *comp_class,
347 bt_component_class_filter_message_iterator_seek_ns_from_origin_method method);
348
349 extern bt_component_class_status
350 bt_component_class_filter_set_message_iterator_seek_beginning_method(
351 bt_component_class_filter *comp_class,
352 bt_component_class_filter_message_iterator_seek_beginning_method method);
353
354 extern bt_bool
355 bt_component_class_filter_set_message_iterator_can_seek_ns_from_origin_method(
356 bt_component_class_filter *comp_class,
357 bt_component_class_filter_message_iterator_can_seek_ns_from_origin_method method);
358
359 extern bt_bool
360 bt_component_class_filter_set_message_iterator_can_seek_beginning_method(
361 bt_component_class_filter *comp_class,
362 bt_component_class_filter_message_iterator_can_seek_beginning_method method);
363
364 /* From component-class-sink-const.h */
365
366 const bt_component_class *
367 bt_component_class_sink_as_component_class_const(
368 const bt_component_class_sink *comp_cls_sink);
369
370 extern void bt_component_class_sink_get_ref(
371 const bt_component_class_sink *component_class_sink);
372
373 extern void bt_component_class_sink_put_ref(
374 const bt_component_class_sink *component_class_sink);
375
376 /* From component-class-sink.h */
377
378 typedef bt_self_component_status (*bt_component_class_sink_init_method)(
379 bt_self_component_sink *self_component,
380 const bt_value *params, void *init_method_data);
381
382 typedef void (*bt_component_class_sink_finalize_method)(
383 bt_self_component_sink *self_component);
384
385 typedef bt_query_status
386 (*bt_component_class_sink_query_method)(
387 bt_self_component_class_sink *comp_class,
388 const bt_query_executor *query_executor,
389 const char *object, const bt_value *params,
390 bt_logging_level log_level,
391 const bt_value **result);
392
393 typedef bt_self_component_status
394 (*bt_component_class_sink_accept_input_port_connection_method)(
395 bt_self_component_sink *self_component,
396 bt_self_component_port_input *self_port,
397 const bt_port_output *other_port);
398
399 typedef bt_self_component_status
400 (*bt_component_class_sink_input_port_connected_method)(
401 bt_self_component_sink *self_component,
402 bt_self_component_port_input *self_port,
403 const bt_port_output *other_port);
404
405 typedef bt_self_component_status
406 (*bt_component_class_sink_graph_is_configured_method)(
407 bt_self_component_sink *self_component);
408
409 typedef bt_self_component_status (*bt_component_class_sink_consume_method)(
410 bt_self_component_sink *self_component);
411
412 bt_component_class *bt_component_class_sink_as_component_class(
413 bt_component_class_sink *comp_cls_sink);
414
415 extern
416 bt_component_class_sink *bt_component_class_sink_create(
417 const char *name,
418 bt_component_class_sink_consume_method method);
419
420 extern bt_component_class_status bt_component_class_sink_set_init_method(
421 bt_component_class_sink *comp_class,
422 bt_component_class_sink_init_method method);
423
424 extern bt_component_class_status bt_component_class_sink_set_finalize_method(
425 bt_component_class_sink *comp_class,
426 bt_component_class_sink_finalize_method method);
427
428 extern bt_component_class_status
429 bt_component_class_sink_set_accept_input_port_connection_method(
430 bt_component_class_sink *comp_class,
431 bt_component_class_sink_accept_input_port_connection_method method);
432
433 extern bt_component_class_status
434 bt_component_class_sink_set_input_port_connected_method(
435 bt_component_class_sink *comp_class,
436 bt_component_class_sink_input_port_connected_method method);
437
438 extern bt_component_class_status
439 bt_component_class_sink_set_graph_is_configured_method(
440 bt_component_class_sink *comp_class,
441 bt_component_class_sink_graph_is_configured_method method);
442
443 extern bt_component_class_status bt_component_class_sink_set_query_method(
444 bt_component_class_sink *comp_class,
445 bt_component_class_sink_query_method method);
446
447 /* From self-component-class-source.h */
448
449 const bt_component_class_source *
450 bt_self_component_class_source_as_component_class_source(
451 bt_self_component_class_source *self_comp_cls_source);
452
453 /* From self-component-class-filter.h */
454
455 const bt_component_class_filter *
456 bt_self_component_class_filter_as_component_class_filter(
457 bt_self_component_class_filter *self_comp_cls_filter);
458
459 /* From self-component-class-sink.h */
460
461 const bt_component_class_sink *
462 bt_self_component_class_sink_as_component_class_sink(
463 bt_self_component_class_sink *self_comp_cls_sink);
464
465 %{
466 /*
467 * This hash table associates a BT component class object address to a
468 * user-defined Python class (PyObject *). The keys and values are NOT
469 * owned by this hash table. The Python class objects are owned by the
470 * Python module, which should not be unloaded until it is not possible
471 * to create a user Python component anyway.
472 *
473 * This hash table is written to when a user-defined Python component
474 * class is created by one of the bt_py3_component_class_*_create()
475 * functions.
476 *
477 * This function is read from when a user calls bt_component_create()
478 * with a component class pointer created by one of the functions above.
479 * In this case, the original Python class needs to be found to
480 * instantiate it and associate the created Python component object with
481 * a BT component object instance.
482 */
483
484 static GHashTable *bt_cc_ptr_to_py_cls;
485
486 static void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
487 PyObject *py_cls)
488 {
489 if (!bt_cc_ptr_to_py_cls) {
490 /*
491 * Lazy-initializing this GHashTable because GLib
492 * might not be initialized yet and it needs to be
493 * before we call g_hash_table_new()
494 */
495 BT_LOGD_STR("Creating native component class to Python component class hash table.");
496 bt_cc_ptr_to_py_cls = g_hash_table_new(g_direct_hash, g_direct_equal);
497 BT_ASSERT(bt_cc_ptr_to_py_cls);
498 }
499
500 g_hash_table_insert(bt_cc_ptr_to_py_cls, (gpointer) bt_cc,
501 (gpointer) py_cls);
502 }
503
504 static PyObject *lookup_cc_ptr_to_py_cls(const bt_component_class *bt_cc)
505 {
506 if (!bt_cc_ptr_to_py_cls) {
507 BT_LOGW("Cannot look up Python component class because hash table is NULL: "
508 "comp-cls-addr=%p", bt_cc);
509 return NULL;
510 }
511
512 return (PyObject *) g_hash_table_lookup(bt_cc_ptr_to_py_cls,
513 (gconstpointer) bt_cc);
514 }
515
516
517 /*
518 * Useful Python objects.
519 */
520
521 static PyObject *py_mod_bt2 = NULL;
522 static PyObject *py_mod_bt2_exc_error_type = NULL;
523 static PyObject *py_mod_bt2_exc_try_again_type = NULL;
524 static PyObject *py_mod_bt2_exc_stop_type = NULL;
525 static PyObject *py_mod_bt2_exc_port_connection_refused_type = NULL;
526 static PyObject *py_mod_bt2_exc_msg_iter_canceled_type = NULL;
527 static PyObject *py_mod_bt2_exc_invalid_query_object_type = NULL;
528 static PyObject *py_mod_bt2_exc_invalid_query_params_type = NULL;
529
530 static void bt_py3_cc_init_from_bt2(void)
531 {
532 /*
533 * This is called once the bt2 package is loaded.
534 *
535 * Those modules and functions are needed while the package is
536 * used. Loading them here is safe because we know the bt2
537 * package is imported, and we know that the user cannot use the
538 * code here without importing bt2 first.
539 */
540 py_mod_bt2 = PyImport_ImportModule("bt2");
541 BT_ASSERT(py_mod_bt2);
542 py_mod_bt2_exc_error_type =
543 PyObject_GetAttrString(py_mod_bt2, "Error");
544 BT_ASSERT(py_mod_bt2_exc_error_type);
545 py_mod_bt2_exc_try_again_type =
546 PyObject_GetAttrString(py_mod_bt2, "TryAgain");
547 BT_ASSERT(py_mod_bt2_exc_try_again_type);
548 py_mod_bt2_exc_stop_type =
549 PyObject_GetAttrString(py_mod_bt2, "Stop");
550 BT_ASSERT(py_mod_bt2_exc_stop_type);
551 py_mod_bt2_exc_port_connection_refused_type =
552 PyObject_GetAttrString(py_mod_bt2, "PortConnectionRefused");
553 BT_ASSERT(py_mod_bt2_exc_port_connection_refused_type);
554 py_mod_bt2_exc_invalid_query_object_type =
555 PyObject_GetAttrString(py_mod_bt2, "InvalidQueryObject");
556 BT_ASSERT(py_mod_bt2_exc_invalid_query_object_type);
557 py_mod_bt2_exc_invalid_query_params_type =
558 PyObject_GetAttrString(py_mod_bt2, "InvalidQueryParams");
559 BT_ASSERT(py_mod_bt2_exc_invalid_query_params_type);
560 }
561
562 static void bt_py3_cc_exit_handler(void)
563 {
564 /*
565 * This is an exit handler (set by the bt2 package).
566 *
567 * We only give back the references that we took in
568 * bt_py3_cc_init_from_bt2() here. The global variables continue
569 * to exist for the code of this file, but they are now borrowed
570 * references. If this code is executed, it means that somehow
571 * the modules are still loaded, so it should be safe to use
572 * them even without a strong reference.
573 *
574 * We cannot do this in the library's destructor because it
575 * gets executed once Python is already finalized.
576 */
577 Py_XDECREF(py_mod_bt2);
578 Py_XDECREF(py_mod_bt2_exc_error_type);
579 Py_XDECREF(py_mod_bt2_exc_try_again_type);
580 Py_XDECREF(py_mod_bt2_exc_stop_type);
581 Py_XDECREF(py_mod_bt2_exc_port_connection_refused_type);
582 Py_XDECREF(py_mod_bt2_exc_msg_iter_canceled_type);
583 Py_XDECREF(py_mod_bt2_exc_invalid_query_object_type);
584 Py_XDECREF(py_mod_bt2_exc_invalid_query_params_type);
585 }
586
587
588 /* Library destructor */
589
590 __attribute__((destructor))
591 static void bt_py3_native_comp_class_dtor(void) {
592 /* Destroy component class association hash table */
593 if (bt_cc_ptr_to_py_cls) {
594 BT_LOGD_STR("Destroying native component class to Python component class hash table.");
595 g_hash_table_destroy(bt_cc_ptr_to_py_cls);
596 }
597 }
598
599
600 // TODO: maybe we can wrap code in the Python methods (e.g. _query_from_native)
601 // in a try catch and print the error there instead, it would be simpler.
602 static
603 void bt2_py_loge_exception(void)
604 {
605 PyObject *type = NULL;
606 PyObject *value = NULL;
607 PyObject *traceback = NULL;
608 PyObject *traceback_module = NULL;
609 PyObject *format_exception_func = NULL;
610 PyObject *exc_str_list = NULL;
611 GString *msg_buf = NULL;
612 Py_ssize_t i;
613
614 BT_ASSERT(PyErr_Occurred() != NULL);
615
616 PyErr_Fetch(&type, &value, &traceback);
617
618 BT_ASSERT(type != NULL);
619
620 /*
621 * traceback can be NULL, when we fail to call a Python function from the
622 * native code (there is not Python stack at that point). E.g.:
623 *
624 * TypeError: _accept_port_connection_from_native() takes 3 positional arguments but 4 were given
625 */
626
627
628 /* Make sure `value` is what we expected - an instance of `type`. */
629 PyErr_NormalizeException(&type, &value, &traceback);
630
631 traceback_module = PyImport_ImportModule("traceback");
632 if (!traceback_module) {
633 BT_LOGE_STR("Failed to log Python exception (could not import traceback module).");
634 goto end;
635 }
636
637 format_exception_func = PyObject_GetAttrString(traceback_module,
638 traceback ? "format_exception" : "format_exception_only");
639 if (!format_exception_func) {
640 BT_LOGE_STR("Failed to log Python exception (could not find format_exception).");
641 goto end;
642 }
643
644 if (!PyCallable_Check(format_exception_func)) {
645 BT_LOGE_STR("Failed to log Python exception (format_exception is not callable).");
646 goto end;
647 }
648
649 exc_str_list = PyObject_CallFunctionObjArgs(format_exception_func, type, value, traceback, NULL);
650 if (!exc_str_list) {
651 PyErr_Print();
652 BT_LOGE_STR("Failed to log Python exception (call to format_exception failed).");
653 goto end;
654 }
655
656 msg_buf = g_string_new(NULL);
657
658 for (i = 0; i < PyList_Size(exc_str_list); i++) {
659 PyObject *exc_str = PyList_GetItem(exc_str_list, i);
660 const char *str = PyUnicode_AsUTF8(exc_str);
661 if (!str) {
662 BT_LOGE_STR("Failed to log Python exception (failed to convert exception to string).");
663 goto end;
664 }
665
666 g_string_append(msg_buf, str);
667 }
668
669 BT_LOGE_STR(msg_buf->str);
670
671 end:
672 if (msg_buf) {
673 g_string_free(msg_buf, TRUE);
674 }
675 Py_XDECREF(exc_str_list);
676 Py_XDECREF(format_exception_func);
677 Py_XDECREF(traceback_module);
678
679 /* PyErr_Restore takes our references. */
680 PyErr_Restore(type, value, traceback);
681 }
682
683 static bt_self_component_status bt_py3_exc_to_self_component_status(void)
684 {
685 bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
686 PyObject *exc = PyErr_Occurred();
687
688 if (!exc) {
689 goto end;
690 }
691
692 if (PyErr_GivenExceptionMatches(exc,
693 py_mod_bt2_exc_try_again_type)) {
694 status = BT_SELF_COMPONENT_STATUS_AGAIN;
695 } else if (PyErr_GivenExceptionMatches(exc,
696 py_mod_bt2_exc_stop_type)) {
697 status = BT_SELF_COMPONENT_STATUS_END;
698 } else if (PyErr_GivenExceptionMatches(exc,
699 py_mod_bt2_exc_port_connection_refused_type)) {
700 status = BT_SELF_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
701 } else {
702 bt2_py_loge_exception();
703 status = BT_SELF_COMPONENT_STATUS_ERROR;
704 }
705
706 end:
707 PyErr_Clear();
708 return status;
709 }
710
711 /* Component class proxy methods (delegate to the attached Python object) */
712
713 static bt_self_message_iterator_status
714 bt_py3_exc_to_self_message_iterator_status(void)
715 {
716 enum bt_self_message_iterator_status status =
717 BT_SELF_MESSAGE_ITERATOR_STATUS_OK;
718 PyObject *exc = PyErr_Occurred();
719
720 if (!exc) {
721 goto end;
722 }
723
724 if (PyErr_GivenExceptionMatches(exc, py_mod_bt2_exc_stop_type)) {
725 status = BT_SELF_MESSAGE_ITERATOR_STATUS_END;
726 } else if (PyErr_GivenExceptionMatches(exc, py_mod_bt2_exc_try_again_type)) {
727 status = BT_SELF_MESSAGE_ITERATOR_STATUS_AGAIN;
728 } else {
729 bt2_py_loge_exception();
730 status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
731 }
732
733 end:
734 PyErr_Clear();
735 return status;
736 }
737
738 static enum bt_query_status bt_py3_exc_to_query_status(void)
739 {
740 enum bt_query_status status = BT_QUERY_STATUS_OK;
741 PyObject *exc = PyErr_Occurred();
742
743 if (!exc) {
744 goto end;
745 }
746
747 if (PyErr_GivenExceptionMatches(exc,
748 py_mod_bt2_exc_invalid_query_object_type)) {
749 status = BT_QUERY_STATUS_INVALID_OBJECT;
750 } else if (PyErr_GivenExceptionMatches(exc,
751 py_mod_bt2_exc_invalid_query_params_type)) {
752 status = BT_QUERY_STATUS_INVALID_PARAMS;
753 } else if (PyErr_GivenExceptionMatches(exc,
754 py_mod_bt2_exc_try_again_type)) {
755 status = BT_QUERY_STATUS_AGAIN;
756 } else {
757 bt2_py_loge_exception();
758 status = BT_QUERY_STATUS_ERROR;
759 }
760
761 end:
762 PyErr_Clear();
763 return status;
764 }
765
766 static bt_self_component_status
767 bt_py3_component_class_init(
768 bt_self_component *self_component,
769 void *self_component_v,
770 swig_type_info *self_comp_cls_type_swig_type,
771 const bt_value *params,
772 void *init_method_data)
773 {
774 const bt_component *component = bt_self_component_as_component(self_component);
775 const bt_component_class *component_class = bt_component_borrow_class_const(component);
776 bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
777 PyObject *py_cls = NULL;
778 PyObject *py_comp = NULL;
779 PyObject *py_params_ptr = NULL;
780 PyObject *py_comp_ptr = NULL;
781
782 (void) init_method_data;
783
784 BT_ASSERT(self_component);
785 BT_ASSERT(self_component_v);
786 BT_ASSERT(self_comp_cls_type_swig_type);
787
788 /*
789 * Get the user-defined Python class which created this
790 * component's class in the first place (borrowed
791 * reference).
792 */
793 py_cls = lookup_cc_ptr_to_py_cls(component_class);
794 if (!py_cls) {
795 BT_LOGE("Cannot find Python class associated to native component class: "
796 "comp-cls-addr=%p", component_class);
797 goto error;
798 }
799
800 /* Parameters pointer -> SWIG pointer Python object */
801 py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
802 SWIGTYPE_p_bt_value, 0);
803 if (!py_params_ptr) {
804 BT_LOGE_STR("Failed to create a SWIG pointer object.");
805 goto error;
806 }
807
808 py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_component_v),
809 self_comp_cls_type_swig_type, 0);
810 if (!py_comp_ptr) {
811 BT_LOGE_STR("Failed to create a SWIG pointer object.");
812 goto error;
813 }
814
815 /*
816 * Do the equivalent of this:
817 *
818 * py_comp = py_cls._init_from_native(py_comp_ptr, py_params_ptr)
819 *
820 * _UserComponentType._init_from_native() calls the Python
821 * component object's __init__() function.
822 */
823 py_comp = PyObject_CallMethod(py_cls,
824 "_init_from_native", "(OO)", py_comp_ptr, py_params_ptr);
825 if (!py_comp) {
826 bt2_py_loge_exception();
827 BT_LOGE("Failed to call Python class's _init_from_native() method: "
828 "py-cls-addr=%p", py_cls);
829
830 goto error;
831 }
832
833 /*
834 * Our user Python component object is now fully created and
835 * initialized by the user. Since we just created it, this
836 * native component is its only (persistent) owner.
837 */
838 bt_self_component_set_data(self_component, py_comp);
839 py_comp = NULL;
840 goto end;
841
842 error:
843 status = BT_SELF_COMPONENT_STATUS_ERROR;
844
845 /*
846 * Clear any exception: we're returning a bad status anyway. If
847 * this call originated from Python (creation from a plugin's
848 * component class, for example), then the user gets an
849 * appropriate creation error.
850 */
851 PyErr_Clear();
852
853 end:
854 Py_XDECREF(py_comp);
855 Py_XDECREF(py_params_ptr);
856 Py_XDECREF(py_comp_ptr);
857 return status;
858 }
859
860 /*
861 * Method of bt_component_class_source to initialize a bt_self_component_source
862 * of that class.
863 */
864
865 static bt_self_component_status
866 bt_py3_component_class_source_init(bt_self_component_source *self_component_source,
867 const bt_value *params, void *init_method_data)
868 {
869 bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
870 return bt_py3_component_class_init(
871 self_component,
872 self_component_source,
873 SWIGTYPE_p_bt_self_component_source,
874 params, init_method_data);
875 }
876
877 static bt_self_component_status
878 bt_py3_component_class_filter_init(bt_self_component_filter *self_component_filter,
879 const bt_value *params, void *init_method_data)
880 {
881 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
882 return bt_py3_component_class_init(
883 self_component,
884 self_component_filter,
885 SWIGTYPE_p_bt_self_component_filter,
886 params, init_method_data);
887 }
888
889 static bt_self_component_status
890 bt_py3_component_class_sink_init(bt_self_component_sink *self_component_sink,
891 const bt_value *params, void *init_method_data)
892 {
893 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
894 return bt_py3_component_class_init(
895 self_component,
896 self_component_sink,
897 SWIGTYPE_p_bt_self_component_sink,
898 params, init_method_data);
899 }
900
901 static void bt_py3_component_class_finalize(bt_self_component *self_component)
902 {
903 PyObject *py_comp = bt_self_component_get_data(self_component);
904 BT_ASSERT(py_comp);
905
906 /* Call user's _finalize() method */
907 PyObject *py_method_result = PyObject_CallMethod(py_comp,
908 "_finalize", NULL);
909
910 if (PyErr_Occurred()) {
911 BT_LOGW("User's _finalize() method raised an exception: ignoring.");
912 }
913
914 /*
915 * Ignore any exception raised by the _finalize() method because
916 * it won't change anything at this point: the component is
917 * being destroyed anyway.
918 */
919 PyErr_Clear();
920 Py_XDECREF(py_method_result);
921 Py_DECREF(py_comp);
922 }
923
924 static void
925 bt_py3_component_class_source_finalize(bt_self_component_source *self_component_source)
926 {
927 bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
928 bt_py3_component_class_finalize(self_component);
929 }
930
931 static void
932 bt_py3_component_class_filter_finalize(bt_self_component_filter *self_component_filter)
933 {
934 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
935 bt_py3_component_class_finalize(self_component);
936 }
937
938 static void
939 bt_py3_component_class_sink_finalize(bt_self_component_sink *self_component_sink)
940 {
941 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
942 bt_py3_component_class_finalize(self_component);
943 }
944
945 static bt_self_component_status
946 bt_py3_component_class_accept_port_connection(
947 bt_self_component *self_component,
948 bt_self_component_port *self_component_port,
949 bt_port_type self_component_port_type,
950 const bt_port *other_port)
951 {
952 enum bt_self_component_status status;
953 PyObject *py_comp = NULL;
954 PyObject *py_self_port_ptr = NULL;
955 PyObject *py_other_port_ptr = NULL;
956 PyObject *py_method_result = NULL;
957
958 py_comp = bt_self_component_get_data(self_component);
959 BT_ASSERT(py_comp);
960
961 swig_type_info *self_component_port_swig_type = NULL;
962 swig_type_info *other_port_swig_type = NULL;
963 switch (self_component_port_type) {
964 case BT_PORT_TYPE_INPUT:
965 self_component_port_swig_type = SWIGTYPE_p_bt_self_component_port_input;
966 other_port_swig_type = SWIGTYPE_p_bt_port_output;
967 break;
968 case BT_PORT_TYPE_OUTPUT:
969 self_component_port_swig_type = SWIGTYPE_p_bt_self_component_port_output;
970 other_port_swig_type = SWIGTYPE_p_bt_port_input;
971 break;
972 }
973 BT_ASSERT(self_component_port_swig_type != NULL);
974 BT_ASSERT(other_port_swig_type != NULL);
975
976 py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_component_port),
977 self_component_port_swig_type, 0);
978 if (!py_self_port_ptr) {
979 BT_LOGE_STR("Failed to create a SWIG pointer object.");
980 goto error;
981 }
982
983 py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
984 other_port_swig_type, 0);
985 if (!py_other_port_ptr) {
986 BT_LOGE_STR("Failed to create a SWIG pointer object.");
987 goto error;
988 }
989
990 py_method_result = PyObject_CallMethod(py_comp,
991 "_accept_port_connection_from_native", "(OiO)", py_self_port_ptr,
992 self_component_port_type, py_other_port_ptr);
993
994 status = bt_py3_exc_to_self_component_status();
995 if (!py_method_result && status == BT_SELF_COMPONENT_STATUS_OK) {
996 /* Pretty sure this should never happen, but just in case */
997 BT_LOGE("User's _accept_port_connection() method failed without raising an exception: "
998 "status=%d", status);
999 goto error;
1000 }
1001
1002 if (status == BT_SELF_COMPONENT_STATUS_REFUSE_PORT_CONNECTION) {
1003 /*
1004 * Looks like the user method raised
1005 * PortConnectionRefused: accept this like if it
1006 * returned False.
1007 */
1008 goto end;
1009 } else if (status != BT_SELF_COMPONENT_STATUS_OK) {
1010 BT_LOGE("User's _accept_port_connection() raised an unexpected exception: "
1011 "status=%d", status);
1012 goto error;
1013 }
1014
1015 BT_ASSERT(PyBool_Check(py_method_result));
1016
1017 if (py_method_result == Py_True) {
1018 status = BT_SELF_COMPONENT_STATUS_OK;
1019 } else {
1020 status = BT_SELF_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
1021 }
1022
1023 goto end;
1024
1025 error:
1026 status = BT_SELF_COMPONENT_STATUS_ERROR;
1027
1028 /*
1029 * Clear any exception: we're returning a bad status anyway. If
1030 * this call originated from Python, then the user gets an
1031 * appropriate error.
1032 */
1033 PyErr_Clear();
1034
1035 end:
1036 Py_XDECREF(py_self_port_ptr);
1037 Py_XDECREF(py_other_port_ptr);
1038 Py_XDECREF(py_method_result);
1039 return status;
1040 }
1041
1042 static bt_self_component_status
1043 bt_py3_component_class_source_accept_output_port_connection(bt_self_component_source *self_component_source,
1044 bt_self_component_port_output *self_component_port_output,
1045 const bt_port_input *other_port_input)
1046 {
1047 bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
1048 bt_self_component_port *self_component_port = bt_self_component_port_output_as_self_component_port(self_component_port_output);
1049 const bt_port *other_port = bt_port_input_as_port_const(other_port_input);
1050 return bt_py3_component_class_accept_port_connection(self_component, self_component_port, BT_PORT_TYPE_OUTPUT, other_port);
1051 }
1052
1053 static bt_self_component_status
1054 bt_py3_component_class_filter_accept_input_port_connection(bt_self_component_filter *self_component_filter,
1055 bt_self_component_port_input *self_component_port_input,
1056 const bt_port_output *other_port_output)
1057 {
1058 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
1059 bt_self_component_port *self_component_port = bt_self_component_port_input_as_self_component_port(self_component_port_input);
1060 const bt_port *other_port = bt_port_output_as_port_const(other_port_output);
1061 return bt_py3_component_class_accept_port_connection(self_component, self_component_port, BT_PORT_TYPE_INPUT, other_port);
1062 }
1063
1064 static bt_self_component_status
1065 bt_py3_component_class_filter_accept_output_port_connection(bt_self_component_filter *self_component_filter,
1066 bt_self_component_port_output *self_component_port_output,
1067 const bt_port_input *other_port_input)
1068 {
1069 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
1070 bt_self_component_port *self_component_port = bt_self_component_port_output_as_self_component_port(self_component_port_output);
1071 const bt_port *other_port = bt_port_input_as_port_const(other_port_input);
1072 return bt_py3_component_class_accept_port_connection(self_component, self_component_port, BT_PORT_TYPE_OUTPUT, other_port);
1073 }
1074
1075 static bt_self_component_status
1076 bt_py3_component_class_sink_accept_input_port_connection(bt_self_component_sink *self_component_sink,
1077 bt_self_component_port_input *self_component_port_input,
1078 const bt_port_output *other_port_output)
1079 {
1080 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
1081 bt_self_component_port *self_component_port = bt_self_component_port_input_as_self_component_port(self_component_port_input);
1082 const bt_port *other_port = bt_port_output_as_port_const(other_port_output);
1083 return bt_py3_component_class_accept_port_connection(self_component, self_component_port, BT_PORT_TYPE_INPUT, other_port);
1084 }
1085
1086 static bt_self_component_status
1087 bt_py3_component_class_port_connected(
1088 bt_self_component *self_component,
1089 void *self_component_port,
1090 swig_type_info *self_component_port_swig_type,
1091 bt_port_type self_component_port_type,
1092 const void *other_port,
1093 swig_type_info *other_port_swig_type)
1094 {
1095 bt_self_component_status status;
1096 PyObject *py_comp = NULL;
1097 PyObject *py_self_port_ptr = NULL;
1098 PyObject *py_other_port_ptr = NULL;
1099 PyObject *py_method_result = NULL;
1100
1101 py_comp = bt_self_component_get_data(self_component);
1102 BT_ASSERT(py_comp);
1103
1104 py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_component_port),
1105 self_component_port_swig_type, 0);
1106 if (!py_self_port_ptr) {
1107 BT_LOGF_STR("Failed to create a SWIG pointer object.");
1108 status = BT_SELF_COMPONENT_STATUS_NOMEM;
1109 goto end;
1110 }
1111
1112 py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
1113 other_port_swig_type, 0);
1114 if (!py_other_port_ptr) {
1115 BT_LOGF_STR("Failed to create a SWIG pointer object.");
1116 status = BT_SELF_COMPONENT_STATUS_NOMEM;
1117 goto end; }
1118
1119 py_method_result = PyObject_CallMethod(py_comp,
1120 "_port_connected_from_native", "(OiO)", py_self_port_ptr,
1121 self_component_port_type, py_other_port_ptr);
1122
1123 BT_ASSERT(!py_method_result || py_method_result == Py_None);
1124
1125 status = bt_py3_exc_to_self_component_status();
1126
1127 end:
1128 Py_XDECREF(py_self_port_ptr);
1129 Py_XDECREF(py_other_port_ptr);
1130 Py_XDECREF(py_method_result);
1131
1132 return status;
1133 }
1134
1135 static bt_self_component_status
1136 bt_py3_component_class_source_output_port_connected(
1137 bt_self_component_source *self_component_source,
1138 bt_self_component_port_output *self_component_port_output,
1139 const bt_port_input *other_port_input)
1140 {
1141 bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
1142
1143 return bt_py3_component_class_port_connected(
1144 self_component,
1145 self_component_port_output,
1146 SWIGTYPE_p_bt_self_component_port_output,
1147 BT_PORT_TYPE_OUTPUT,
1148 other_port_input,
1149 SWIGTYPE_p_bt_port_input);
1150 }
1151
1152 static bt_self_component_status
1153 bt_py3_component_class_filter_input_port_connected(
1154 bt_self_component_filter *self_component_filter,
1155 bt_self_component_port_input *self_component_port_input,
1156 const bt_port_output *other_port_output)
1157 {
1158 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
1159
1160 return bt_py3_component_class_port_connected(
1161 self_component,
1162 self_component_port_input,
1163 SWIGTYPE_p_bt_self_component_port_input,
1164 BT_PORT_TYPE_INPUT,
1165 other_port_output,
1166 SWIGTYPE_p_bt_port_output);
1167 }
1168
1169 static bt_self_component_status
1170 bt_py3_component_class_filter_output_port_connected(
1171 bt_self_component_filter *self_component_filter,
1172 bt_self_component_port_output *self_component_port_output,
1173 const bt_port_input *other_port_input)
1174 {
1175 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
1176
1177 return bt_py3_component_class_port_connected(
1178 self_component,
1179 self_component_port_output,
1180 SWIGTYPE_p_bt_self_component_port_output,
1181 BT_PORT_TYPE_OUTPUT,
1182 other_port_input,
1183 SWIGTYPE_p_bt_port_input);
1184 }
1185
1186 static bt_self_component_status
1187 bt_py3_component_class_sink_input_port_connected(
1188 bt_self_component_sink *self_component_sink,
1189 bt_self_component_port_input *self_component_port_input,
1190 const bt_port_output *other_port_output)
1191 {
1192 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
1193
1194 return bt_py3_component_class_port_connected(
1195 self_component,
1196 self_component_port_input,
1197 SWIGTYPE_p_bt_self_component_port_input,
1198 BT_PORT_TYPE_INPUT,
1199 other_port_output,
1200 SWIGTYPE_p_bt_port_output);
1201 }
1202
1203 static bt_self_component_status
1204 bt_py3_component_class_sink_graph_is_configured(bt_self_component_sink *self_component_sink)
1205 {
1206 PyObject *py_comp = NULL;
1207 PyObject *py_method_result = NULL;
1208 bt_self_component_status status = BT_SELF_COMPONENT_STATUS_OK;
1209 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
1210
1211 py_comp = bt_self_component_get_data(self_component);
1212 py_method_result = PyObject_CallMethod(py_comp,
1213 "_graph_is_configured_from_native", NULL);
1214
1215 BT_ASSERT(!py_method_result || py_method_result == Py_None);
1216
1217 status = bt_py3_exc_to_self_component_status();
1218
1219 Py_XDECREF(py_method_result);
1220
1221 return status;
1222 }
1223
1224 static bt_query_status
1225 bt_py3_component_class_query(
1226 const bt_component_class *component_class,
1227 const bt_query_executor *query_executor,
1228 const char *object, const bt_value *params,
1229 bt_logging_level log_level,
1230 const bt_value **result)
1231 {
1232 PyObject *py_cls = NULL;
1233 PyObject *py_params_ptr = NULL;
1234 PyObject *py_query_exec_ptr = NULL;
1235 PyObject *py_query_func = NULL;
1236 PyObject *py_object = NULL;
1237 PyObject *py_results_addr = NULL;
1238 bt_query_status status = BT_QUERY_STATUS_OK;
1239
1240 py_cls = lookup_cc_ptr_to_py_cls(component_class);
1241 if (!py_cls) {
1242 BT_LOGE("Cannot find Python class associated to native component class: "
1243 "comp-cls-addr=%p", component_class);
1244 goto error;
1245 }
1246
1247 py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
1248 SWIGTYPE_p_bt_value, 0);
1249 if (!py_params_ptr) {
1250 BT_LOGE_STR("Failed to create a SWIG pointer object.");
1251 goto error;
1252 }
1253
1254 py_query_exec_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(query_executor),
1255 SWIGTYPE_p_bt_query_executor, 0);
1256 if (!py_query_exec_ptr) {
1257 BT_LOGE_STR("Failed to create a SWIG pointer object.");
1258 goto error;
1259 }
1260
1261 py_object = SWIG_FromCharPtr(object);
1262 if (!py_object) {
1263 BT_LOGE_STR("Failed to create a Python string.");
1264 goto error;
1265 }
1266
1267 py_results_addr = PyObject_CallMethod(py_cls,
1268 "_query_from_native", "(OOOi)", py_query_exec_ptr,
1269 py_object, py_params_ptr, (int) log_level);
1270
1271 if (!py_results_addr) {
1272 BT_LOGE("Failed to call Python class's _query_from_native() method: "
1273 "py-cls-addr=%p", py_cls);
1274 status = bt_py3_exc_to_query_status();
1275 goto end;
1276 }
1277
1278 /*
1279 * The returned object, on success, is an integer object
1280 * (PyLong) containing the address of a BT value object (new
1281 * reference).
1282 */
1283 *result = PyLong_AsVoidPtr(py_results_addr);
1284 BT_ASSERT(!PyErr_Occurred());
1285 BT_ASSERT(*result);
1286 goto end;
1287
1288 error:
1289 PyErr_Clear();
1290 status = BT_QUERY_STATUS_ERROR;
1291
1292 end:
1293 Py_XDECREF(py_params_ptr);
1294 Py_XDECREF(py_query_exec_ptr);
1295 Py_XDECREF(py_query_func);
1296 Py_XDECREF(py_object);
1297 Py_XDECREF(py_results_addr);
1298 return status;
1299 }
1300
1301 static bt_query_status
1302 bt_py3_component_class_source_query(
1303 bt_self_component_class_source *self_component_class_source,
1304 const bt_query_executor *query_executor,
1305 const char *object, const bt_value *params,
1306 bt_logging_level log_level,
1307 const bt_value **result)
1308 {
1309 const bt_component_class_source *component_class_source = bt_self_component_class_source_as_component_class_source(self_component_class_source);
1310 const bt_component_class *component_class = bt_component_class_source_as_component_class_const(component_class_source);
1311 return bt_py3_component_class_query(component_class, query_executor, object, params, log_level, result);
1312 }
1313
1314 static bt_query_status
1315 bt_py3_component_class_filter_query(
1316 bt_self_component_class_filter *self_component_class_filter,
1317 const bt_query_executor *query_executor,
1318 const char *object, const bt_value *params,
1319 bt_logging_level log_level,
1320 const bt_value **result)
1321 {
1322 const bt_component_class_filter *component_class_filter = bt_self_component_class_filter_as_component_class_filter(self_component_class_filter);
1323 const bt_component_class *component_class = bt_component_class_filter_as_component_class_const(component_class_filter);
1324 return bt_py3_component_class_query(component_class, query_executor, object, params, log_level, result);
1325 }
1326
1327 static bt_query_status
1328 bt_py3_component_class_sink_query(
1329 bt_self_component_class_sink *self_component_class_sink,
1330 const bt_query_executor *query_executor,
1331 const char *object, const bt_value *params,
1332 bt_logging_level log_level,
1333 const bt_value **result)
1334 {
1335 const bt_component_class_sink *component_class_sink = bt_self_component_class_sink_as_component_class_sink(self_component_class_sink);
1336 const bt_component_class *component_class = bt_component_class_sink_as_component_class_const(component_class_sink);
1337 return bt_py3_component_class_query(component_class, query_executor, object, params, log_level, result);
1338 }
1339
1340 static bt_self_message_iterator_status
1341 bt_py3_component_class_message_iterator_init(
1342 bt_self_message_iterator *self_message_iterator,
1343 bt_self_component *self_component,
1344 bt_self_component_port_output *self_component_port_output)
1345 {
1346 bt_self_message_iterator_status status = BT_SELF_MESSAGE_ITERATOR_STATUS_OK;
1347 PyObject *py_comp_cls = NULL;
1348 PyObject *py_iter_cls = NULL;
1349 PyObject *py_iter_ptr = NULL;
1350 PyObject *py_component_port_output_ptr = NULL;
1351 PyObject *py_init_method_result = NULL;
1352 PyObject *py_iter = NULL;
1353 PyObject *py_comp;
1354
1355 py_comp = bt_self_component_get_data(self_component);
1356
1357 /* Find user's Python message iterator class */
1358 py_comp_cls = PyObject_GetAttrString(py_comp, "__class__");
1359 if (!py_comp_cls) {
1360 BT_LOGE_STR("Cannot get Python object's `__class__` attribute.");
1361 goto error;
1362 }
1363
1364 py_iter_cls = PyObject_GetAttrString(py_comp_cls, "_iter_cls");
1365 if (!py_iter_cls) {
1366 BT_LOGE_STR("Cannot get Python class's `_iter_cls` attribute.");
1367 goto error;
1368 }
1369
1370 py_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_message_iterator),
1371 SWIGTYPE_p_bt_self_message_iterator, 0);
1372 if (!py_iter_ptr) {
1373 BT_LOGE_STR("Failed to create a SWIG pointer object.");
1374 goto error;
1375 }
1376
1377 /*
1378 * Create object with borrowed native message iterator
1379 * reference:
1380 *
1381 * py_iter = py_iter_cls.__new__(py_iter_cls, py_iter_ptr)
1382 */
1383 py_iter = PyObject_CallMethod(py_iter_cls, "__new__",
1384 "(OO)", py_iter_cls, py_iter_ptr);
1385 if (!py_iter) {
1386 BT_LOGE("Failed to call Python class's __new__() method: "
1387 "py-cls-addr=%p", py_iter_cls);
1388 bt2_py_loge_exception();
1389 goto error;
1390 }
1391
1392 /*
1393 * Initialize object:
1394 *
1395 * py_iter.__init__(self_output_port)
1396 *
1397 * through the _init_for_native helper static method.
1398 *
1399 * At this point, py_iter._ptr is set, so this initialization
1400 * function has access to self._component (which gives it the
1401 * user Python component object from which the iterator was
1402 * created).
1403 */
1404 py_component_port_output_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_component_port_output),
1405 SWIGTYPE_p_bt_self_component_port_output, 0);
1406 if (!py_component_port_output_ptr) {
1407 BT_LOGE_STR("Failed to create a SWIG pointer object.");
1408 goto error;
1409 }
1410
1411 py_init_method_result = PyObject_CallMethod(py_iter, "_init_from_native", "O", py_component_port_output_ptr);
1412 if (!py_init_method_result) {
1413 BT_LOGE_STR("User's __init__() method failed.");
1414 bt2_py_loge_exception();
1415 goto error;
1416 }
1417
1418 /*
1419 * Since the Python code can never instantiate a user-defined
1420 * message iterator class, the native message iterator
1421 * object does NOT belong to a user Python message iterator
1422 * object (borrowed reference). However this Python object is
1423 * owned by this native message iterator object.
1424 *
1425 * In the Python world, the lifetime of the native message
1426 * iterator is managed by a _GenericMessageIterator
1427 * instance:
1428 *
1429 * _GenericMessageIterator instance:
1430 * owns a native bt_message_iterator object (iter)
1431 * owns a _UserMessageIterator instance (py_iter)
1432 * self._ptr is a borrowed reference to the
1433 * native bt_private_connection_private_message_iterator
1434 * object (iter)
1435 */
1436 bt_self_message_iterator_set_data(self_message_iterator, py_iter);
1437 py_iter = NULL;
1438 goto end;
1439
1440 error:
1441 status = bt_py3_exc_to_self_message_iterator_status();
1442 if (status == BT_SELF_MESSAGE_ITERATOR_STATUS_OK) {
1443 /*
1444 * Looks like there wasn't any exception from the Python
1445 * side, but we're still in an error state here.
1446 */
1447 status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR;
1448 }
1449
1450 /*
1451 * Clear any exception: we're returning a bad status anyway. If
1452 * this call originated from Python, then the user gets an
1453 * appropriate creation error.
1454 */
1455 PyErr_Clear();
1456
1457 end:
1458 Py_XDECREF(py_comp_cls);
1459 Py_XDECREF(py_iter_cls);
1460 Py_XDECREF(py_iter_ptr);
1461 Py_XDECREF(py_component_port_output_ptr);
1462 Py_XDECREF(py_init_method_result);
1463 Py_XDECREF(py_iter);
1464 return status;
1465 }
1466
1467 static bt_self_message_iterator_status
1468 bt_py3_component_class_source_message_iterator_init(
1469 bt_self_message_iterator *self_message_iterator,
1470 bt_self_component_source *self_component_source,
1471 bt_self_component_port_output *self_component_port_output)
1472 {
1473 bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
1474 return bt_py3_component_class_message_iterator_init(self_message_iterator, self_component, self_component_port_output);
1475 }
1476
1477 static bt_self_message_iterator_status
1478 bt_py3_component_class_filter_message_iterator_init(
1479 bt_self_message_iterator *self_message_iterator,
1480 bt_self_component_filter *self_component_filter,
1481 bt_self_component_port_output *self_component_port_output)
1482 {
1483 bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
1484 return bt_py3_component_class_message_iterator_init(self_message_iterator, self_component, self_component_port_output);
1485 }
1486
1487 static void
1488 bt_py3_component_class_message_iterator_finalize(
1489 bt_self_message_iterator *message_iterator)
1490 {
1491 PyObject *py_message_iter = bt_self_message_iterator_get_data(message_iterator);
1492 PyObject *py_method_result = NULL;
1493
1494 BT_ASSERT(py_message_iter);
1495
1496 /* Call user's _finalize() method */
1497 py_method_result = PyObject_CallMethod(py_message_iter,
1498 "_finalize", NULL);
1499
1500 if (PyErr_Occurred()) {
1501 BT_LOGW("User's _finalize() method raised an exception: ignoring.");
1502 }
1503
1504 /*
1505 * Ignore any exception raised by the _finalize() method because
1506 * it won't change anything at this point: the component is
1507 * being destroyed anyway.
1508 */
1509 PyErr_Clear();
1510 Py_XDECREF(py_method_result);
1511 Py_DECREF(py_message_iter);
1512 }
1513
1514 /* Valid for both sources and filters. */
1515
1516 static bt_self_message_iterator_status
1517 bt_py3_component_class_message_iterator_next(
1518 bt_self_message_iterator *message_iterator,
1519 bt_message_array_const msgs, uint64_t capacity,
1520 uint64_t *count)
1521 {
1522 bt_self_message_iterator_status status = BT_SELF_MESSAGE_ITERATOR_STATUS_OK;
1523 PyObject *py_message_iter = bt_self_message_iterator_get_data(message_iterator);
1524 PyObject *py_method_result = NULL;
1525
1526 BT_ASSERT(py_message_iter);
1527 py_method_result = PyObject_CallMethod(py_message_iter,
1528 "_next_from_native", NULL);
1529 if (!py_method_result) {
1530 status = bt_py3_exc_to_self_message_iterator_status();
1531 BT_ASSERT(status != BT_SELF_MESSAGE_ITERATOR_STATUS_OK);
1532 goto end;
1533 }
1534
1535 /*
1536 * The returned object, on success, is an integer object
1537 * (PyLong) containing the address of a native message
1538 * object (which is now ours).
1539 */
1540 msgs[0] = PyLong_AsVoidPtr(py_method_result);
1541 *count = 1;
1542
1543 /* Clear potential overflow error; should never happen */
1544 BT_ASSERT(!PyErr_Occurred());
1545 goto end;
1546
1547 end:
1548 Py_XDECREF(py_method_result);
1549 return status;
1550 }
1551
1552 static bt_self_component_status
1553 bt_py3_component_class_sink_consume(bt_self_component_sink *self_component_sink)
1554 {
1555 bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
1556 PyObject *py_comp = bt_self_component_get_data(self_component);
1557 PyObject *py_method_result = NULL;
1558 bt_self_component_status status;
1559
1560 BT_ASSERT(py_comp);
1561 py_method_result = PyObject_CallMethod(py_comp,
1562 "_consume", NULL);
1563
1564 status = bt_py3_exc_to_self_component_status();
1565 if (!py_method_result && status == BT_SELF_COMPONENT_STATUS_OK) {
1566 /* Pretty sure this should never happen, but just in case */
1567 BT_LOGE("User's _consume() method failed without raising an exception: "
1568 "status=%d", status);
1569 status = BT_SELF_COMPONENT_STATUS_ERROR;
1570 }
1571
1572 Py_XDECREF(py_method_result);
1573 return status;
1574 }
1575
1576 static
1577 int bt_py3_component_class_set_help_and_desc(
1578 bt_component_class *component_class,
1579 const char *description, const char *help)
1580 {
1581 int ret;
1582
1583 if (description) {
1584 ret = bt_component_class_set_description(component_class, description);
1585 if (ret) {
1586 BT_LOGE("Cannot set component class's description: "
1587 "comp-cls-addr=%p", component_class);
1588 goto end;
1589 }
1590 }
1591
1592 if (help) {
1593 ret = bt_component_class_set_help(component_class, help);
1594 if (ret) {
1595 BT_LOGE("Cannot set component class's help text: "
1596 "comp-cls-addr=%p", component_class);
1597 goto end;
1598 }
1599 }
1600
1601 ret = 0;
1602
1603 end:
1604 return ret;
1605 }
1606
1607 static
1608 bt_component_class_source *bt_py3_component_class_source_create(
1609 PyObject *py_cls, const char *name, const char *description,
1610 const char *help)
1611 {
1612 bt_component_class_source *component_class_source;
1613 bt_component_class *component_class;
1614 int ret;
1615
1616 BT_ASSERT(py_cls);
1617
1618 component_class_source = bt_component_class_source_create(name,
1619 bt_py3_component_class_message_iterator_next);
1620 if (!component_class_source) {
1621 BT_LOGE_STR("Cannot create source component class.");
1622 goto end;
1623 }
1624
1625 component_class = bt_component_class_source_as_component_class(component_class_source);
1626
1627 if (bt_py3_component_class_set_help_and_desc(component_class, description, help)) {
1628 goto end;
1629 }
1630
1631 ret = bt_component_class_source_set_init_method(component_class_source, bt_py3_component_class_source_init);
1632 BT_ASSERT(ret == 0);
1633 ret = bt_component_class_source_set_finalize_method (component_class_source, bt_py3_component_class_source_finalize);
1634 BT_ASSERT(ret == 0);
1635 ret = bt_component_class_source_set_accept_output_port_connection_method(component_class_source,
1636 bt_py3_component_class_source_accept_output_port_connection);
1637 BT_ASSERT(ret == 0);
1638 ret = bt_component_class_source_set_output_port_connected_method(component_class_source,
1639 bt_py3_component_class_source_output_port_connected);
1640 BT_ASSERT(ret == 0);
1641 ret = bt_component_class_source_set_query_method(component_class_source, bt_py3_component_class_source_query);
1642 BT_ASSERT(ret == 0);
1643 ret = bt_component_class_source_set_message_iterator_init_method(
1644 component_class_source, bt_py3_component_class_source_message_iterator_init);
1645 BT_ASSERT(ret == 0);
1646 ret = bt_component_class_source_set_message_iterator_finalize_method(
1647 component_class_source, bt_py3_component_class_message_iterator_finalize);
1648 BT_ASSERT(ret == 0);
1649
1650 register_cc_ptr_to_py_cls(component_class, py_cls);
1651
1652 end:
1653 return component_class_source;
1654 }
1655
1656 static
1657 bt_component_class_filter *bt_py3_component_class_filter_create(
1658 PyObject *py_cls, const char *name, const char *description,
1659 const char *help)
1660 {
1661 bt_component_class *component_class;
1662 bt_component_class_filter *component_class_filter;
1663 int ret;
1664
1665 BT_ASSERT(py_cls);
1666
1667 component_class_filter = bt_component_class_filter_create(name,
1668 bt_py3_component_class_message_iterator_next);
1669 if (!component_class_filter) {
1670 BT_LOGE_STR("Cannot create filter component class.");
1671 goto end;
1672 }
1673
1674 component_class = bt_component_class_filter_as_component_class(component_class_filter);
1675
1676 if (bt_py3_component_class_set_help_and_desc(component_class, description, help)) {
1677 goto end;
1678 }
1679
1680 ret = bt_component_class_filter_set_init_method(component_class_filter, bt_py3_component_class_filter_init);
1681 BT_ASSERT(ret == 0);
1682 ret = bt_component_class_filter_set_finalize_method (component_class_filter, bt_py3_component_class_filter_finalize);
1683 BT_ASSERT(ret == 0);
1684 ret = bt_component_class_filter_set_accept_input_port_connection_method(component_class_filter,
1685 bt_py3_component_class_filter_accept_input_port_connection);
1686 BT_ASSERT(ret == 0);
1687 ret = bt_component_class_filter_set_accept_output_port_connection_method(component_class_filter,
1688 bt_py3_component_class_filter_accept_output_port_connection);
1689 BT_ASSERT(ret == 0);
1690 ret = bt_component_class_filter_set_input_port_connected_method(component_class_filter,
1691 bt_py3_component_class_filter_input_port_connected);
1692 BT_ASSERT(ret == 0);
1693 ret = bt_component_class_filter_set_output_port_connected_method(component_class_filter,
1694 bt_py3_component_class_filter_output_port_connected);
1695 BT_ASSERT(ret == 0);
1696 ret = bt_component_class_filter_set_query_method(component_class_filter, bt_py3_component_class_filter_query);
1697 BT_ASSERT(ret == 0);
1698 ret = bt_component_class_filter_set_message_iterator_init_method(
1699 component_class_filter, bt_py3_component_class_filter_message_iterator_init);
1700 BT_ASSERT(ret == 0);
1701 ret = bt_component_class_filter_set_message_iterator_finalize_method(
1702 component_class_filter, bt_py3_component_class_message_iterator_finalize);
1703 BT_ASSERT(ret == 0);
1704
1705 register_cc_ptr_to_py_cls(component_class, py_cls);
1706
1707 end:
1708 return component_class_filter;
1709 }
1710
1711 static
1712 bt_component_class_sink *bt_py3_component_class_sink_create(
1713 PyObject *py_cls, const char *name, const char *description,
1714 const char *help)
1715 {
1716 bt_component_class_sink *component_class_sink;
1717 bt_component_class *component_class;
1718 int ret;
1719
1720 BT_ASSERT(py_cls);
1721
1722 component_class_sink = bt_component_class_sink_create(name, bt_py3_component_class_sink_consume);
1723
1724 if (!component_class_sink) {
1725 BT_LOGE_STR("Cannot create sink component class.");
1726 goto end;
1727 }
1728
1729 component_class = bt_component_class_sink_as_component_class(component_class_sink);
1730
1731 if (bt_py3_component_class_set_help_and_desc(component_class, description, help)) {
1732 goto end;
1733 }
1734
1735 ret = bt_component_class_sink_set_init_method(component_class_sink, bt_py3_component_class_sink_init);
1736 BT_ASSERT(ret == 0);
1737 ret = bt_component_class_sink_set_finalize_method(component_class_sink, bt_py3_component_class_sink_finalize);
1738 BT_ASSERT(ret == 0);
1739 ret = bt_component_class_sink_set_accept_input_port_connection_method(component_class_sink,
1740 bt_py3_component_class_sink_accept_input_port_connection);
1741 BT_ASSERT(ret == 0);
1742 ret = bt_component_class_sink_set_input_port_connected_method(component_class_sink,
1743 bt_py3_component_class_sink_input_port_connected);
1744 BT_ASSERT(ret == 0);
1745 ret = bt_component_class_sink_set_graph_is_configured_method(component_class_sink,
1746 bt_py3_component_class_sink_graph_is_configured);
1747 BT_ASSERT(ret == 0);
1748 ret = bt_component_class_sink_set_query_method(component_class_sink, bt_py3_component_class_sink_query);
1749 BT_ASSERT(ret == 0);
1750
1751 register_cc_ptr_to_py_cls(component_class, py_cls);
1752
1753 end:
1754 return component_class_sink;
1755 }
1756 %}
1757
1758 struct bt_component_class_source *bt_py3_component_class_source_create(
1759 PyObject *py_cls, const char *name, const char *description,
1760 const char *help);
1761 struct bt_component_class_filter *bt_py3_component_class_filter_create(
1762 PyObject *py_cls, const char *name, const char *description,
1763 const char *help);
1764 struct bt_component_class_sink *bt_py3_component_class_sink_create(
1765 PyObject *py_cls, const char *name, const char *description,
1766 const char *help);
1767 void bt_py3_cc_init_from_bt2(void);
1768 void bt_py3_cc_exit_handler(void);
This page took 0.096819 seconds and 5 git commands to generate.