+ int trace_valid = 0;
+ struct bt_value *environment = NULL;
+
+ stream_class = bt_event_class_borrow_stream_class(event_class);
+ BT_ASSERT(stream_class);
+ trace = bt_stream_class_borrow_trace(stream_class);
+ if (trace) {
+ BT_LOGD_STR("Event class is part of a trace.");
+ packet_header_type =
+ bt_trace_borrow_packet_header_field_type(trace);
+ trace_valid = trace->valid;
+ BT_ASSERT(trace_valid);
+ environment = trace->environment;
+ }
+
+ packet_context_type =
+ bt_stream_class_borrow_packet_context_field_type(
+ stream_class);
+ event_header_type =
+ bt_stream_class_borrow_event_header_field_type(
+ stream_class);
+ stream_event_ctx_type =
+ bt_stream_class_borrow_event_context_field_type(
+ stream_class);
+ event_context_type =
+ bt_event_class_borrow_context_field_type(event_class);
+ event_payload_type =
+ bt_event_class_borrow_payload_field_type(event_class);
+ ret = bt_validate_class_types(environment, packet_header_type,
+ packet_context_type, event_header_type, stream_event_ctx_type,
+ event_context_type, event_payload_type, trace_valid,
+ stream_class->valid, event_class->valid,
+ validation_output, validation_flags, copy_field_type_func);
+ if (ret) {
+ /*
+ * This means something went wrong during the validation
+ * process, not that the objects are invalid.
+ */
+ BT_LOGE("Failed to validate event and parents: ret=%d", ret);
+ goto error;
+ }
+
+ if ((validation_output->valid_flags & validation_flags) !=
+ validation_flags) {
+ /* Invalid trace/stream class/event class */
+ BT_LOGW("Invalid trace, stream class, or event class: "
+ "valid-flags=0x%x", validation_output->valid_flags);
+ goto error;
+ }
+
+ goto end;
+
+error:
+ bt_validation_output_put_types(validation_output);
+ ret = -1;
+
+end:
+ return ret;
+}
+
+static
+int bt_event_create_fields(
+ struct bt_stream_class *stream_class,
+ struct bt_validation_output *validation_output,
+ create_field_func create_field_func,
+ release_field_func release_field_func,
+ create_header_field_func create_header_field_func,
+ release_header_field_func release_header_field_func,
+ struct bt_field_wrapper **header_field,
+ struct bt_field **stream_event_context_field,
+ struct bt_field **context_field,
+ struct bt_field **payload_field)
+{
+ int ret = 0;
+
+ if (validation_output->event_header_type) {
+ BT_LOGD("Creating initial event header field: ft-addr=%p",
+ validation_output->event_header_type);
+ *header_field =
+ create_header_field_func(stream_class,
+ validation_output->event_header_type);
+ if (!*header_field) {
+ BT_LOGE_STR("Cannot create initial event header field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->stream_event_ctx_type) {
+ BT_LOGD("Creating initial stream event context field: ft-addr=%p",
+ validation_output->stream_event_ctx_type);
+ *stream_event_context_field = create_field_func(
+ validation_output->stream_event_ctx_type);
+ if (!*stream_event_context_field) {
+ BT_LOGE_STR("Cannot create initial stream event context field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->event_context_type) {
+ BT_LOGD("Creating initial event context field: ft-addr=%p",
+ validation_output->event_context_type);
+ *context_field = create_field_func(
+ validation_output->event_context_type);
+ if (!*context_field) {
+ BT_LOGE_STR("Cannot create initial event context field object.");
+ goto error;
+ }
+ }
+
+ if (validation_output->event_payload_type) {
+ BT_LOGD("Creating initial event payload field: ft-addr=%p",
+ validation_output->event_payload_type);
+ *payload_field = create_field_func(
+ validation_output->event_payload_type);
+ if (!*payload_field) {
+ BT_LOGE_STR("Cannot create initial event payload field object.");
+ goto error;
+ }
+ }
+
+ goto end;
+
+error:
+ if (*header_field) {
+ release_header_field_func(*header_field, stream_class);
+ }
+
+ if (*stream_event_context_field) {
+ release_field_func(*stream_event_context_field);
+ }
+
+ if (*context_field) {
+ release_field_func(*context_field);
+ }
+
+ if (*payload_field) {
+ release_field_func(*payload_field);
+ }
+
+ ret = -1;
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+int _bt_event_validate(struct bt_event *event)
+{
+ int ret = 0;
+ struct bt_stream_class *stream_class;
+
+ BT_ASSERT(event);
+ if (event->header_field) {
+ ret = bt_field_validate_recursive(
+ event->header_field->field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's header field: "
+ "%![event-]+e, %![field-]+f",
+ event, event->header_field->field);
+ goto end;
+ }
+ }
+
+ stream_class = bt_event_class_borrow_stream_class(event->class);
+
+ /*
+ * We should not have been able to create the event without associating
+ * the event class to a stream class.
+ */
+ BT_ASSERT(stream_class);
+
+ if (stream_class->event_context_field_type) {
+ ret = bt_field_validate_recursive(
+ event->stream_event_context_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's stream event context field: "
+ "%![event-]+e, %![field-]+f",
+ event, event->stream_event_context_field);
+ goto end;
+ }
+ }
+
+ if (event->class->context_field_type) {
+ ret = bt_field_validate_recursive(event->context_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's payload field: "
+ "%![event-]+e, %![field-]+f",
+ event, event->context_field);
+ goto end;
+ }
+ }
+
+ ret = bt_field_validate_recursive(event->payload_field);
+ if (ret) {
+ BT_ASSERT_PRE_MSG("Invalid event's payload field: "
+ "%![event-]+e, %![field-]+f",
+ event, event->payload_field);
+ goto end;
+ }
+
+end:
+ return ret;
+}
+
+BT_HIDDEN
+void _bt_event_set_is_frozen(struct bt_event *event,
+ bool is_frozen)
+{
+ BT_ASSERT(event);
+ BT_LOGD("Freezing event: addr=%p, "
+ "event-class-name=\"%s\", event-class-id=%" PRId64,
+ event, bt_event_class_get_name(event->class),
+ bt_event_class_get_id(event->class));
+
+ if (event->header_field) {
+ BT_LOGD_STR("Freezing event's header field.");
+ bt_field_set_is_frozen_recursive(
+ event->header_field->field, is_frozen);
+ }
+
+ if (event->stream_event_context_field) {
+ BT_LOGD_STR("Freezing event's stream event context field.");
+ bt_field_set_is_frozen_recursive(
+ event->stream_event_context_field, is_frozen);
+ }
+
+ if (event->context_field) {
+ BT_LOGD_STR("Freezing event's context field.");
+ bt_field_set_is_frozen_recursive(event->context_field,
+ is_frozen);
+ }
+
+ if (event->payload_field) {
+ BT_LOGD_STR("Freezing event's payload field.");
+ bt_field_set_is_frozen_recursive(event->payload_field,
+ is_frozen);
+ }
+
+ event->frozen = is_frozen;
+ BT_LOGD_STR("Freezing event's packet.");
+ bt_packet_set_is_frozen(event->packet, is_frozen);
+}
+
+static inline
+int bt_event_initialize(struct bt_event *event,
+ struct bt_event_class *event_class,
+ bt_validation_flag_copy_field_type_func field_type_copy_func,
+ create_field_func create_field_func,
+ release_field_func release_field_func,
+ create_header_field_func create_header_field_func,
+ release_header_field_func release_header_field_func)
+{
+ int ret;
+ struct bt_trace *trace = NULL;
+ struct bt_stream_class *stream_class = NULL;
+ struct bt_field_wrapper *event_header = NULL;