bt2: add "get supported MIP versions" method support
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 12 Aug 2019 21:19:46 +0000 (17:19 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 13 Aug 2019 00:28:02 +0000 (20:28 -0400)
This patch makes the `bt2` package wrap the library's "get supported MIP
versions" component class method.

In a Python component class, it is expected that the optional
_user_get_supported_mip_versions() method returns either a
`bt2.UnsignedIntegerRangeSet` object or what such an object needs to be
constructed. In other words, the method can return, for example:

    return [0, 1, (3, 5)]

Like in the library, the default _user_get_supported_mip_versions()
returns 0 (only protocol 0 supported):

    def _user_get_supported_mip_versions(cls, params, obj, log_level):
        return [0]

_bt_get_supported_mip_versions_from_native() returns a new reference on
this unsigned integer range set. Then, the native
component_class_get_supported_mip_versions() copies the ranges from the
returned range set to the range set to fill. I believe this makes
_user_get_supported_mip_versions() easier to use than receiving a range
set object and filling it like it's done in C.

The feature is not tested in this patch because the "get supported MIP
versions" method is not used within the library.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: I9e0c6f0fcac23d2224401c1fb1c258f061642767
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1875
Tested-by: jenkins <jenkins@lttng.org>
src/bindings/python/bt2/bt2/component.py
src/bindings/python/bt2/bt2/native_bt_component_class.i.h

index d7e5f09e013139c88637f0d6b599c14d5bddd557..2d0cd922a1a07730b830ca35c0aeecef5deaf881 100644 (file)
@@ -571,9 +571,29 @@ class _UserComponentType(type):
     def addr(cls):
         return int(cls._bt_cc_ptr)
 
+    def _bt_get_supported_mip_versions_from_native(cls, params_ptr, obj, log_level):
+        # this can raise, but the native side checks the exception
+        if params_ptr is not None:
+            params = bt2_value._create_from_ptr_and_get_ref(params_ptr)
+        else:
+            params = None
+
+        # this can raise, but the native side checks the exception
+        range_set = cls._user_get_supported_mip_versions(params, obj, log_level)
+
+        if type(range_set) is not bt2.UnsignedIntegerRangeSet:
+            # this can raise, but the native side checks the exception
+            range_set = bt2.UnsignedIntegerRangeSet(range_set)
+
+        # return new reference
+        range_set._get_ref(range_set._ptr)
+        return int(range_set._ptr)
+
+    def _user_get_supported_mip_versions(cls, params, obj, log_level):
+        return [0]
+
     def _bt_query_from_native(cls, priv_query_exec_ptr, object, params_ptr, method_obj):
-        # this can raise, in which case the native call to
-        # bt_component_class_query() returns NULL
+        # this can raise, but the native side checks the exception
         if params_ptr is not None:
             params = bt2_value._create_from_ptr_and_get_ref(params_ptr)
         else:
index 84c88f6db54724368e989b6c70dbe4ec4a355768..ff736a8057c6e12a73b6d4886a81271a3651c0c4 100644 (file)
@@ -297,6 +297,152 @@ end:
        return status;
 }
 
