- BT_LOGD("Freezing event: addr=%p, "
- "event-class-name=\"%s\", event-class-id=%" PRId64,
- event, bt_ctf_event_class_get_name(event->event_class),
- bt_ctf_event_class_get_id(event->event_class));
- bt_ctf_packet_freeze(event->packet);
- BT_LOGD_STR("Freezing event's header field.");
- bt_ctf_field_freeze(event->event_header);
- BT_LOGD_STR("Freezing event's stream event context field.");
- bt_ctf_field_freeze(event->stream_event_context);
- BT_LOGD_STR("Freezing event's context field.");
- bt_ctf_field_freeze(event->context_payload);
- BT_LOGD_STR("Freezing event's payload field.");
- bt_ctf_field_freeze(event->fields_payload);
- event->frozen = 1;
+ /*
+ * Those are the important ordered steps:
+ *
+ * 1. Reset the event object (put any permanent reference it
+ * has, unfreeze it and its fields in developer mode, etc.),
+ * but do NOT put its class's reference. This event class
+ * contains the pool to which we're about to recycle this
+ * event object, so we must guarantee its existence thanks
+ * to this existing reference.
+ *
+ * 2. Move the event class reference to our `event_class`
+ * variable so that we can set the event's class member
+ * to NULL before recycling it. We CANNOT do this after
+ * we put the event class reference because this bt_put()
+ * could destroy the event class, also destroying its
+ * event pool, thus also destroying our event object (this
+ * would result in an invalid write access).
+ *
+ * 3. Recycle the event object.
+ *
+ * 4. Put our event class reference.
+ */
+ bt_event_reset(event);
+ event_class = BT_FROM_COMMON(event->common.class);
+ BT_ASSERT(event_class);
+ event->common.class = NULL;
+ bt_object_pool_recycle_object(&event_class->event_pool, event);
+ bt_put(event_class);
+}
+
+int bt_event_move_header(struct bt_event *event,
+ struct bt_event_header_field *header_field)
+{
+ struct bt_stream_class *stream_class;
+ struct bt_field_wrapper *field_wrapper = (void *) header_field;
+
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_NON_NULL(field_wrapper, "Header field");
+ BT_ASSERT_PRE_HOT(BT_TO_COMMON(event), "Event", ": +%!+e", event);
+ stream_class = bt_event_class_borrow_stream_class(
+ bt_event_borrow_class(event));
+ BT_ASSERT_PRE(stream_class->common.event_header_field_type,
+ "Stream class has no event header field type: %!+S",
+ stream_class);
+
+ /* Recycle current header field: always exists */
+ BT_ASSERT(event->common.header_field);
+ bt_event_header_field_recycle(event->common.header_field,
+ stream_class);
+
+ /* Move new field */
+ event->common.header_field = (void *) field_wrapper;
+ return 0;