lib: make can_seek_beginning and can_seek_ns_from_origin methods return a status
authorSimon Marchi <simon.marchi@efficios.com>
Fri, 6 Sep 2019 19:50:51 +0000 (15:50 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Tue, 17 Sep 2019 19:05:53 +0000 (15:05 -0400)
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 <simon.marchi@efficios.com>
Reviewed-on: https://review.lttng.org/c/babeltrace/+/2012
Tested-by: jenkins <jenkins@lttng.org>
Reviewed-by: Francis Deslauriers <francis.deslauriers@efficios.com>
19 files changed:
include/babeltrace2/graph/component-class-filter.h
include/babeltrace2/graph/component-class-source.h
include/babeltrace2/graph/component-class.h
include/babeltrace2/graph/message-iterator.h
include/babeltrace2/graph/self-component-port-input-message-iterator.h
src/bindings/python/bt2/bt2/message_iterator.py
src/bindings/python/bt2/bt2/native_bt.i
src/bindings/python/bt2/bt2/native_bt_component_class.i.h
src/bindings/python/bt2/bt2/native_bt_log_and_append_error.h
src/lib/graph/iterator.c
src/lib/graph/message/iterator.h
src/plugins/lttng-utils/debug-info/debug-info.c
src/plugins/lttng-utils/debug-info/debug-info.h
src/plugins/text/dmesg/dmesg.c
src/plugins/text/dmesg/dmesg.h
src/plugins/utils/muxer/muxer.c
src/plugins/utils/muxer/muxer.h
src/plugins/utils/trimmer/trimmer.c
tests/bindings/python/bt2/test_message_iterator.py

index d0bfbcd895846af39656b4f51921f24ba46a91eb..c4c5d1de2cf0f706f6a89f9759d54b06218f37bc 100644 (file)
@@ -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)(
index b8cf57e8f6c7fd3ca583d338a1ee5984709d8ce8..7856cea486013c5f0305733e0d8b508f5c0308bc 100644 (file)
@@ -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)(
index 2c2a85c23c3139879b4e8bf5f31c3a1f0ad2cdfe..324f123886713b596240b2b39b1710d003567c12 100644 (file)
@@ -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;
index ebdc2e68563e75c24c8d9dc239472744926eb696..a7c3941cb0fb2d6781a358be26c6335e354ac250 100644 (file)
@@ -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
index 8d5f29f79c19da9a196ce202b726a18922045e06..c83bd8db60cfd42d560f4649619486cc7b917ce9 100644 (file)
@@ -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(
index da9ca7474a2735daaf58c1619dd5473be3ee7400..c392d420491918ac1c35fd910d9fc3783d732144 100644 (file)
@@ -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):
index 8146e8ff4299d85ca3cea46dfb7f5b5fc1046654..4e48876848d30347539003364805141c17abac1a 100644 (file)
@@ -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);
index 6774ec6f522f7d8a9230cb555a7162246fa6ed2a..58c6c7740f8fd72ce476c7dda96896f894c93e4d 100644 (file)
@@ -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
index 15295bbfc4c2ea3b8581a760b008bfa933febeb2..37cc2e78ac6484bb93880d51a8916d88139bb017 100644 (file)
@@ -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)
 {
index 3ebe11f866438c70acdb65abd87303551a14b0eb..983f5c100ab5d1a5482742bd080739589f90128c 100644 (file)
@@ -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);
index 82689f61da6674a5975c22ea8bc217527e30ddda..8014d1fad536c27d8fbd97772a7c014035f17e43 100644 (file)
@@ -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;
index c2fda777295ee198d268c4fa84da9152809e75e4..58809eb2e2aca4ab24c7d26f90f348805cdd8be2 100644 (file)
@@ -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
index fb50f60fcfa0cd3dc43c53a9eb6662897a900f59..6319545b87dd67b9be62fdd01acf6ab0c886afdc 100644 (file)
@@ -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(
index 7fa50720e4588e9ff333d5d7d170d1de0b878720..4a131ea3c31169ce64f4b26c64d49674053be0df 100644 (file)
@@ -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
index 45656bf1e42ebbfb6d2c3155afee2a7756fc0b3f..b72f47947f96ea6e707456b5e3dc0d02b869d6ab 100644 (file)
@@ -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(
index 328d3a28334a46737837a9a18ed3ea78bdbf0918..d6ca31bb63b435383c45c1ee55d5505425b44472 100644 (file)
@@ -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
index 95faf568645d33868ccd337f6b054cd13178bf9d..72e8b762bc71c954e5de539d59639ecc73080121 100644 (file)
@@ -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(
index b18d976b0fe9ad8905de5307a8d6006d62ad7f3d..4d39fba27cdbd662e5d1df2e21c830e6a7fb66e3 100644 (file)
@@ -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);
index 2d4ab43850774131ffa9982355639079aa3f518b..01d4eca3c5b9d0d4d768dd6304554b6b2b01512d 100644 (file)
@@ -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):
This page took 0.036919 seconds and 4 git commands to generate.