+ if (event->common_context_field) {
+ bt_field_set_is_frozen(
+ event->common_context_field, false);
+ bt_field_reset(
+ event->common_context_field);
+ }
+
+ if (event->specific_context_field) {
+ bt_field_set_is_frozen(
+ event->specific_context_field, false);
+ bt_field_reset(event->specific_context_field);
+ }
+
+ if (event->payload_field) {
+ bt_field_set_is_frozen(
+ event->payload_field, false);
+ bt_field_reset(event->payload_field);
+ }
+}
+
+#ifdef BT_DEV_MODE
+# define bt_event_reset_dev_mode _bt_event_reset_dev_mode
+#else
+# define bt_event_reset_dev_mode(_x)
+#endif
+
+static inline
+void bt_event_reset(struct bt_event *event)
+{
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Resetting event: %!+e", event);
+ bt_event_set_is_frozen(event, false);
+
+ if (event->default_cv) {
+ bt_clock_value_reset(event->default_cv);
+ }
+
+ bt_object_put_no_null_check(&event->packet->base);
+ event->packet = NULL;
+}
+
+static inline
+void bt_event_recycle(struct bt_event *event)
+{
+ struct bt_event_class *event_class;
+
+ BT_ASSERT(event);
+ BT_LIB_LOGD("Recycling event: %!+e", event);
+
+ /*
+ * 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 = event->class;
+ BT_ASSERT(event_class);
+ event->class = NULL;
+ bt_object_pool_recycle_object(&event_class->event_pool, event);
+ bt_object_put_no_null_check(&event_class->base);
+}
+
+static inline
+void bt_event_set_packet(struct bt_event *event, struct bt_packet *packet)
+{
+ BT_ASSERT_PRE_NON_NULL(event, "Event");
+ BT_ASSERT_PRE_NON_NULL(packet, "Packet");
+ BT_ASSERT_PRE_EVENT_HOT(event);
+ BT_ASSERT_PRE(bt_event_class_borrow_stream_class(
+ event->class) == packet->stream->class,
+ "Packet's stream class and event's stream class differ: "
+ "%![event-]+e, %![packet-]+a", event, packet);
+
+ BT_ASSERT(!event->packet);
+ event->packet = packet;
+ bt_object_get_no_null_check_no_parent_check(&event->packet->base);
+ BT_LIB_LOGV("Set event's packet: %![event-]+e, %![packet-]+a",
+ event, packet);
+}
+
+static inline
+struct bt_event *bt_event_create(struct bt_event_class *event_class,
+ struct bt_packet *packet)
+{
+ struct bt_event *event = NULL;
+
+ BT_ASSERT(event_class);
+ event = bt_object_pool_create_object(&event_class->event_pool);
+ if (unlikely(!event)) {
+ BT_LIB_LOGE("Cannot allocate one event from event class's event pool: "
+ "%![ec-]+E", event_class);
+ goto end;
+ }
+
+ if (likely(!event->class)) {
+ event->class = event_class;
+ bt_object_get_no_null_check(&event_class->base);
+ }
+
+ BT_ASSERT(packet);
+ bt_event_set_packet(event, packet);
+ goto end;
+
+end:
+ return event;
+}