From: Simon Marchi Date: Thu, 5 Sep 2019 18:44:50 +0000 (-0400) Subject: lib: make message iterator creation functions return a status X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=e803df70898ad94809e70156df2e6bdfd4b1ee2a lib: make message iterator creation functions return a status 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 Reviewed-on: https://review.lttng.org/c/babeltrace/+/2004 Tested-by: jenkins Reviewed-by: Francis Deslauriers --- diff --git a/include/babeltrace2/graph/self-component-port-input-message-iterator.h b/include/babeltrace2/graph/self-component-port-input-message-iterator.h index d4ad8b59..8d5f29f7 100644 --- a/include/babeltrace2/graph/self-component-port-input-message-iterator.h +++ b/include/babeltrace2/graph/self-component-port-input-message-iterator.h @@ -36,6 +36,18 @@ 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( diff --git a/src/bindings/python/bt2/bt2/component.py b/src/bindings/python/bt2/bt2/component.py index a0d29e27..a4f80c61 100644 --- a/src/bindings/python/bt2/bt2/component.py +++ b/src/bindings/python/bt2/bt2/component.py @@ -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) diff --git a/src/bindings/python/bt2/bt2/message_iterator.py b/src/bindings/python/bt2/bt2/message_iterator.py index 5ccec738..e0bd7492 100644 --- a/src/bindings/python/bt2/bt2/message_iterator.py +++ b/src/bindings/python/bt2/bt2/message_iterator.py @@ -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) diff --git a/src/bindings/python/bt2/bt2/native_bt_message_iterator.i b/src/bindings/python/bt2/bt2/native_bt_message_iterator.i index 6336a214..7362bb79 100644 --- a/src/bindings/python/bt2/bt2/native_bt_message_iterator.i +++ b/src/bindings/python/bt2/bt2/native_bt_message_iterator.i @@ -22,6 +22,27 @@ * 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 %include %include @@ -31,6 +52,16 @@ #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( diff --git a/src/bindings/python/bt2/bt2/native_bt_message_iterator.i.h b/src/bindings/python/bt2/bt2/native_bt_message_iterator.i.h index f687dc9a..76b2c876 100644 --- a/src/bindings/python/bt2/bt2/native_bt_message_iterator.i.h +++ b/src/bindings/python/bt2/bt2/native_bt_message_iterator.i.h @@ -22,6 +22,44 @@ * 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) { diff --git a/src/lib/graph/component-class-sink-simple.c b/src/lib/graph/component-class-sink-simple.c index 797ee50a..cbf67811 100644 --- a/src/lib/graph/component-class-sink-simple.c +++ b/src/lib/graph/component-class-sink-simple.c @@ -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; } diff --git a/src/lib/graph/iterator.c b/src/lib/graph/iterator.c index 21cd6eb8..1030a465 100644 --- a/src/lib/graph/iterator.c +++ b/src/lib/graph/iterator.c @@ -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( diff --git a/src/plugins/ctf/fs-sink/fs-sink.c b/src/plugins/ctf/fs-sink/fs-sink.c index 077a08b2..977cc143 100644 --- a/src/plugins/ctf/fs-sink/fs-sink.c +++ b/src/plugins/ctf/fs-sink/fs-sink.c @@ -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; } diff --git a/src/plugins/lttng-utils/debug-info/debug-info.c b/src/plugins/lttng-utils/debug-info/debug-info.c index 545a4eee..c2fda777 100644 --- a/src/plugins/lttng-utils/debug-info/debug-info.c +++ b/src/plugins/lttng-utils/debug-info/debug-info.c @@ -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: diff --git a/src/plugins/text/details/details.c b/src/plugins/text/details/details.c index 85cfb017..582230f0 100644 --- a/src/plugins/text/details/details.c +++ b/src/plugins/text/details/details.c @@ -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; } diff --git a/src/plugins/text/pretty/pretty.c b/src/plugins/text/pretty/pretty.c index d0e1fbbc..2bf9f7b7 100644 --- a/src/plugins/text/pretty/pretty.c +++ b/src/plugins/text/pretty/pretty.c @@ -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; } diff --git a/src/plugins/utils/counter/counter.c b/src/plugins/utils/counter/counter.c index 2ad60167..bf0e4a57 100644 --- a/src/plugins/utils/counter/counter.c +++ b/src/plugins/utils/counter/counter.c @@ -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; } diff --git a/src/plugins/utils/dummy/dummy.c b/src/plugins/utils/dummy/dummy.c index 681db3b6..d41551de 100644 --- a/src/plugins/utils/dummy/dummy.c +++ b/src/plugins/utils/dummy/dummy.c @@ -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; } diff --git a/src/plugins/utils/muxer/muxer.c b/src/plugins/utils/muxer/muxer.c index f67955d1..328d3a28 100644 --- a/src/plugins/utils/muxer/muxer.c +++ b/src/plugins/utils/muxer/muxer.c @@ -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; diff --git a/src/plugins/utils/trimmer/trimmer.c b/src/plugins/utils/trimmer/trimmer.c index c821e0b4..b18d976b 100644 --- a/src/plugins/utils/trimmer/trimmer.c +++ b/src/plugins/utils/trimmer/trimmer.c @@ -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; } diff --git a/tests/bindings/python/bt2/test_message_iterator.py b/tests/bindings/python/bt2/test_message_iterator.py index 9635672f..c317ae43 100644 --- a/tests/bindings/python/bt2/test_message_iterator.py +++ b/tests/bindings/python/bt2/test_message_iterator.py @@ -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):