From f2fb1b3297ca0bc13b53189a063b63944be7fae9 Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 6 Sep 2019 15:50:51 -0400 Subject: [PATCH] lib: make can_seek_beginning and can_seek_ns_from_origin methods return a status The current situation is problematic: calling any of these methods on a message iterator can result in running some user code, which can fail for various reasons (e.g. any Python exception being raised and escaping). It is not possible to inform the caller of such failure, as the return type of these methods is bt_bool. This must change. This patch changes them to return a status, and return the result by an output parameter. If the method returns OK, it must have set the output parameter to BT_TRUE or BT_FALSE. If it returns another status, the output parameter value is unused. Change-Id: Iaa3dcc1494e2a0fcbdbb14283af3bf8504cd8ef5 Signed-off-by: Simon Marchi Reviewed-on: https://review.lttng.org/c/babeltrace/+/2012 Tested-by: jenkins Reviewed-by: Francis Deslauriers --- .../graph/component-class-filter.h | 8 +- .../graph/component-class-source.h | 8 +- include/babeltrace2/graph/component-class.h | 14 ++ include/babeltrace2/graph/message-iterator.h | 14 ++ ...lf-component-port-input-message-iterator.h | 10 +- .../python/bt2/bt2/message_iterator.py | 6 +- src/bindings/python/bt2/bt2/native_bt.i | 10 ++ .../bt2/bt2/native_bt_component_class.i.h | 21 ++- .../bt2/bt2/native_bt_log_and_append_error.h | 11 -- src/lib/graph/iterator.c | 128 ++++++++++++++---- src/lib/graph/message/iterator.h | 8 +- .../lttng-utils/debug-info/debug-info.c | 9 +- .../lttng-utils/debug-info/debug-info.h | 6 +- src/plugins/text/dmesg/dmesg.c | 9 +- src/plugins/text/dmesg/dmesg.h | 5 +- src/plugins/utils/muxer/muxer.c | 42 +++--- src/plugins/utils/muxer/muxer.h | 5 +- src/plugins/utils/trimmer/trimmer.c | 39 +++++- .../python/bt2/test_message_iterator.py | 54 ++++++++ 19 files changed, 304 insertions(+), 103 deletions(-) diff --git a/include/babeltrace2/graph/component-class-filter.h b/include/babeltrace2/graph/component-class-filter.h index d0bfbcd8..c4c5d1de 100644 --- a/include/babeltrace2/graph/component-class-filter.h +++ b/include/babeltrace2/graph/component-class-filter.h @@ -77,14 +77,14 @@ typedef bt_component_class_message_iterator_seek_beginning_method_status (*bt_component_class_filter_message_iterator_seek_beginning_method)( bt_self_message_iterator *message_iterator); -typedef bt_bool +typedef bt_component_class_message_iterator_can_seek_ns_from_origin_method_status (*bt_component_class_filter_message_iterator_can_seek_ns_from_origin_method)( bt_self_message_iterator *message_iterator, - int64_t ns_from_origin); + int64_t ns_from_origin, bt_bool *can_seek); -typedef bt_bool +typedef bt_component_class_message_iterator_can_seek_beginning_method_status (*bt_component_class_filter_message_iterator_can_seek_beginning_method)( - bt_self_message_iterator *message_iterator); + bt_self_message_iterator *message_iterator, bt_bool *can_seek); typedef bt_component_class_query_method_status (*bt_component_class_filter_query_method)( diff --git a/include/babeltrace2/graph/component-class-source.h b/include/babeltrace2/graph/component-class-source.h index b8cf57e8..7856cea4 100644 --- a/include/babeltrace2/graph/component-class-source.h +++ b/include/babeltrace2/graph/component-class-source.h @@ -77,14 +77,14 @@ typedef bt_component_class_message_iterator_seek_beginning_method_status (*bt_component_class_source_message_iterator_seek_beginning_method)( bt_self_message_iterator *message_iterator); -typedef bt_bool +typedef bt_component_class_message_iterator_can_seek_ns_from_origin_method_status (*bt_component_class_source_message_iterator_can_seek_ns_from_origin_method)( bt_self_message_iterator *message_iterator, - int64_t ns_from_origin); + int64_t ns_from_origin, bt_bool *can_seek); -typedef bt_bool +typedef bt_component_class_message_iterator_can_seek_beginning_method_status (*bt_component_class_source_message_iterator_can_seek_beginning_method)( - bt_self_message_iterator *message_iterator); + bt_self_message_iterator *message_iterator, bt_bool *can_seek); typedef bt_component_class_query_method_status (*bt_component_class_source_query_method)( diff --git a/include/babeltrace2/graph/component-class.h b/include/babeltrace2/graph/component-class.h index 2c2a85c2..324f1238 100644 --- a/include/babeltrace2/graph/component-class.h +++ b/include/babeltrace2/graph/component-class.h @@ -87,6 +87,20 @@ typedef enum bt_component_class_message_iterator_seek_ns_from_origin_method_stat BT_COMPONENT_CLASS_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, } bt_component_class_message_iterator_seek_ns_from_origin_method_status; +typedef enum bt_component_class_message_iterator_can_seek_beginning_method_status { + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_OK = __BT_FUNC_STATUS_OK, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_AGAIN = __BT_FUNC_STATUS_AGAIN, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_ERROR = __BT_FUNC_STATUS_ERROR, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, +} bt_component_class_message_iterator_can_seek_beginning_method_status; + +typedef enum bt_component_class_message_iterator_can_seek_ns_from_origin_method_status { + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_OK = __BT_FUNC_STATUS_OK, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_AGAIN = __BT_FUNC_STATUS_AGAIN, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_ERROR = __BT_FUNC_STATUS_ERROR, + BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_METHOD_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, +} bt_component_class_message_iterator_can_seek_ns_from_origin_method_status; + typedef enum bt_component_class_set_method_status { BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK = __BT_FUNC_STATUS_OK, } bt_component_class_set_method_status; diff --git a/include/babeltrace2/graph/message-iterator.h b/include/babeltrace2/graph/message-iterator.h index ebdc2e68..a7c3941c 100644 --- a/include/babeltrace2/graph/message-iterator.h +++ b/include/babeltrace2/graph/message-iterator.h @@ -55,6 +55,20 @@ typedef enum bt_message_iterator_seek_ns_from_origin_status { BT_MESSAGE_ITERATOR_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, } bt_message_iterator_seek_ns_from_origin_status; +typedef enum bt_message_iterator_can_seek_beginning_status { + BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_OK = __BT_FUNC_STATUS_OK, + BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_AGAIN = __BT_FUNC_STATUS_AGAIN, + BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_ERROR = __BT_FUNC_STATUS_ERROR, + BT_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, +} bt_message_iterator_can_seek_beginning_status; + +typedef enum bt_message_iterator_can_seek_ns_from_origin_status { + BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_OK = __BT_FUNC_STATUS_OK, + BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_AGAIN = __BT_FUNC_STATUS_AGAIN, + BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_ERROR = __BT_FUNC_STATUS_ERROR, + BT_MESSAGE_ITERATOR_CAN_SEEK_NS_FROM_ORIGIN_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR, +} bt_message_iterator_can_seek_ns_from_origin_status; + #ifdef __cplusplus } #endif 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 8d5f29f7..c83bd8db 100644 --- a/include/babeltrace2/graph/self-component-port-input-message-iterator.h +++ b/include/babeltrace2/graph/self-component-port-input-message-iterator.h @@ -77,13 +77,15 @@ bt_self_component_port_input_message_iterator_next( bt_self_component_port_input_message_iterator *iterator, bt_message_array_const *msgs, uint64_t *count); -extern bt_bool +extern bt_message_iterator_can_seek_ns_from_origin_status bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( bt_self_component_port_input_message_iterator *iterator, - int64_t ns_from_origin); + int64_t ns_from_origin, bt_bool *can_seek); -extern bt_bool bt_self_component_port_input_message_iterator_can_seek_beginning( - bt_self_component_port_input_message_iterator *iterator); +extern bt_message_iterator_can_seek_beginning_status +bt_self_component_port_input_message_iterator_can_seek_beginning( + bt_self_component_port_input_message_iterator *iterator, + bt_bool *can_seek); extern bt_message_iterator_seek_ns_from_origin_status bt_self_component_port_input_message_iterator_seek_ns_from_origin( diff --git a/src/bindings/python/bt2/bt2/message_iterator.py b/src/bindings/python/bt2/bt2/message_iterator.py index da9ca747..c392d420 100644 --- a/src/bindings/python/bt2/bt2/message_iterator.py +++ b/src/bindings/python/bt2/bt2/message_iterator.py @@ -58,7 +58,11 @@ class _GenericMessageIterator(object._SharedObject, _MessageIterator): @property def can_seek_beginning(self): - res = self._can_seek_beginning(self._ptr) + status, res = self._can_seek_beginning(self._ptr) + utils._handle_func_status( + status, + 'cannot check whether or not message iterator can seek its beginning', + ) return res != 0 def seek_beginning(self): diff --git a/src/bindings/python/bt2/bt2/native_bt.i b/src/bindings/python/bt2/bt2/native_bt.i index 8146e8ff..4e488768 100644 --- a/src/bindings/python/bt2/bt2/native_bt.i +++ b/src/bindings/python/bt2/bt2/native_bt.i @@ -139,6 +139,16 @@ typedef uint64_t bt_listener_id; SWIG_From_unsigned_SS_long_SS_long((uint64_t) (*$1))); } +/* Output argument typemap for initialized bt_boot output parameter (always appends) */ +%typemap(in, numinputs=0) (bt_bool *) (bt_bool temp) { + $1 = &temp; +} + +%typemap(argout) bt_bool * { + $result = SWIG_Python_AppendOutput(resultobj, + SWIG_From_bool(*$1)); +} + /* Input argument typemap for UUID bytes */ %typemap(in) bt_uuid { $1 = (unsigned char *) PyBytes_AsString($input); diff --git a/src/bindings/python/bt2/bt2/native_bt_component_class.i.h b/src/bindings/python/bt2/bt2/native_bt_component_class.i.h index 6774ec6f..58c6c774 100644 --- a/src/bindings/python/bt2/bt2/native_bt_component_class.i.h +++ b/src/bindings/python/bt2/bt2/native_bt_component_class.i.h @@ -538,13 +538,13 @@ void component_class_sink_finalize(bt_self_component_sink *self_component_sink) } static -bt_bool component_class_can_seek_beginning( - bt_self_message_iterator *self_message_iterator) +bt_component_class_message_iterator_can_seek_beginning_method_status +component_class_can_seek_beginning( + bt_self_message_iterator *self_message_iterator, bt_bool *can_seek) { PyObject *py_iter; PyObject *py_result = NULL; - bt_bool can_seek_beginning = false; - + bt_component_class_message_iterator_can_seek_beginning_method_status status; py_iter = bt_self_message_iterator_get_data(self_message_iterator); BT_ASSERT(py_iter); @@ -553,19 +553,16 @@ bt_bool component_class_can_seek_beginning( BT_ASSERT(!py_result || PyBool_Check(py_result)); if (py_result) { - can_seek_beginning = PyObject_IsTrue(py_result); + *can_seek = PyObject_IsTrue(py_result); + status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_OK; } else { - /* - * Once can_seek_beginning can report errors, convert the - * exception to a status. For now, log and return false; - */ - loge_exception_message_iterator(self_message_iterator); - PyErr_Clear(); + status = py_exc_to_status_message_iterator(self_message_iterator); + BT_ASSERT(status != __BT_FUNC_STATUS_OK); } Py_XDECREF(py_result); - return can_seek_beginning; + return status; } static diff --git a/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h b/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h index 15295bbf..37cc2e78 100644 --- a/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h +++ b/src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h @@ -232,17 +232,6 @@ void loge_exception(const char *module_name, int active_log_level) true, NULL, NULL, NULL, module_name); } -static -void loge_exception_message_iterator( - bt_self_message_iterator *self_message_iterator) -{ - bt_logging_level log_level = get_self_message_iterator_log_level( - self_message_iterator); - - log_exception_and_maybe_append_error(BT_LOG_ERROR, log_level, - true, NULL, NULL, self_message_iterator, NULL); -} - static inline void logw_exception(int active_log_level) { diff --git a/src/lib/graph/iterator.c b/src/lib/graph/iterator.c index 3ebe11f8..983f5c10 100644 --- a/src/lib/graph/iterator.c +++ b/src/lib/graph/iterator.c @@ -273,18 +273,23 @@ void bt_self_component_port_input_message_iterator_set_connection( } static -bt_bool can_seek_ns_from_origin_true( +enum bt_message_iterator_can_seek_beginning_status can_seek_ns_from_origin_true( struct bt_self_component_port_input_message_iterator *iterator, - int64_t ns_from_origin) + int64_t ns_from_origin, bt_bool *can_seek) { - return BT_TRUE; + *can_seek = BT_TRUE; + + return BT_FUNC_STATUS_OK; } static -bt_bool can_seek_beginning_true( - struct bt_self_component_port_input_message_iterator *iterator) +enum bt_message_iterator_can_seek_beginning_status can_seek_beginning_true( + struct bt_self_component_port_input_message_iterator *iterator, + bt_bool *can_seek) { - return BT_TRUE; + *can_seek = BT_TRUE; + + return BT_FUNC_STATUS_OK; } static @@ -961,13 +966,15 @@ struct bt_self_component_port_output *bt_self_message_iterator_borrow_port( return (void *) iterator->upstream_port; } -bt_bool bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( +enum bt_message_iterator_can_seek_ns_from_origin_status +bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( struct bt_self_component_port_input_message_iterator *iterator, - int64_t ns_from_origin) + int64_t ns_from_origin, bt_bool *can_seek) { - bt_bool can = BT_FALSE; + enum bt_message_iterator_can_seek_ns_from_origin_status status; BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); + BT_ASSERT_PRE_NON_NULL(can_seek, "Result (output)"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); BT_ASSERT_PRE( bt_component_borrow_graph(iterator->upstream_component)->config_state != @@ -976,8 +983,22 @@ bt_bool bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( bt_component_borrow_graph(iterator->upstream_component)); if (iterator->methods.can_seek_ns_from_origin) { - can = iterator->methods.can_seek_ns_from_origin(iterator, - ns_from_origin); + /* + * Initialize to an invalid value, so we can post-assert that + * the method returned a valid value. + */ + *can_seek = -1; + + status = (int) iterator->methods.can_seek_ns_from_origin(iterator, + ns_from_origin, can_seek); + + BT_ASSERT_POST( + status != BT_FUNC_STATUS_OK || + *can_seek == BT_TRUE || + *can_seek == BT_FALSE, + "Unexpected boolean value returned from user's \"can seek ns from origin\" method: val=%d, %![iter-]+i", + *can_seek, iterator); + goto end; } @@ -985,20 +1006,22 @@ bt_bool bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( * Automatic seeking fall back: if we can seek to the beginning, * then we can automatically seek to any message. */ - if (iterator->methods.can_seek_beginning) { - can = iterator->methods.can_seek_beginning(iterator); - } + status = (int) bt_self_component_port_input_message_iterator_can_seek_beginning( + iterator, can_seek); end: - return can; + return status; } -bt_bool bt_self_component_port_input_message_iterator_can_seek_beginning( - struct bt_self_component_port_input_message_iterator *iterator) +enum bt_message_iterator_can_seek_beginning_status +bt_self_component_port_input_message_iterator_can_seek_beginning( + struct bt_self_component_port_input_message_iterator *iterator, + bt_bool *can_seek) { - bt_bool can = BT_FALSE; + enum bt_message_iterator_can_seek_beginning_status status; BT_ASSERT_PRE_NON_NULL(iterator, "Message iterator"); + BT_ASSERT_PRE_NON_NULL(can_seek, "Result (output)"); BT_ASSERT_PRE_ITER_HAS_STATE_TO_SEEK(iterator); BT_ASSERT_PRE( bt_component_borrow_graph(iterator->upstream_component)->config_state != @@ -1007,10 +1030,26 @@ bt_bool bt_self_component_port_input_message_iterator_can_seek_beginning( bt_component_borrow_graph(iterator->upstream_component)); if (iterator->methods.can_seek_beginning) { - can = iterator->methods.can_seek_beginning(iterator); + /* + * Initialize to an invalid value, so we can post-assert that + * the method returned a valid value. + */ + *can_seek = -1; + + status = (int) iterator->methods.can_seek_beginning(iterator, can_seek); + + BT_ASSERT_POST( + status != BT_FUNC_STATUS_OK || + *can_seek == BT_TRUE || + *can_seek == BT_FALSE, + "Unexpected boolean value returned from user's \"can seek beginning\" method: val=%d, %![iter-]+i", + *can_seek, iterator); + } else { + *can_seek = BT_FALSE; + status = BT_FUNC_STATUS_OK; } - return can; + return status; } static inline @@ -1050,6 +1089,22 @@ void reset_iterator_expectations( iterator->clock_expectation.type = CLOCK_EXPECTATION_UNSET; } +static +bool message_iterator_can_seek_beginning( + struct bt_self_component_port_input_message_iterator *iterator) +{ + enum bt_message_iterator_can_seek_beginning_status status; + bt_bool can_seek; + + status = bt_self_component_port_input_message_iterator_can_seek_beginning( + iterator, &can_seek); + if (status != BT_FUNC_STATUS_OK) { + can_seek = BT_FALSE; + } + + return can_seek; +} + enum bt_message_iterator_seek_beginning_status bt_self_component_port_input_message_iterator_seek_beginning( struct bt_self_component_port_input_message_iterator *iterator) @@ -1063,9 +1118,7 @@ bt_self_component_port_input_message_iterator_seek_beginning( BT_GRAPH_CONFIGURATION_STATE_CONFIGURING, "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); - BT_ASSERT_PRE( - bt_self_component_port_input_message_iterator_can_seek_beginning( - iterator), + BT_ASSERT_PRE(message_iterator_can_seek_beginning(iterator), "Message iterator cannot seek beginning: %!+i", iterator); /* @@ -1588,6 +1641,22 @@ int clock_raw_value_from_ns_from_origin(const bt_clock_class *clock_class, cc_offset_cycles, cc_freq, ns_from_origin, raw_value); } +static +bool message_iterator_can_seek_ns_from_origin( + struct bt_self_component_port_input_message_iterator *iterator, + int64_t ns_from_origin) +{ + enum bt_message_iterator_can_seek_ns_from_origin_status status; + bt_bool can_seek; + + status = bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( + iterator, ns_from_origin, &can_seek); + if (status != BT_FUNC_STATUS_OK) { + can_seek = BT_FALSE; + } + + return can_seek; +} enum bt_message_iterator_seek_ns_from_origin_status bt_self_component_port_input_message_iterator_seek_ns_from_origin( @@ -1605,8 +1674,7 @@ bt_self_component_port_input_message_iterator_seek_ns_from_origin( "Graph is not configured: %!+g", bt_component_borrow_graph(iterator->upstream_component)); BT_ASSERT_PRE( - bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( - iterator, ns_from_origin), + message_iterator_can_seek_ns_from_origin(iterator, ns_from_origin), "Message iterator cannot seek nanoseconds from origin: %!+i, " "ns-from-origin=%" PRId64, iterator, ns_from_origin); set_self_comp_port_input_msg_iterator_state(iterator, @@ -1643,7 +1711,15 @@ bt_self_component_port_input_message_iterator_seek_ns_from_origin( * The iterator doesn't know how to seek to a particular time. We will * seek to the beginning and fast forward to the right place. */ - BT_ASSERT(iterator->methods.can_seek_beginning(iterator)); + enum bt_component_class_message_iterator_can_seek_beginning_method_status + can_seek_status; + bt_bool can_seek_beginning; + + can_seek_status = iterator->methods.can_seek_beginning(iterator, + &can_seek_beginning); + BT_ASSERT(can_seek_status == BT_FUNC_STATUS_OK); + BT_ASSERT(can_seek_beginning); + BT_ASSERT(iterator->methods.seek_beginning); BT_LIB_LOGD("Calling user's \"seek beginning\" method: %!+i", iterator); diff --git a/src/lib/graph/message/iterator.h b/src/lib/graph/message/iterator.h index 82689f61..8014d1fa 100644 --- a/src/lib/graph/message/iterator.h +++ b/src/lib/graph/message/iterator.h @@ -77,13 +77,13 @@ typedef enum bt_component_class_message_iterator_seek_beginning_method_status (*bt_self_component_port_input_message_iterator_seek_beginning_method)( void *); -typedef bt_bool +typedef enum bt_component_class_message_iterator_can_seek_ns_from_origin_method_status (*bt_self_component_port_input_message_iterator_can_seek_ns_from_origin_method)( - void *, int64_t); + void *, int64_t, bt_bool *); -typedef bt_bool +typedef enum bt_component_class_message_iterator_can_seek_beginning_method_status (*bt_self_component_port_input_message_iterator_can_seek_beginning_method)( - void *); + void *, bt_bool *); struct bt_self_component_port_input_message_iterator { struct bt_object base; diff --git a/src/plugins/lttng-utils/debug-info/debug-info.c b/src/plugins/lttng-utils/debug-info/debug-info.c index c2fda777..58809eb2 100644 --- a/src/plugins/lttng-utils/debug-info/debug-info.c +++ b/src/plugins/lttng-utils/debug-info/debug-info.c @@ -2043,15 +2043,16 @@ end: } BT_HIDDEN -bt_bool debug_info_msg_iter_can_seek_beginning( - bt_self_message_iterator *self_msg_iter) +bt_component_class_message_iterator_can_seek_beginning_method_status +debug_info_msg_iter_can_seek_beginning( + bt_self_message_iterator *self_msg_iter, bt_bool *can_seek) { struct debug_info_msg_iter *debug_info_msg_iter = bt_self_message_iterator_get_data(self_msg_iter); BT_ASSERT(debug_info_msg_iter); - return bt_self_component_port_input_message_iterator_can_seek_beginning( - debug_info_msg_iter->msg_iter); + return (int) bt_self_component_port_input_message_iterator_can_seek_beginning( + debug_info_msg_iter->msg_iter, can_seek); } BT_HIDDEN diff --git a/src/plugins/lttng-utils/debug-info/debug-info.h b/src/plugins/lttng-utils/debug-info/debug-info.h index fb50f60f..6319545b 100644 --- a/src/plugins/lttng-utils/debug-info/debug-info.h +++ b/src/plugins/lttng-utils/debug-info/debug-info.h @@ -55,8 +55,10 @@ bt_component_class_message_iterator_next_method_status debug_info_msg_iter_next( uint64_t *count); BT_HIDDEN -bt_bool debug_info_msg_iter_can_seek_beginning( - bt_self_message_iterator *message_iterator); +bt_component_class_message_iterator_can_seek_beginning_method_status +debug_info_msg_iter_can_seek_beginning( + bt_self_message_iterator *message_iterator, + bt_bool *can_seek); BT_HIDDEN bt_component_class_message_iterator_seek_beginning_method_status debug_info_msg_iter_seek_beginning( diff --git a/src/plugins/text/dmesg/dmesg.c b/src/plugins/text/dmesg/dmesg.c index 7fa50720..4a131ea3 100644 --- a/src/plugins/text/dmesg/dmesg.c +++ b/src/plugins/text/dmesg/dmesg.c @@ -866,14 +866,17 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next( } BT_HIDDEN -bt_bool dmesg_msg_iter_can_seek_beginning( - bt_self_message_iterator *self_msg_iter) +bt_component_class_message_iterator_can_seek_beginning_method_status +dmesg_msg_iter_can_seek_beginning( + bt_self_message_iterator *self_msg_iter, bt_bool *can_seek) { struct dmesg_msg_iter *dmesg_msg_iter = bt_self_message_iterator_get_data(self_msg_iter); /* Can't seek the beginning of the standard input stream */ - return !dmesg_msg_iter->dmesg_comp->params.read_from_stdin; + *can_seek = !dmesg_msg_iter->dmesg_comp->params.read_from_stdin; + + return BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_OK; } BT_HIDDEN diff --git a/src/plugins/text/dmesg/dmesg.h b/src/plugins/text/dmesg/dmesg.h index 45656bf1..b72f4794 100644 --- a/src/plugins/text/dmesg/dmesg.h +++ b/src/plugins/text/dmesg/dmesg.h @@ -52,8 +52,9 @@ bt_component_class_message_iterator_next_method_status dmesg_msg_iter_next( uint64_t *count); BT_HIDDEN -bt_bool dmesg_msg_iter_can_seek_beginning( - bt_self_message_iterator *message_iterator); +bt_component_class_message_iterator_can_seek_beginning_method_status +dmesg_msg_iter_can_seek_beginning( + bt_self_message_iterator *message_iterator, bt_bool *can_seek); BT_HIDDEN bt_component_class_message_iterator_seek_beginning_method_status dmesg_msg_iter_seek_beginning( diff --git a/src/plugins/utils/muxer/muxer.c b/src/plugins/utils/muxer/muxer.c index 328d3a28..d6ca31bb 100644 --- a/src/plugins/utils/muxer/muxer.c +++ b/src/plugins/utils/muxer/muxer.c @@ -1488,49 +1488,57 @@ end: } static inline -bt_bool muxer_upstream_msg_iters_can_all_seek_beginning( - GPtrArray *muxer_upstream_msg_iters) +bt_component_class_message_iterator_can_seek_beginning_method_status +muxer_upstream_msg_iters_can_all_seek_beginning( + GPtrArray *muxer_upstream_msg_iters, bt_bool *can_seek) { + bt_component_class_message_iterator_can_seek_beginning_method_status status; uint64_t i; - bt_bool ret = BT_TRUE; for (i = 0; i < muxer_upstream_msg_iters->len; i++) { struct muxer_upstream_msg_iter *upstream_msg_iter = muxer_upstream_msg_iters->pdata[i]; + status = (int) bt_self_component_port_input_message_iterator_can_seek_beginning( + upstream_msg_iter->msg_iter, can_seek); + if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_OK) { + goto end; + } - if (!bt_self_component_port_input_message_iterator_can_seek_beginning( - upstream_msg_iter->msg_iter)) { - ret = BT_FALSE; + if (!*can_seek) { goto end; } } + *can_seek = BT_TRUE; + end: - return ret; + return status; } BT_HIDDEN -bt_bool muxer_msg_iter_can_seek_beginning( - bt_self_message_iterator *self_msg_iter) +bt_component_class_message_iterator_can_seek_beginning_method_status +muxer_msg_iter_can_seek_beginning( + bt_self_message_iterator *self_msg_iter, bt_bool *can_seek) { struct muxer_msg_iter *muxer_msg_iter = bt_self_message_iterator_get_data(self_msg_iter); - bt_bool ret = BT_TRUE; + bt_component_class_message_iterator_can_seek_beginning_method_status status; - if (!muxer_upstream_msg_iters_can_all_seek_beginning( - muxer_msg_iter->active_muxer_upstream_msg_iters)) { - ret = BT_FALSE; + status = muxer_upstream_msg_iters_can_all_seek_beginning( + muxer_msg_iter->active_muxer_upstream_msg_iters, can_seek); + if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_CAN_SEEK_BEGINNING_METHOD_STATUS_OK) { goto end; } - if (!muxer_upstream_msg_iters_can_all_seek_beginning( - muxer_msg_iter->ended_muxer_upstream_msg_iters)) { - ret = BT_FALSE; + if (!*can_seek) { goto end; } + status = muxer_upstream_msg_iters_can_all_seek_beginning( + muxer_msg_iter->ended_muxer_upstream_msg_iters, can_seek); + end: - return ret; + return status; } BT_HIDDEN diff --git a/src/plugins/utils/muxer/muxer.h b/src/plugins/utils/muxer/muxer.h index 95faf568..72e8b762 100644 --- a/src/plugins/utils/muxer/muxer.h +++ b/src/plugins/utils/muxer/muxer.h @@ -59,8 +59,9 @@ bt_component_class_port_connected_method_status muxer_input_port_connected( const bt_port_output *other_port); BT_HIDDEN -bt_bool muxer_msg_iter_can_seek_beginning( - bt_self_message_iterator *message_iterator); +bt_component_class_message_iterator_can_seek_beginning_method_status +muxer_msg_iter_can_seek_beginning( + bt_self_message_iterator *message_iterator, bt_bool *can_seek); BT_HIDDEN bt_component_class_message_iterator_seek_beginning_method_status muxer_msg_iter_seek_beginning( diff --git a/src/plugins/utils/trimmer/trimmer.c b/src/plugins/utils/trimmer/trimmer.c index b18d976b..4d39fba2 100644 --- a/src/plugins/utils/trimmer/trimmer.c +++ b/src/plugins/utils/trimmer/trimmer.c @@ -998,14 +998,25 @@ bt_component_class_message_iterator_next_method_status state_seek_initially( struct trimmer_iterator *trimmer_it) { struct trimmer_comp *trimmer_comp = trimmer_it->trimmer_comp; - bt_component_class_message_iterator_next_method_status status = - BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK; + bt_component_class_message_iterator_next_method_status status; BT_ASSERT(trimmer_it->begin.is_set); if (trimmer_it->begin.is_infinite) { - if (!bt_self_component_port_input_message_iterator_can_seek_beginning( - trimmer_it->upstream_iter)) { + bt_bool can_seek; + + status = (int) bt_self_component_port_input_message_iterator_can_seek_beginning( + trimmer_it->upstream_iter, &can_seek); + if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(trimmer_comp->self_comp, + "Cannot make upstream message iterator initially seek its beginning."); + } + + goto end; + } + + if (!can_seek) { BT_COMP_LOGE_APPEND_CAUSE(trimmer_comp->self_comp, "Cannot make upstream message iterator initially seek its beginning."); status = BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_ERROR; @@ -1015,9 +1026,23 @@ bt_component_class_message_iterator_next_method_status state_seek_initially( status = (int) bt_self_component_port_input_message_iterator_seek_beginning( trimmer_it->upstream_iter); } else { - if (!bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( - trimmer_it->upstream_iter, - trimmer_it->begin.ns_from_origin)) { + bt_bool can_seek; + + status = (int) bt_self_component_port_input_message_iterator_can_seek_ns_from_origin( + trimmer_it->upstream_iter, trimmer_it->begin.ns_from_origin, + &can_seek); + + if (status != BT_COMPONENT_CLASS_MESSAGE_ITERATOR_NEXT_METHOD_STATUS_OK) { + if (status < 0) { + BT_COMP_LOGE_APPEND_CAUSE(trimmer_comp->self_comp, + "Cannot make upstream message iterator initially seek: seek-ns-from-origin=%" PRId64, + trimmer_it->begin.ns_from_origin); + } + + goto end; + } + + if (!can_seek) { BT_COMP_LOGE_APPEND_CAUSE(trimmer_comp->self_comp, "Cannot make upstream message iterator initially seek: seek-ns-from-origin=%" PRId64, trimmer_it->begin.ns_from_origin); diff --git a/tests/bindings/python/bt2/test_message_iterator.py b/tests/bindings/python/bt2/test_message_iterator.py index 2d4ab438..01d4eca3 100644 --- a/tests/bindings/python/bt2/test_message_iterator.py +++ b/tests/bindings/python/bt2/test_message_iterator.py @@ -457,6 +457,60 @@ class UserMessageIteratorSeekBeginningTestCase(unittest.TestCase): graph.run_once() self.assertFalse(can_seek_beginning) + def test_can_seek_beginning_user_error(self): + class MySink(bt2._UserSinkComponent): + def __init__(self, params, obj): + self._add_input_port('in') + + def _user_graph_is_configured(self): + self._msg_iter = self._create_input_port_message_iterator( + self._input_ports['in'] + ) + + def _user_consume(self): + # This is expected to raise. + self._msg_iter.can_seek_beginning + + def _user_can_seek_beginning(self): + raise ValueError('moustiquaire') + + graph = _setup_seek_test( + MySink, user_can_seek_beginning=_user_can_seek_beginning + ) + + with self.assertRaises(bt2._Error) as ctx: + graph.run_once() + + cause = ctx.exception[0] + self.assertIn('ValueError: moustiquaire', cause.message) + + def test_can_seek_beginning_wrong_return_value(self): + class MySink(bt2._UserSinkComponent): + def __init__(self, params, obj): + self._add_input_port('in') + + def _user_graph_is_configured(self): + self._msg_iter = self._create_input_port_message_iterator( + self._input_ports['in'] + ) + + def _user_consume(self): + # This is expected to raise. + self._msg_iter.can_seek_beginning + + def _user_can_seek_beginning(self): + return 'Amqui' + + graph = _setup_seek_test( + MySink, user_can_seek_beginning=_user_can_seek_beginning + ) + + with self.assertRaises(bt2._Error) as ctx: + graph.run_once() + + cause = ctx.exception[0] + self.assertIn("TypeError: 'str' is not a 'bool' object", cause.message) + def test_seek_beginning(self): class MySink(bt2._UserSinkComponent): def __init__(self, params, obj): -- 2.34.1