bt2: remove BT CC entry from global HT in _UserComponentType.__del__()
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Sat, 3 Aug 2019 18:29:27 +0000 (14:29 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 5 Aug 2019 19:10:13 +0000 (15:10 -0400)
The global `bt_cc_ptr_to_py_cls` hash table maps BT component class
pointers to Python component classes (`PyObject *`) for component
classes created in Python. The key and value are weak references.

When the Python side calls native_bt.bt2_component_class_*_create() with
a Python component class, an entry is added to `bt_cc_ptr_to_py_cls` on
success. This works most of the time because all Python classes are
normally destroyed when the interpreter is finalized, but there could be
issues with specific/unusual import patterns.

To avoid potential issues, remove an entry from `bt_cc_ptr_to_py_cls` in
_UserComponentType.__del__(), where a strong BT component class
reference is finally released.

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

index a057019aa379c37cb7af3f471b2fe46cb070a146..31f6372532f7d58b317b1301e2dbc6da7369a341 100644 (file)
@@ -617,6 +617,7 @@ class _UserComponentType(type):
         if hasattr(cls, '_bt_cc_ptr'):
             cc_ptr = cls._bt_as_component_class_ptr(cls._bt_cc_ptr)
             native_bt.component_class_put_ref(cc_ptr)
+            native_bt.bt2_unregister_cc_ptr_to_py_cls(cc_ptr)
 
 
 # Subclasses must provide these methods or property:
index 25f50df23ba7fb68041d0fe8148d184debfb9295..8efe81471ecdf0cea0146445c9cf94f2e246f2a6 100644 (file)
@@ -47,3 +47,4 @@ struct bt_component_class_filter *bt_bt2_component_class_filter_create(
 struct bt_component_class_sink *bt_bt2_component_class_sink_create(
                PyObject *py_cls, const char *name, const char *description,
                const char *help);
+void bt_bt2_unregister_cc_ptr_to_py_cls(const bt_component_class *comp_cls);
index 479f9abf737595e2c738e0e43ac70d57ca08aca0..fc10efef34b6bff60ab069c7075a43c5930703a2 100644 (file)
 
 static GHashTable *bt_cc_ptr_to_py_cls;
 
+static
+void bt_bt2_unregister_cc_ptr_to_py_cls(const bt_component_class *comp_cls)
+{
+       gboolean existed;
+
+       if (!bt_cc_ptr_to_py_cls) {
+               return;
+       }
+
+       existed = g_hash_table_remove(bt_cc_ptr_to_py_cls, comp_cls);
+       BT_ASSERT(existed);
+}
+
 static
 void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
                PyObject *py_cls)
@@ -85,6 +98,7 @@ void native_comp_class_dtor(void) {
        if (bt_cc_ptr_to_py_cls) {
                BT_LOGD_STR("Destroying native component class to Python component class hash table.");
                g_hash_table_destroy(bt_cc_ptr_to_py_cls);
+               bt_cc_ptr_to_py_cls = NULL;
        }
 }
 
This page took 0.028277 seconds and 4 git commands to generate.