+enum bt_trace_class_status bt_trace_class_add_destruction_listener(
+ const struct bt_trace_class *_tc,
+ bt_trace_class_destruction_listener_func listener,
+ void *data, uint64_t *listener_id)
+{
+ struct bt_trace_class *tc = (void *) _tc;
+ uint64_t i;
+ struct bt_trace_class_destruction_listener_elem new_elem = {
+ .func = listener,
+ .data = data,
+ };
+
+ BT_ASSERT_PRE_NON_NULL(tc, "Trace class");
+ BT_ASSERT_PRE_NON_NULL(listener, "Listener");
+
+ /* Find the next available spot */
+ for (i = 0; i < tc->destruction_listeners->len; i++) {
+ struct bt_trace_class_destruction_listener_elem elem =
+ g_array_index(tc->destruction_listeners,
+ struct bt_trace_class_destruction_listener_elem, i);
+
+ if (!elem.func) {
+ break;
+ }
+ }
+
+ if (i == tc->destruction_listeners->len) {
+ g_array_append_val(tc->destruction_listeners, new_elem);
+ } else {
+ g_array_insert_val(tc->destruction_listeners, i, new_elem);
+ }
+
+ if (listener_id) {
+ *listener_id = i;
+ }
+
+ BT_LIB_LOGV("Added trace class destruction listener: %![tc-]+T, "
+ "listener-id=%" PRIu64, tc, i);
+ return BT_TRACE_CLASS_STATUS_OK;
+}
+
+BT_ASSERT_PRE_FUNC
+static
+bool has_listener_id(const struct bt_trace_class *tc, uint64_t listener_id)
+{
+ BT_ASSERT(listener_id < tc->destruction_listeners->len);
+ return (&g_array_index(tc->destruction_listeners,
+ struct bt_trace_class_destruction_listener_elem,
+ listener_id))->func != NULL;
+}
+
+enum bt_trace_class_status bt_trace_class_remove_destruction_listener(
+ const struct bt_trace_class *_tc, uint64_t listener_id)
+{
+ struct bt_trace_class *tc = (void *) _tc;
+ struct bt_trace_class_destruction_listener_elem *elem;
+
+ BT_ASSERT_PRE_NON_NULL(tc, "Trace class");
+ BT_ASSERT_PRE(has_listener_id(tc, listener_id),
+ "Trace class has no such trace class destruction listener ID: "
+ "%![tc-]+T, %" PRIu64, tc, listener_id);
+ elem = &g_array_index(tc->destruction_listeners,
+ struct bt_trace_class_destruction_listener_elem,
+ listener_id);
+ BT_ASSERT(elem->func);
+
+ elem->func = NULL;
+ elem->data = NULL;
+ BT_LIB_LOGV("Removed trace class destruction listener: "
+ "%![tc-]+T, listener-id=%" PRIu64,
+ tc, listener_id);
+ return BT_TRACE_CLASS_STATUS_OK;
+}
+