lib: make message iterator creation functions return a status
authorSimon Marchi <simon.marchi@efficios.com>
Thu, 5 Sep 2019 18:44:50 +0000 (14:44 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Fri, 6 Sep 2019 18:07:44 +0000 (14:07 -0400)
These two functions:

- bt_self_component_port_input_message_iterator_create_from_message_iterator
- bt_self_component_port_input_message_iterator_create_from_sink_component

call some user code at some point (the upstream message iterator's init
function), which can possibly fail (return ERROR).  However, they
currently just return the pointer to the created message iterator, no
status.  So on failure (NULL return value), the caller has to assume
that it translates to a MEMORY_ERROR, given that this is the semantic
for all creation functions that just return a pointer.

Therefore, change them to return a status, and return the pointer by
output parameter.

Wrappers for the Python bindings are necessary, because these functions
offer no guarantee about the value of the output pointer on failure.
But the argout typemap checks whether the pointer is NULL to know if the
function has failed or not.

A test is added in Python to check that if
_create_input_port_message_iterator (both in _UserMessageIterator and
_UserSinkComponent) fails, the error is propagated correctly.

Change-Id: I8151b7e9702d5210c28e2c4a9f323f1d990233ed
Signed-off-by: Simon Marchi <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2004
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
16 files changed:
include/babeltrace2/graph/self-component-port-input-message-iterator.h
src/bindings/python/bt2/bt2/component.py
src/bindings/python/bt2/bt2/message_iterator.py
src/bindings/python/bt2/bt2/native_bt_message_iterator.i
src/bindings/python/bt2/bt2/native_bt_message_iterator.i.h
src/lib/graph/component-class-sink-simple.c
src/lib/graph/iterator.c
src/plugins/ctf/fs-sink/fs-sink.c
src/plugins/lttng-utils/debug-info/debug-info.c
src/plugins/text/details/details.c
src/plugins/text/pretty/pretty.c
src/plugins/utils/counter/counter.c
src/plugins/utils/dummy/dummy.c
src/plugins/utils/muxer/muxer.c
src/plugins/utils/trimmer/trimmer.c
tests/bindings/python/bt2/test_message_iterator.py

index d4ad8b5966d2d334f2c4bf5179617246837009e5..8d5f29f79c19da9a196ce202b726a18922045e06 100644 (file)
 extern "C" {
 #endif
 
+typedef enum bt_self_component_port_input_message_iterator_create_from_message_iterator_status {
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK            = __BT_FUNC_STATUS_OK,
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_ERROR         = __BT_FUNC_STATUS_ERROR,
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_MEMORY_ERROR  = __BT_FUNC_STATUS_MEMORY_ERROR,
+} bt_self_component_port_input_message_iterator_create_from_message_iterator_status;
+
+typedef enum bt_self_component_port_input_message_iterator_create_from_sink_component_status {
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK              = __BT_FUNC_STATUS_OK,
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_ERROR           = __BT_FUNC_STATUS_ERROR,
+       BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_MEMORY_ERROR    = __BT_FUNC_STATUS_MEMORY_ERROR,
+} bt_self_component_port_input_message_iterator_create_from_sink_component_status;
+
 static inline
 bt_message_iterator *
 bt_self_component_port_input_message_iterator_as_message_iterator(
@@ -44,15 +56,17 @@ bt_self_component_port_input_message_iterator_as_message_iterator(
        return __BT_UPCAST(bt_message_iterator, iterator);
 }
 
-extern bt_self_component_port_input_message_iterator *
+extern bt_self_component_port_input_message_iterator_create_from_message_iterator_status
 bt_self_component_port_input_message_iterator_create_from_message_iterator(
                bt_self_message_iterator *self_msg_iter,
-               bt_self_component_port_input *input_port);
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator);
 
-extern bt_self_component_port_input_message_iterator *
+extern bt_self_component_port_input_message_iterator_create_from_sink_component_status
 bt_self_component_port_input_message_iterator_create_from_sink_component(
                bt_self_component_sink *self_comp,
-               bt_self_component_port_input *input_port);
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator);
 
 extern bt_component *
 bt_self_component_port_input_message_iterator_borrow_component(
index a0d29e272f43d5286cad50f47ff400c68eb33a2f..a4f80c613d98fb6dfe5239e332c92e9ce23634d5 100644 (file)
@@ -899,12 +899,11 @@ class _UserSinkComponent(_UserComponent, _SinkComponent):
     def _create_input_port_message_iterator(self, input_port):
         utils._check_type(input_port, bt2_port._UserComponentInputPort)
 
-        msg_iter_ptr = native_bt.self_component_port_input_message_iterator_create_from_sink_component(
+        status, msg_iter_ptr = native_bt.bt2_self_component_port_input_message_iterator_create_from_sink_component(
             self._bt_ptr, input_port._ptr
         )
-
-        if msg_iter_ptr is None:
-            raise bt2._MemoryError('cannot create message iterator object')
+        utils._handle_func_status(status, 'cannot create message iterator object')
+        assert msg_iter_ptr is not None
 
         return bt2_message_iterator._UserComponentInputPortMessageIterator(msg_iter_ptr)
 
index 5ccec738aad7a1b4cc7c66362cf4ed4c0f59c2fd..e0bd74923a0c50f4f3b6038b867d50495f503c97 100644 (file)
@@ -175,12 +175,11 @@ class _UserMessageIterator(_MessageIterator):
     def _create_input_port_message_iterator(self, input_port):
         utils._check_type(input_port, bt2_port._UserComponentInputPort)
 
-        msg_iter_ptr = native_bt.self_component_port_input_message_iterator_create_from_message_iterator(
+        status, msg_iter_ptr = native_bt.bt2_self_component_port_input_message_iterator_create_from_message_iterator(
             self._bt_ptr, input_port._ptr
         )
-
-        if msg_iter_ptr is None:
-            raise bt2._MemoryError('cannot create message iterator object')
+        utils._handle_func_status(status, 'cannot create message iterator object')
+        assert msg_iter_ptr is not None
 
         return _UserComponentInputPortMessageIterator(msg_iter_ptr)
 
index 6336a2143e1d1f54bad7bf09cf3f61f2bf3f70f6..7362bb7962d861a166689ed166759562f2788af9 100644 (file)
  * THE SOFTWARE.
  */
 
+/* Output argument typemap for message_iterator (always appends) */
+%typemap(in, numinputs=0)
+       (bt_self_component_port_input_message_iterator **)
+       (bt_self_component_port_input_message_iterator *temp_msg_iter = NULL) {
+       $1 = &temp_msg_iter;
+}
+
+%typemap(argout)
+       (bt_self_component_port_input_message_iterator **) {
+       if (*$1) {
+               /* SWIG_Python_AppendOutput() steals the created object */
+               $result = SWIG_Python_AppendOutput($result,
+                               SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
+                                       SWIGTYPE_p_bt_self_component_port_input_message_iterator, 0));
+       } else {
+               /* SWIG_Python_AppendOutput() steals Py_None */
+               Py_INCREF(Py_None);
+               $result = SWIG_Python_AppendOutput($result, Py_None);
+       }
+}
+
 %include <babeltrace2/graph/message-iterator.h>
 %include <babeltrace2/graph/self-component-port-input-message-iterator.h>
 %include <babeltrace2/graph/self-message-iterator.h>
 #include "native_bt_message_iterator.i.h"
 %}
 
+bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+bt_bt2_self_component_port_input_message_iterator_create_from_message_iterator(
+               bt_self_message_iterator *self_msg_iter,
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator);
+bt_self_component_port_input_message_iterator_create_from_sink_component_status
+bt_bt2_self_component_port_input_message_iterator_create_from_sink_component(
+               bt_self_component_sink *self_comp,
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator);
 PyObject *bt_bt2_get_user_component_from_user_msg_iter(
                bt_self_message_iterator *self_message_iterator);
 PyObject *bt_bt2_self_component_port_input_get_msg_range(
index f687dc9a480c01ff9eed498a432a812ba17d8420..76b2c876d26a03bbd2d42d15d633c318d4a6be1b 100644 (file)
  * THE SOFTWARE.
  */
 
+bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+bt_bt2_self_component_port_input_message_iterator_create_from_message_iterator(
+               bt_self_message_iterator *self_msg_iter,
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator)
+{
+       bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+               status;
+
+       status = bt_self_component_port_input_message_iterator_create_from_message_iterator(
+               self_msg_iter, input_port, message_iterator);
+
+       if (status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
+               *message_iterator = NULL;
+       }
+
+       return status;
+}
+
+bt_self_component_port_input_message_iterator_create_from_sink_component_status
+bt_bt2_self_component_port_input_message_iterator_create_from_sink_component(
+               bt_self_component_sink *self_comp,
+               bt_self_component_port_input *input_port,
+               bt_self_component_port_input_message_iterator **message_iterator)
+{
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               status;
+
+       status = bt_self_component_port_input_message_iterator_create_from_sink_component(
+               self_comp, input_port, message_iterator);
+
+       if (status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               *message_iterator = NULL;
+       }
+
+       return status;
+}
+
 static PyObject *bt_bt2_get_user_component_from_user_msg_iter(
                bt_self_message_iterator *self_message_iterator)
 {
index 797ee50a61d1ffae98d49fa47dbe5549d2344ade..cbf6781186d904b0d4e8d7bf8fbd2e062549fb06 100644 (file)
@@ -109,7 +109,9 @@ enum bt_component_class_sink_graph_is_configured_method_status
 simple_sink_graph_is_configured(
        bt_self_component_sink *self_comp)
 {
-       int status = BT_FUNC_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        struct simple_sink_data *data = bt_self_component_get_data(
                bt_self_component_sink_as_self_component(self_comp));
 
@@ -122,36 +124,40 @@ simple_sink_graph_is_configured(
                BT_LIB_LOGE_APPEND_CAUSE(
                        "Simple sink component's input port is not connected: "
                        "%![comp-]+c, %![port-]+p", self_comp, self_port);
-               status = BT_FUNC_STATUS_ERROR;
+               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
                goto end;
        }
 
        BT_ASSERT(data);
-       data->msg_iter =
-               bt_self_component_port_input_message_iterator_create_from_sink_component(
-                       self_comp, self_port);
-       if (!data->msg_iter) {
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component(
+               self_comp, self_port, &data->msg_iter);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
                BT_LIB_LOGE_APPEND_CAUSE(
                        "Cannot create input port message iterator: "
                        "%![comp-]+c, %![port-]+p", self_comp, self_port);
-               status = BT_FUNC_STATUS_MEMORY_ERROR;
+               status = (int) msg_iter_status;
                goto end;
        }
 
        if (data->init_method_data.init_func) {
+               bt_graph_simple_sink_component_init_func_status init_status;
+
                /* Call user's initialization function */
-               status = data->init_method_data.init_func(data->msg_iter,
+               init_status = data->init_method_data.init_func(data->msg_iter,
                        data->init_method_data.user_data);
-               if (status != BT_FUNC_STATUS_OK) {
+               if (init_status != BT_GRAPH_SIMPLE_SINK_COMPONENT_INIT_FUNC_STATUS_OK) {
                        BT_LIB_LOGW_APPEND_CAUSE(
                                "Simple sink component's user's initialization function failed: "
                                "status=%s, %![comp-]+c, %![port-]+p",
-                               bt_common_func_status_string(status),
+                               bt_common_func_status_string(init_status),
                                self_comp, self_port);
+                       status = (int) init_status;
                        goto end;
                }
        }
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+
 end:
        return status;
 }
index 21cd6eb80d9c802cc4d9314d32985f95d1bc3830..1030a4651390ce1a6c176b7fc2077cc5601cfc59 100644 (file)
@@ -288,10 +288,10 @@ bt_bool can_seek_beginning_true(
 }
 
 static
-struct bt_self_component_port_input_message_iterator *
-create_self_component_input_port_message_iterator(
+int create_self_component_input_port_message_iterator(
                struct bt_self_message_iterator *self_downstream_msg_iter,
-               struct bt_self_component_port_input *self_port)
+               struct bt_self_component_port_input *self_port,
+               struct bt_self_component_port_input_message_iterator **message_iterator)
 {
        typedef enum bt_component_class_message_iterator_init_method_status (*init_method_t)(
                        void *, void *, void *);
@@ -306,7 +306,9 @@ create_self_component_input_port_message_iterator(
        struct bt_component *comp;
        struct bt_component *upstream_comp;
        struct bt_component_class *upstream_comp_cls;
+       int status;
 
+       BT_ASSERT_PRE_NON_NULL(message_iterator, "Created message iterator");
        BT_ASSERT_PRE_NON_NULL(port, "Input port");
        comp = bt_port_borrow_component_inline(port);
        BT_ASSERT_PRE(bt_port_is_connected(port),
@@ -338,6 +340,7 @@ create_self_component_input_port_message_iterator(
                BT_LIB_LOGE_APPEND_CAUSE(
                        "Failed to allocate one self component input port "
                        "message iterator.");
+               status = BT_FUNC_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -346,6 +349,7 @@ create_self_component_input_port_message_iterator(
        iterator->msgs = g_ptr_array_new();
        if (!iterator->msgs) {
                BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
+               status = BT_FUNC_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -354,12 +358,14 @@ create_self_component_input_port_message_iterator(
        iterator->auto_seek.msgs = g_queue_new();
        if (!iterator->auto_seek.msgs) {
                BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GQueue.");
+               status = BT_FUNC_STATUS_MEMORY_ERROR;
                goto error;
        }
 
        iterator->upstream_msg_iters = g_ptr_array_new();
        if (!iterator->upstream_msg_iters) {
                BT_LIB_LOGE_APPEND_CAUSE("Failed to allocate a GPtrArray.");
+               status = BT_FUNC_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -471,6 +477,7 @@ create_self_component_input_port_message_iterator(
                                "%![iter-]+i, status=%s",
                                iterator,
                                bt_common_func_status_string(iter_status));
+                       status = iter_status;
                        goto error;
                }
        }
@@ -493,33 +500,38 @@ create_self_component_input_port_message_iterator(
        BT_LIB_LOGI("Created message iterator on self component input port: "
                "%![up-port-]+p, %![up-comp-]+c, %![iter-]+i",
                upstream_port, upstream_comp, iterator);
+
+       *message_iterator = iterator;
+       status = BT_FUNC_STATUS_OK;
        goto end;
 
 error:
        BT_OBJECT_PUT_REF_AND_RESET(iterator);
 
 end:
-       return iterator;
+       return status;
 }
 
-struct bt_self_component_port_input_message_iterator *
+bt_self_component_port_input_message_iterator_create_from_message_iterator_status
 bt_self_component_port_input_message_iterator_create_from_message_iterator(
                struct bt_self_message_iterator *self_msg_iter,
-               struct bt_self_component_port_input *input_port)
+               struct bt_self_component_port_input *input_port,
+               struct bt_self_component_port_input_message_iterator **message_iterator)
 {
        BT_ASSERT_PRE_NON_NULL(self_msg_iter, "Message iterator");
        return create_self_component_input_port_message_iterator(self_msg_iter,
-               input_port);
+               input_port, message_iterator);
 }
 
-struct bt_self_component_port_input_message_iterator *
+bt_self_component_port_input_message_iterator_create_from_sink_component_status
 bt_self_component_port_input_message_iterator_create_from_sink_component(
                struct bt_self_component_sink *self_comp,
-               struct bt_self_component_port_input *input_port)
+               struct bt_self_component_port_input *input_port,
+               struct bt_self_component_port_input_message_iterator **message_iterator)
 {
        BT_ASSERT_PRE_NON_NULL(self_comp, "Sink component");
        return create_self_component_input_port_message_iterator(NULL,
-               input_port);
+               input_port, message_iterator);
 }
 
 void *bt_self_message_iterator_get_data(
index 077a08b29522bd866d8d085e49c3b658cea0fee5..977cc143745887456b8fb242708a25b1868c7537 100644 (file)
@@ -1095,24 +1095,27 @@ end:
 }
 
 BT_HIDDEN
-bt_component_class_sink_graph_is_configured_method_status ctf_fs_sink_graph_is_configured(
+bt_component_class_sink_graph_is_configured_method_status
+ctf_fs_sink_graph_is_configured(
                bt_self_component_sink *self_comp)
 {
-       bt_component_class_sink_graph_is_configured_method_status status =
-               BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        struct fs_sink_comp *fs_sink = bt_self_component_get_data(
                        bt_self_component_sink_as_self_component(self_comp));
 
-       fs_sink->upstream_iter =
+       msg_iter_status =
                bt_self_component_port_input_message_iterator_create_from_sink_component(
                        self_comp,
                        bt_self_component_sink_borrow_input_port_by_name(
-                               self_comp, in_port_name));
-       if (!fs_sink->upstream_iter) {
-               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
+                               self_comp, in_port_name), &fs_sink->upstream_iter);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               status = (int) msg_iter_status;
                goto end;
        }
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
 end:
        return status;
 }
index 545a4eee8c1c929ad6aef23a1d5605998c3fb6a2..c2fda777295ee198d268c4fa84da9152809e75e4 100644 (file)
@@ -1960,8 +1960,9 @@ bt_component_class_message_iterator_init_method_status debug_info_msg_iter_init(
                bt_self_component_filter *self_comp_flt,
                bt_self_component_port_output *self_port)
 {
-       bt_component_class_message_iterator_init_method_status status =
-               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+       bt_component_class_message_iterator_init_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+               msg_iter_status;
        struct bt_self_component_port_input *input_port = NULL;
        bt_self_component_port_input_message_iterator *upstream_iterator = NULL;
        struct debug_info_msg_iter *debug_info_msg_iter = NULL;
@@ -1990,10 +1991,10 @@ bt_component_class_message_iterator_init_method_status debug_info_msg_iter_init(
        debug_info_msg_iter->self_comp = self_comp;
 
        /* Create an iterator on the upstream component. */
-       upstream_iterator = bt_self_component_port_input_message_iterator_create_from_message_iterator(
-               self_msg_iter, input_port);
-       if (!upstream_iterator) {
-               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_message_iterator(
+               self_msg_iter, input_port, &upstream_iterator);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
+               status = (int) msg_iter_status;
                goto error;
        }
 
@@ -2031,6 +2032,7 @@ bt_component_class_message_iterator_init_method_status debug_info_msg_iter_init(
        bt_self_message_iterator_set_data(self_msg_iter, debug_info_msg_iter);
        debug_info_msg_iter->input_iterator = self_msg_iter;
 
+       status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
        goto end;
 
 error:
index 85cfb017534bfefef6aed7e0a06918619889c997..582230f0fb3dde3a4083880ed2c9952d70554747 100644 (file)
@@ -434,8 +434,9 @@ BT_HIDDEN
 bt_component_class_sink_graph_is_configured_method_status
 details_graph_is_configured(bt_self_component_sink *comp)
 {
-       bt_component_class_sink_graph_is_configured_method_status status =
-               BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        bt_self_component_port_input_message_iterator *iterator;
        struct details_comp *details_comp;
        bt_self_component_port_input *in_port;
@@ -453,17 +454,19 @@ details_graph_is_configured(bt_self_component_sink *comp)
                goto end;
        }
 
-       iterator = bt_self_component_port_input_message_iterator_create_from_sink_component(
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component(
                comp, bt_self_component_sink_borrow_input_port_by_name(comp,
-                       in_port_name));
-       if (!iterator) {
-               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR;
+                       in_port_name), &iterator);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               status = (int) msg_iter_status;
                goto end;
        }
 
        BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_MOVE_REF(
                details_comp->msg_iter, iterator);
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+
 end:
        return status;
 }
index d0e1fbbc6e1c356252a159f5ff8cbcbb997c91ea..2bf9f7b741390156d7476796935997bbe8e57ac5 100644 (file)
@@ -154,21 +154,26 @@ BT_HIDDEN
 bt_component_class_sink_graph_is_configured_method_status
 pretty_graph_is_configured(bt_self_component_sink *comp)
 {
-       bt_component_class_sink_graph_is_configured_method_status status =
-               BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        struct pretty_component *pretty;
 
        pretty = bt_self_component_get_data(
                        bt_self_component_sink_as_self_component(comp));
        BT_ASSERT(pretty);
        BT_ASSERT(!pretty->iterator);
-       pretty->iterator = bt_self_component_port_input_message_iterator_create_from_sink_component(
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component(
                comp, bt_self_component_sink_borrow_input_port_by_name(comp,
-                       in_port_name));
-       if (!pretty->iterator) {
-               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_ERROR;
+                       in_port_name), &pretty->iterator);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               status = (int) msg_iter_status;
+               goto end;
        }
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+
+end:
        return status;
 }
 
index 2ad601675054183bc44a4eb6a29eded3b333c07d..bf0e4a575f03d99499c84051889f4009a38dfba0 100644 (file)
@@ -217,25 +217,28 @@ bt_component_class_sink_graph_is_configured_method_status
 counter_graph_is_configured(
                bt_self_component_sink *comp)
 {
-       bt_component_class_sink_graph_is_configured_method_status status =
-               BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        struct counter *counter;
        bt_self_component_port_input_message_iterator *iterator;
 
        counter = bt_self_component_get_data(
                bt_self_component_sink_as_self_component(comp));
        BT_ASSERT(counter);
-       iterator = bt_self_component_port_input_message_iterator_create_from_sink_component(
+
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component(
                comp, bt_self_component_sink_borrow_input_port_by_name(comp,
-                       in_port_name));
-       if (!iterator) {
-               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR;
+                       in_port_name), &iterator);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               status = (int) msg_iter_status;
                goto end;
        }
 
        BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_MOVE_REF(
                counter->msg_iter, iterator);
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
 end:
        return status;
 }
index 681db3b65cce0349b7bcb36583a5e735c2a1cf39..d41551de78c075ae5f62ae66da0848868933593a 100644 (file)
@@ -91,25 +91,28 @@ BT_HIDDEN
 bt_component_class_sink_graph_is_configured_method_status dummy_graph_is_configured(
                bt_self_component_sink *comp)
 {
-       bt_component_class_sink_graph_is_configured_method_status status =
-               BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+       bt_component_class_sink_graph_is_configured_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_sink_component_status
+               msg_iter_status;
        struct dummy *dummy;
        bt_self_component_port_input_message_iterator *iterator;
 
        dummy = bt_self_component_get_data(
                bt_self_component_sink_as_self_component(comp));
        BT_ASSERT(dummy);
-       iterator = bt_self_component_port_input_message_iterator_create_from_sink_component(
+       msg_iter_status = bt_self_component_port_input_message_iterator_create_from_sink_component(
                comp, bt_self_component_sink_borrow_input_port_by_name(comp,
-                       in_port_name));
-       if (!iterator) {
-               status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_MEMORY_ERROR;
+                       in_port_name), &iterator);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_SINK_COMPONENT_STATUS_OK) {
+               status = (int) msg_iter_status;
                goto end;
        }
 
        BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_MOVE_REF(
                dummy->msg_iter, iterator);
 
+       status = BT_COMPONENT_CLASS_SINK_GRAPH_IS_CONFIGURED_METHOD_STATUS_OK;
+
 end:
        return status;
 }
index f67955d1d94de57e385120b2df08b79b197950ee..328d3a28334a46737837a9a18ed3ea78bdbf0918 100644 (file)
@@ -430,16 +430,17 @@ void muxer_finalize(bt_self_component_filter *self_comp)
 }
 
 static
-bt_self_component_port_input_message_iterator *
+bt_self_component_port_input_message_iterator_create_from_message_iterator_status
 create_msg_iter_on_input_port(struct muxer_comp *muxer_comp,
                struct muxer_msg_iter *muxer_msg_iter,
-               bt_self_component_port_input *self_port)
+               bt_self_component_port_input *self_port,
+               bt_self_component_port_input_message_iterator **msg_iter)
 {
        const bt_port *port = bt_self_component_port_as_port(
                bt_self_component_port_input_as_self_component_port(
                        self_port));
-       bt_self_component_port_input_message_iterator *msg_iter =
-               NULL;
+       bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+               status;
 
        BT_ASSERT(port);
        BT_ASSERT(bt_port_is_connected(port));
@@ -447,9 +448,9 @@ create_msg_iter_on_input_port(struct muxer_comp *muxer_comp,
        // TODO: Advance the iterator to >= the time of the latest
        //       returned message by the muxer message
        //       iterator which creates it.
-       msg_iter = bt_self_component_port_input_message_iterator_create_from_message_iterator(
-               muxer_msg_iter->self_msg_iter, self_port);
-       if (!msg_iter) {
+       status = bt_self_component_port_input_message_iterator_create_from_message_iterator(
+               muxer_msg_iter->self_msg_iter, self_port, msg_iter);
+       if (status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
                BT_COMP_LOGE("Cannot create upstream message iterator on input port: "
                        "port-addr=%p, port-name=\"%s\"",
                        port, bt_port_get_name(port));
@@ -461,7 +462,7 @@ create_msg_iter_on_input_port(struct muxer_comp *muxer_comp,
                port, bt_port_get_name(port), msg_iter);
 
 end:
-       return msg_iter;
+       return status;
 }
 
 static
@@ -1241,12 +1242,13 @@ void destroy_muxer_msg_iter(struct muxer_msg_iter *muxer_msg_iter)
 }
 
 static
-int muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp,
+bt_component_class_message_iterator_init_method_status
+muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp,
                struct muxer_msg_iter *muxer_msg_iter)
 {
        int64_t count;
        int64_t i;
-       int ret = 0;
+       bt_component_class_message_iterator_init_method_status status;
 
        count = bt_component_filter_get_input_port_count(
                bt_self_component_filter_as_component_filter(
@@ -1255,6 +1257,7 @@ int muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp,
                BT_COMP_LOGD("No input port to initialize for muxer component's message iterator: "
                        "muxer-comp-addr=%p, muxer-msg-iter-addr=%p",
                        muxer_comp, muxer_msg_iter);
+               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
                goto end;
        }
 
@@ -1264,6 +1267,9 @@ int muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp,
                        bt_self_component_filter_borrow_input_port_by_index(
                                muxer_comp->self_comp_flt, i);
                const bt_port *port;
+               bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+                       msg_iter_status;
+               int int_status;
 
                BT_ASSERT(self_port);
                port = bt_self_component_port_as_port(
@@ -1276,27 +1282,29 @@ int muxer_msg_iter_init_upstream_iterators(struct muxer_comp *muxer_comp,
                        continue;
                }
 
-               upstream_msg_iter = create_msg_iter_on_input_port(muxer_comp,
-                       muxer_msg_iter, self_port);
-               if (!upstream_msg_iter) {
+               msg_iter_status = create_msg_iter_on_input_port(muxer_comp,
+                       muxer_msg_iter, self_port, &upstream_msg_iter);
+               if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
                        /* create_msg_iter_on_input_port() logs errors */
-                       BT_ASSERT(!upstream_msg_iter);
-                       ret = -1;
+                       status = (int) msg_iter_status;
                        goto end;
                }
 
-               ret = muxer_msg_iter_add_upstream_msg_iter(muxer_msg_iter,
+               int_status = muxer_msg_iter_add_upstream_msg_iter(muxer_msg_iter,
                        upstream_msg_iter);
                bt_self_component_port_input_message_iterator_put_ref(
                        upstream_msg_iter);
-               if (ret) {
+               if (int_status) {
+                       status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
                        /* muxer_msg_iter_add_upstream_msg_iter() logs errors */
                        goto end;
                }
        }
 
+       status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+
 end:
-       return ret;
+       return status;
 }
 
 BT_HIDDEN
@@ -1307,9 +1315,7 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
 {
        struct muxer_comp *muxer_comp = NULL;
        struct muxer_msg_iter *muxer_msg_iter = NULL;
-       bt_component_class_message_iterator_init_method_status status =
-               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
-       int ret;
+       bt_component_class_message_iterator_init_method_status status;
 
        muxer_comp = bt_self_component_get_data(
                bt_self_component_filter_as_self_component(self_comp));
@@ -1327,6 +1333,7 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
                BT_COMP_LOGE("Recursive initialization of muxer component's message iterator: "
                        "comp-addr=%p, muxer-comp-addr=%p, msg-iter-addr=%p",
                        self_comp, muxer_comp, self_msg_iter);
+               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
                goto error;
        }
 
@@ -1334,6 +1341,7 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
        muxer_msg_iter = g_new0(struct muxer_msg_iter, 1);
        if (!muxer_msg_iter) {
                BT_COMP_LOGE_STR("Failed to allocate one muxer component's message iterator.");
+               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -1345,6 +1353,7 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
                        (GDestroyNotify) destroy_muxer_upstream_msg_iter);
        if (!muxer_msg_iter->active_muxer_upstream_msg_iters) {
                BT_COMP_LOGE_STR("Failed to allocate a GPtrArray.");
+               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
@@ -1353,17 +1362,18 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
                        (GDestroyNotify) destroy_muxer_upstream_msg_iter);
        if (!muxer_msg_iter->ended_muxer_upstream_msg_iters) {
                BT_COMP_LOGE_STR("Failed to allocate a GPtrArray.");
+               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
                goto error;
        }
 
-       ret = muxer_msg_iter_init_upstream_iterators(muxer_comp,
+       status = muxer_msg_iter_init_upstream_iterators(muxer_comp,
                muxer_msg_iter);
-       if (ret) {
+       if (status) {
                BT_COMP_LOGE("Cannot initialize connected input ports for muxer component's message iterator: "
                        "comp-addr=%p, muxer-comp-addr=%p, "
                        "muxer-msg-iter-addr=%p, msg-iter-addr=%p, ret=%d",
                        self_comp, muxer_comp, muxer_msg_iter,
-                       self_msg_iter, ret);
+                       self_msg_iter, status);
                goto error;
        }
 
@@ -1377,7 +1387,6 @@ bt_component_class_message_iterator_init_method_status muxer_msg_iter_init(
 error:
        destroy_muxer_msg_iter(muxer_msg_iter);
        bt_self_message_iterator_set_data(self_msg_iter, NULL);
-       status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
 
 end:
        muxer_comp->initializing_muxer_msg_iter = false;
index c821e0b41e75b269d1f45858d15c3cc12837408f..b18d976b0fe9ad8905de5307a8d6006d62ad7f3d 100644 (file)
@@ -631,7 +631,10 @@ end:
 static
 void destroy_trimmer_iterator(struct trimmer_iterator *trimmer_it)
 {
-       BT_ASSERT(trimmer_it);
+       if (!trimmer_it) {
+               goto end;
+       }
+
        bt_self_component_port_input_message_iterator_put_ref(
                trimmer_it->upstream_iter);
 
@@ -644,6 +647,8 @@ void destroy_trimmer_iterator(struct trimmer_iterator *trimmer_it)
        }
 
        g_free(trimmer_it);
+end:
+       return;
 }
 
 static
@@ -661,14 +666,15 @@ bt_component_class_message_iterator_init_method_status trimmer_msg_iter_init(
                bt_self_component_filter *self_comp,
                bt_self_component_port_output *port)
 {
-       bt_component_class_message_iterator_init_method_status status =
-               BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+       bt_component_class_message_iterator_init_method_status status;
+       bt_self_component_port_input_message_iterator_create_from_message_iterator_status
+               msg_iter_status;
        struct trimmer_iterator *trimmer_it;
 
        trimmer_it = g_new0(struct trimmer_iterator, 1);
        if (!trimmer_it) {
                status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
-               goto end;
+               goto error;
        }
 
        trimmer_it->trimmer_comp = bt_self_component_get_data(
@@ -688,20 +694,20 @@ bt_component_class_message_iterator_init_method_status trimmer_msg_iter_init(
 
        trimmer_it->begin = trimmer_it->trimmer_comp->begin;
        trimmer_it->end = trimmer_it->trimmer_comp->end;
-       trimmer_it->upstream_iter =
+       msg_iter_status =
                bt_self_component_port_input_message_iterator_create_from_message_iterator(
                        self_msg_iter,
                        bt_self_component_filter_borrow_input_port_by_name(
-                               self_comp, in_port_name));
-       if (!trimmer_it->upstream_iter) {
-               status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_ERROR;
-               goto end;
+                               self_comp, in_port_name), &trimmer_it->upstream_iter);
+       if (msg_iter_status != BT_SELF_COMPONENT_PORT_INPUT_MESSAGE_ITERATOR_CREATE_FROM_MESSAGE_ITERATOR_STATUS_OK) {
+               status = (int) msg_iter_status;
+               goto error;
        }
 
        trimmer_it->output_messages = g_queue_new();
        if (!trimmer_it->output_messages) {
                status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
-               goto end;
+               goto error;
        }
 
        trimmer_it->stream_states = g_hash_table_new_full(g_direct_hash,
@@ -709,17 +715,19 @@ bt_component_class_message_iterator_init_method_status trimmer_msg_iter_init(
                (GDestroyNotify) destroy_trimmer_iterator_stream_state);
        if (!trimmer_it->stream_states) {
                status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_MEMORY_ERROR;
-               goto end;
+               goto error;
        }
 
        trimmer_it->self_msg_iter = self_msg_iter;
        bt_self_message_iterator_set_data(self_msg_iter, trimmer_it);
 
-end:
-       if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK && trimmer_it) {
-               destroy_trimmer_iterator(trimmer_it);
-       }
+       status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_INIT_METHOD_STATUS_OK;
+       goto end;
 
+error:
+       destroy_trimmer_iterator(trimmer_it);
+
+end:
        return status;
 }
 
index 9635672fe792b409e53bf81cb8bc68036be81439..c317ae432f7764a7bfdea06f329d422341c163d2 100644 (file)
@@ -115,6 +115,45 @@ class UserMessageIteratorTestCase(unittest.TestCase):
         self.assertTrue(src_iter_initialized)
         self.assertTrue(flt_iter_initialized)
 
+    def test_create_user_error(self):
+        # This tests both error handling by
+        # _UserSinkComponent._create_input_port_message_iterator
+        # and _UserMessageIterator._create_input_port_message_iterator, as they
+        # are both used in the graph.
+        class MySourceIter(bt2._UserMessageIterator):
+            def __init__(self, self_port_output):
+                raise ValueError('Very bad error')
+
+        class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter):
+            def __init__(self, params, obj):
+                self._add_output_port('out')
+
+        class MyFilterIter(bt2._UserMessageIterator):
+            def __init__(self, self_port_output):
+                # This is expected to raise because of the error in
+                # MySourceIter.__init__.
+                self._create_input_port_message_iterator(
+                    self._component._input_ports['in']
+                )
+
+        class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter):
+            def __init__(self, params, obj):
+                self._add_input_port('in')
+                self._add_output_port('out')
+
+        graph = self._create_graph(MySource, MyFilter)
+
+        with self.assertRaises(bt2._Error) as ctx:
+            graph.run()
+
+        exc = ctx.exception
+        cause = exc[0]
+
+        self.assertIsInstance(cause, bt2._MessageIteratorErrorCause)
+        self.assertEqual(cause.component_name, 'src')
+        self.assertEqual(cause.component_output_port_name, 'out')
+        self.assertIn('ValueError: Very bad error', cause.message)
+
     def test_finalize(self):
         class MyIter(bt2._UserMessageIterator):
             def _user_finalize(self):
This page took 0.044762 seconds and 4 git commands to generate.