bt2: free port user data when finalizing components
[babeltrace.git] / src / bindings / python / bt2 / bt2 / native_bt_component_class.i.h
index 23e7d06a0dbcc5f1c831fa7b1bff588f490c2ef7..6ea021dee6adf02fd86f2bb6bdc86e8adde9b795 100644 (file)
@@ -505,16 +505,15 @@ void component_class_finalize(bt_self_component *self_component)
                bt_logging_level log_level = get_self_component_log_level(
                        self_component);
 
-               BT_COMP_LOG_CUR_LVL(BT_LOG_WARNING, log_level, self_component,
-                       "User component's _user_finalize() method raised an exception: ignoring:");
-               logw_exception(log_level);
-
                /*
                 * Ignore any exception raised by the _user_finalize() method
                 * because it won't change anything at this point: the component
                 * is being destroyed anyway.
                 */
-               PyErr_Clear();
+               BT_COMP_LOG_CUR_LVL(BT_LOG_WARNING, log_level, self_component,
+                       "User component's _user_finalize() method raised an exception: ignoring:");
+               logw_exception_clear(log_level);
+
                goto end;
        }
 
@@ -525,25 +524,126 @@ end:
        Py_DECREF(py_comp);
 }
 
+/* Decref the Python object in the user data associated to `port`. */
+
+static
+void delete_port_user_data(bt_self_component_port *port)
+{
+       Py_DECREF(bt_self_component_port_get_data(port));
+}
+
+static
+void delete_port_input_user_data(bt_self_component_port_input *port_input)
+{
+       bt_self_component_port *port =
+               bt_self_component_port_input_as_self_component_port(port_input);
+
+       delete_port_user_data(port);
+}
+
+static
+void delete_port_output_user_data(bt_self_component_port_output *port_output)
+{
+       bt_self_component_port *port =
+               bt_self_component_port_output_as_self_component_port(port_output);
+
+       delete_port_user_data(port);
+}
+
 static
 void component_class_source_finalize(bt_self_component_source *self_component_source)
 {
-       bt_self_component *self_component = bt_self_component_source_as_self_component(self_component_source);
+       uint64_t i;
+       bt_self_component *self_component;
+       const bt_component_source *component_source;
+
+       self_component = bt_self_component_source_as_self_component(
+               self_component_source);
+       component_source = bt_self_component_source_as_component_source(
+               self_component_source);
+
        component_class_finalize(self_component);
+
+       /*
+        * Free the user data Python object attached to the port.  The
+        * corresponding incref was done by the `void *` typemap in
+        * native_bt_port.i.
+        */
+       for (i = 0; i < bt_component_source_get_output_port_count(component_source); i++) {
+               bt_self_component_port_output *port_output;
+
+               port_output = bt_self_component_source_borrow_output_port_by_index(
+                       self_component_source, i);
+
+               delete_port_output_user_data(port_output);
+       }
 }
 
 static
 void component_class_filter_finalize(bt_self_component_filter *self_component_filter)
 {
-       bt_self_component *self_component = bt_self_component_filter_as_self_component(self_component_filter);
+       uint64_t i;
+       bt_self_component *self_component;
+       const bt_component_filter *component_filter;
+
+       self_component = bt_self_component_filter_as_self_component(
+               self_component_filter);
+       component_filter = bt_self_component_filter_as_component_filter(
+               self_component_filter);
+
        component_class_finalize(self_component);
+
+       /*
+        * Free the user data Python object attached to the port.  The
+        * corresponding incref was done by the `void *` typemap in
+        * native_bt_port.i.
+        */
+       for (i = 0; i < bt_component_filter_get_input_port_count(component_filter); i++) {
+               bt_self_component_port_input *port_input;
+
+               port_input = bt_self_component_filter_borrow_input_port_by_index(
+                       self_component_filter, i);
+
+               delete_port_input_user_data(port_input);
+       }
+
+       for (i = 0; i < bt_component_filter_get_output_port_count(component_filter); i++) {
+               bt_self_component_port_output *port_output;
+
+               port_output = bt_self_component_filter_borrow_output_port_by_index(
+                       self_component_filter, i);
+
+               delete_port_output_user_data(port_output);
+       }
 }
 
 static
 void component_class_sink_finalize(bt_self_component_sink *self_component_sink)
 {
-       bt_self_component *self_component = bt_self_component_sink_as_self_component(self_component_sink);
+       uint64_t i;
+       bt_self_component *self_component;
+       const bt_component_sink *component_sink;
+
+       self_component = bt_self_component_sink_as_self_component(
+               self_component_sink);
+       component_sink = bt_self_component_sink_as_component_sink(
+               self_component_sink);
+
        component_class_finalize(self_component);
+
+       /*
+        * Free the user data Python object attached to the port.  The
+        * corresponding incref was done by the `void *` typemap in
+        * native_bt_port.i.
+        */
+       for (i = 0; i < bt_component_sink_get_input_port_count(component_sink); i++) {
+               bt_self_component_port_input *port_input;
+
+               port_input = bt_self_component_sink_borrow_input_port_by_index(
+                       self_component_sink, i);
+
+               delete_port_input_user_data(port_input);
+       }
 }
 
 static
@@ -1181,17 +1281,15 @@ void component_class_message_iterator_finalize(
                bt_logging_level log_level = get_self_component_log_level(
                        self_comp);
 
-               BT_COMP_LOG_CUR_LVL(BT_LOG_WARNING, log_level, self_comp,
-                       "User's _user_finalize() method raised an exception: ignoring:");
-               logw_exception(get_self_message_iterator_log_level(
-                       message_iterator));
-
                /*
                 * Ignore any exception raised by the _user_finalize() method
                 * because it won't change anything at this point: the component
                 * is being destroyed anyway.
                 */
-               PyErr_Clear();
+               BT_COMP_LOG_CUR_LVL(BT_LOG_WARNING, log_level, self_comp,
+                       "User's _user_finalize() method raised an exception: ignoring:");
+               logw_exception_clear(get_self_message_iterator_log_level(
+                       message_iterator));
        }
 
        Py_XDECREF(py_method_result);
@@ -1211,8 +1309,7 @@ component_class_message_iterator_next(
        PyObject *py_message_iter = bt_self_message_iterator_get_data(message_iterator);
        PyObject *py_method_result = NULL;
 
-       BT_ASSERT(py_message_iter);
-
+       BT_ASSERT_DBG(py_message_iter);
        py_method_result = PyObject_CallMethod(py_message_iter,
                "_bt_next_from_native", NULL);
        if (!py_method_result) {
@@ -1229,7 +1326,7 @@ component_class_message_iterator_next(
        *count = 1;
 
        /* Overflow errors should never happen. */
-       BT_ASSERT(!PyErr_Occurred());
+       BT_ASSERT_DBG(!PyErr_Occurred());
 
        status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK;
 
@@ -1247,7 +1344,7 @@ component_class_sink_consume(bt_self_component_sink *self_component_sink)
        PyObject *py_method_result = NULL;
        bt_component_class_sink_consume_method_status status;
 
-       BT_ASSERT(py_comp);
+       BT_ASSERT_DBG(py_comp);
 
        py_method_result = PyObject_CallMethod(py_comp,
                "_user_consume", NULL);
This page took 0.025077 seconds and 4 git commands to generate.