+static inline
+void bt_event_reset(struct bt_event *event)
+{
+ BT_ASSERT(event);
+ bt_event_set_is_frozen(event, false);
+ bt_event_reset_dev_mode(event);
+ 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 = 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_object_put_no_null_check(&event_class->common.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_COMMON_HOT(BT_TO_COMMON(event), "Event");
+ BT_ASSERT(!event->packet);
+ event->packet = packet;
+ bt_object_get_no_null_check_no_parent_check(&event->packet->base);
+ BT_LOGV("Set event's packet: event-addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64 ", "
+ "packet-addr=%p",
+ event, bt_event_class_common_get_name(event->common.class),
+ bt_event_class_common_get_id(event->common.class), 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: "
+ "%![event-class-]+E", event_class);
+ goto end;
+ }
+
+ if (unlikely(!event->common.class)) {
+ event->common.class = BT_TO_COMMON(event_class);
+ bt_object_get_no_null_check(&event_class->common.base);
+ }
+
+ BT_ASSERT(packet);
+ bt_event_set_packet(event, packet);
+ goto end;
+
+end:
+ return event;
+}
+