*/
#define BT_LOG_TAG "TRACE"
-#include <babeltrace/lib-logging-internal.h>
-
-#include <babeltrace/assert-pre-internal.h>
-#include <babeltrace/trace-ir/trace-class.h>
-#include <babeltrace/trace-ir/trace-class-const.h>
-#include <babeltrace/trace-ir/trace-internal.h>
-#include <babeltrace/trace-ir/clock-class-internal.h>
-#include <babeltrace/trace-ir/stream-internal.h>
-#include <babeltrace/trace-ir/stream-class-internal.h>
-#include <babeltrace/trace-ir/event-internal.h>
-#include <babeltrace/trace-ir/event-class.h>
-#include <babeltrace/trace-ir/event-class-internal.h>
-#include <babeltrace/ctf-writer/functor-internal.h>
-#include <babeltrace/ctf-writer/clock-internal.h>
-#include <babeltrace/trace-ir/field-wrapper-internal.h>
-#include <babeltrace/trace-ir/field-class-internal.h>
-#include <babeltrace/trace-ir/attributes-internal.h>
-#include <babeltrace/trace-ir/utils-internal.h>
-#include <babeltrace/trace-ir/resolve-field-path-internal.h>
-#include <babeltrace/compiler-internal.h>
-#include <babeltrace/value.h>
-#include <babeltrace/value-const.h>
-#include <babeltrace/value-internal.h>
-#include <babeltrace/types.h>
-#include <babeltrace/endian-internal.h>
-#include <babeltrace/assert-internal.h>
-#include <babeltrace/compat/glib-internal.h>
+#include <babeltrace2/lib-logging-internal.h>
+
+#include <babeltrace2/assert-pre-internal.h>
+#include <babeltrace2/trace-ir/trace-class.h>
+#include <babeltrace2/trace-ir/trace-class-const.h>
+#include <babeltrace2/trace-ir/trace-internal.h>
+#include <babeltrace2/trace-ir/clock-class-internal.h>
+#include <babeltrace2/trace-ir/stream-internal.h>
+#include <babeltrace2/trace-ir/stream-class-internal.h>
+#include <babeltrace2/trace-ir/event-internal.h>
+#include <babeltrace2/trace-ir/event-class.h>
+#include <babeltrace2/trace-ir/event-class-internal.h>
+#include <babeltrace2/ctf-writer/functor-internal.h>
+#include <babeltrace2/ctf-writer/clock-internal.h>
+#include <babeltrace2/trace-ir/field-wrapper-internal.h>
+#include <babeltrace2/trace-ir/field-class-internal.h>
+#include <babeltrace2/trace-ir/attributes-internal.h>
+#include <babeltrace2/trace-ir/utils-internal.h>
+#include <babeltrace2/trace-ir/resolve-field-path-internal.h>
+#include <babeltrace2/compiler-internal.h>
+#include <babeltrace2/value.h>
+#include <babeltrace2/value-const.h>
+#include <babeltrace2/value-internal.h>
+#include <babeltrace2/types.h>
+#include <babeltrace2/endian-internal.h>
+#include <babeltrace2/assert-internal.h>
+#include <babeltrace2/compat/glib-internal.h>
#include <inttypes.h>
#include <stdint.h>
#include <string.h>
if (tc->destruction_listeners) {
uint64_t i;
BT_LIB_LOGV("Calling trace class destruction listener(s): %!+T", tc);
+
+ /*
+ * The trace class' reference count is 0 if we're here. Increment
+ * it to avoid a double-destroy (possibly infinitely recursive).
+ * This could happen for example if a destruction listener did
+ * bt_object_get_ref() (or anything that causes
+ * bt_object_get_ref() to be called) on the trace class (ref.
+ * count goes from 0 to 1), and then bt_object_put_ref(): the
+ * reference count would go from 1 to 0 again and this function
+ * would be called again.
+ */
+ tc->base.ref_count++;
+
/* Call all the trace class destruction listeners */
for (i = 0; i < tc->destruction_listeners->len; i++) {
struct bt_trace_class_destruction_listener_elem elem =
if (elem.func) {
elem.func(tc, elem.data);
}
+
+ /*
+ * The destruction listener should not have kept a
+ * reference to the trace class.
+ */
+ BT_ASSERT_PRE(tc->base.ref_count == 1, "Destruction listener kept a reference to the trace class being destroyed: %![tc-]+T", tc);
}
g_array_free(tc->destruction_listeners, TRUE);
tc->destruction_listeners = NULL;