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>
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)
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:
# Subclasses must provide these methods or property:
struct bt_component_class_sink *bt_bt2_component_class_sink_create(
PyObject *py_cls, const char *name, const char *description,
const char *help);
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);
static GHashTable *bt_cc_ptr_to_py_cls;
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)
static
void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
PyObject *py_cls)
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);
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;