+static
+bt_component_class_get_supported_mip_versions_method_status
+component_class_get_supported_mip_versions(
+               const bt_component_class *component_class,
+               bt_self_component_class *self_component_class,
+               const bt_value *params, void *init_method_data,
+               bt_logging_level log_level,
+               bt_integer_range_set_unsigned *supported_versions)
+{
+       uint64_t i;
+       PyObject *py_cls = NULL;
+       PyObject *py_params_ptr = NULL;
+       PyObject *py_range_set_addr = NULL;
+       bt_integer_range_set_unsigned *ret_range_set = NULL;
+       bt_component_class_get_supported_mip_versions_method_status status =
+               __BT_FUNC_STATUS_OK;
+
+       py_cls = lookup_cc_ptr_to_py_cls(component_class);
+       if (!py_cls) {
+               BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG,
+                       "Cannot find Python class associated to native component class: "
+                       "comp-cls-addr=%p", component_class);
+               goto error;
+       }
+
+       py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
+               SWIGTYPE_p_bt_value, 0);
+       if (!py_params_ptr) {
+               BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG,
+                       "Failed to create a SWIG pointer object.");
+               goto error;
+       }
+
+       /*
+        * We don't take any reference on `init_method_data` which, if
+        * not `NULL`, is assumed to be a `PyObject *`: the user's
+        * _user_get_supported_mip_versions() function will eventually
+        * take a reference if needed. If `init_method_data` is `NULL`,
+        * then we pass `Py_None` as the initialization's Python object.
+        */
+       py_range_set_addr = PyObject_CallMethod(py_cls,
+               "_bt_get_supported_mip_versions_from_native", "(OOi)",
+               py_params_ptr, init_method_data ? init_method_data : Py_None,
+               (int) log_level);
+       if (!py_range_set_addr) {
+               BT_LOG_WRITE_CUR_LVL(BT_LOG_WARNING, log_level, BT_LOG_TAG,
+                       "Failed to call Python class's _bt_get_supported_mip_versions_from_native() method: "
+                       "py-cls-addr=%p", py_cls);
+               status = py_exc_to_status_component_class(self_component_class,
+                       log_level);
+               goto end;
+       }
+
+       /*
+        * The returned object, on success, is an integer object
+        * (PyLong) containing the address of a BT unsigned integer
+        * range set object (new reference).
+        */
+       ret_range_set = PyLong_AsVoidPtr(py_range_set_addr);
+       BT_ASSERT(!PyErr_Occurred());
+       BT_ASSERT(ret_range_set);
+
+       /* Copy returned ranges to input range set */
+       for (i = 0; i < bt_integer_range_set_get_range_count(
+                       bt_integer_range_set_unsigned_as_range_set_const(ret_range_set));
+                       i++) {
+               const bt_integer_range_unsigned *range =
+                       bt_integer_range_set_unsigned_borrow_range_by_index_const(
+                               ret_range_set, i);
+               bt_integer_range_set_add_range_status add_range_status;
+
+               add_range_status = bt_integer_range_set_unsigned_add_range(
+                       supported_versions,
+                       bt_integer_range_unsigned_get_lower(range),
+                       bt_integer_range_unsigned_get_upper(range));
+               if (add_range_status) {
+                       BT_LOG_WRITE_CUR_LVL(BT_LOG_ERROR, log_level, BT_LOG_TAG,
+                               "Failed to add range to supported MIP versions range set.");
+                       goto error;
+               }
+       }
+
+       goto end;
+
+error:
+       PyErr_Clear();
+       status = __BT_FUNC_STATUS_ERROR;
+
+end:
+       Py_XDECREF(py_params_ptr);
+       Py_XDECREF(py_range_set_addr);
+       bt_integer_range_set_unsigned_put_ref(ret_range_set);
+       return status;
+}
+
+static
+bt_component_class_get_supported_mip_versions_method_status
+component_class_source_get_supported_mip_versions(
+               bt_self_component_class_source *self_component_class_source,
+               const bt_value *params, void *init_method_data,
+               bt_logging_level log_level,
+               bt_integer_range_set_unsigned *supported_versions)
+{
+       const bt_component_class_source *component_class_source = bt_self_component_class_source_as_component_class_source(self_component_class_source);
+       const bt_component_class *component_class = bt_component_class_source_as_component_class_const(component_class_source);
+       bt_self_component_class *self_component_class = bt_self_component_class_source_as_self_component_class(self_component_class_source);
+
+       return component_class_get_supported_mip_versions(
+               component_class, self_component_class,
+               params, init_method_data, log_level, supported_versions);
+}
+
+static
+bt_component_class_get_supported_mip_versions_method_status
+component_class_filter_get_supported_mip_versions(
+               bt_self_component_class_filter *self_component_class_filter,
+               const bt_value *params, void *init_method_data,
+               bt_logging_level log_level,
+               bt_integer_range_set_unsigned *supported_versions)
+{
+       const bt_component_class_filter *component_class_filter = bt_self_component_class_filter_as_component_class_filter(self_component_class_filter);
+       const bt_component_class *component_class = bt_component_class_filter_as_component_class_const(component_class_filter);
+       bt_self_component_class *self_component_class = bt_self_component_class_filter_as_self_component_class(self_component_class_filter);
+
+       return component_class_get_supported_mip_versions(
+               component_class, self_component_class,
+               params, init_method_data, log_level, supported_versions);
+}
+
+static
+bt_component_class_get_supported_mip_versions_method_status
+component_class_sink_get_supported_mip_versions(
+               bt_self_component_class_sink *self_component_class_sink,
+               const bt_value *params, void *init_method_data,
+               bt_logging_level log_level,
+               bt_integer_range_set_unsigned *supported_versions)
+{
+       const bt_component_class_sink *component_class_sink = bt_self_component_class_sink_as_component_class_sink(self_component_class_sink);
+       const bt_component_class *component_class = bt_component_class_sink_as_component_class_const(component_class_sink);
+       bt_self_component_class *self_component_class = bt_self_component_class_sink_as_self_component_class(self_component_class_sink);
+
+       return component_class_get_supported_mip_versions(
+               component_class, self_component_class,
+               params, init_method_data, log_level, supported_versions);
+}
+
 /*
  * Method of bt_component_class_source to initialize a bt_self_component_source
  * of that class.
@@ -1055,6 +1201,8 @@ bt_component_class_source *bt_bt2_component_class_source_create(
        BT_ASSERT(ret == 0);
        ret = bt_component_class_source_set_query_method(component_class_source, component_class_source_query);
        BT_ASSERT(ret == 0);
+       ret = bt_component_class_source_set_get_supported_mip_versions_method(component_class_source, component_class_source_get_supported_mip_versions);
+       BT_ASSERT(ret == 0);
        ret = bt_component_class_source_set_message_iterator_init_method(
                component_class_source, component_class_source_message_iterator_init);
        BT_ASSERT(ret == 0);
@@ -1108,6 +1256,8 @@ bt_component_class_filter *bt_bt2_component_class_filter_create(
        BT_ASSERT(ret == 0);
        ret = bt_component_class_filter_set_query_method(component_class_filter, component_class_filter_query);
        BT_ASSERT(ret == 0);
+       ret = bt_component_class_filter_set_get_supported_mip_versions_method(component_class_filter, component_class_filter_get_supported_mip_versions);
+       BT_ASSERT(ret == 0);
        ret = bt_component_class_filter_set_message_iterator_init_method(
                component_class_filter, component_class_filter_message_iterator_init);
        BT_ASSERT(ret == 0);
@@ -1155,6 +1305,8 @@ bt_component_class_sink *bt_bt2_component_class_sink_create(
        BT_ASSERT(ret == 0);
        ret = bt_component_class_sink_set_query_method(component_class_sink, component_class_sink_query);
        BT_ASSERT(ret == 0);
+       ret = bt_component_class_sink_set_get_supported_mip_versions_method(component_class_sink, component_class_sink_get_supported_mip_versions);
+       BT_ASSERT(ret == 0);
        register_cc_ptr_to_py_cls(component_class, py_cls);
 
 end:
This page took 0.028269 seconds and 4 git commands to generate.