+
+/*
+ * Validate that the buffer has enough room to hold empty capture fields.
+ */
+static
+bool validate_buffer_len(struct lttng_event_notifier_notification *notif, size_t captures_left)
+{
+ if (notif->writer.end_write_pos - notif->writer.write_pos < MSG_WRITE_NIL_LEN * captures_left)
+ return false;
+ return true;
+}
+
+void lttng_event_notifier_notification_send(struct lttng_kernel_event_notifier *event_notifier,
+ const char *stack_data,
+ struct lttng_kernel_probe_ctx *probe_ctx,
+ struct lttng_kernel_notification_ctx *notif_ctx)
+{
+ struct lttng_event_notifier_notification notif = { 0 };
+ size_t captures_left;
+
+ if (notification_init(¬if, event_notifier))
+ goto error;
+
+ captures_left = event_notifier->priv->num_captures;
+ if (!validate_buffer_len(¬if, captures_left))
+ goto error;
+
+ if (unlikely(notif_ctx->eval_capture)) {
+ struct lttng_kernel_bytecode_runtime *capture_bc_runtime;
+
+ /*
+ * Iterate over all the capture bytecodes. If the interpreter
+ * functions returns successfully, append the value of the
+ * `output` parameter to the capture buffer. If the interpreter
+ * fails, append an empty capture to the buffer.
+ */
+ list_for_each_entry_rcu(capture_bc_runtime,
+ &event_notifier->priv->capture_bytecode_runtime_head, node) {
+ struct lttng_interpreter_output output;
+ uint8_t *save_pos;
+ int ret = -1;
+
+ lttng_msgpack_save_writer_pos(¬if.writer, &save_pos);
+ captures_left--;
+ if (capture_bc_runtime->interpreter_func(capture_bc_runtime,
+ stack_data, probe_ctx, &output) == LTTNG_KERNEL_BYTECODE_INTERPRETER_OK)
+ ret = notification_append_capture(¬if, &output);
+ if (ret || !validate_buffer_len(¬if, captures_left)) {
+ /*
+ * On append capture error or if the generated
+ * buffer data would not leave enough room to
+ * write empty capture fields for the remaining
+ * fields, skip the field capture by restoring
+ * the msgpack writer position and writing an
+ * empty capture field.
+ */
+ lttng_msgpack_restore_writer_pos(¬if.writer, save_pos);
+ ret = notification_append_empty_capture(¬if);
+ WARN_ON_ONCE(ret);
+ }
+ }
+ }
+
+ if (notif.has_captures && lttng_msgpack_end_array(¬if.writer))
+ goto error;
+
+ /*
+ * Send the notification (including the capture buffer) to the
+ * sessiond.
+ */
+ notification_send(¬if, event_notifier);
+ return;
+
+error:
+ record_error(event_notifier);
+ return;
+}