From 4d18a7015d1c16d85203100a1000fa59b254d7f6 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 18:50:28 +0100 Subject: [PATCH] Report cancelled composer submissions before releasing their owned requests --- tools/chatgui/transport/gui_bridge.h | 5 ++++- tools/chatgui/transport/gui_bridge_impl.cpp | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/chatgui/transport/gui_bridge.h b/tools/chatgui/transport/gui_bridge.h index b0864454..75eb5bec 100644 --- a/tools/chatgui/transport/gui_bridge.h +++ b/tools/chatgui/transport/gui_bridge.h @@ -105,7 +105,10 @@ int gui_bridge_post_setting(enum gui_setting_target target, const char* key, con * Владение и результат — как у post_setting; строка/форма вызывающего после возврата больше не нужны. */ int gui_bridge_update_name(const char* name); -/* Composer-запрос: 0 — владение req передано, callback/отмена освободят блок; -1 — req остаётся вызывающему. */ +/* Composer-запрос: 0 — владение req передано, callback/отмена освободят блок; -1 — req остаётся вызывающему. + * inst привязывается к опубликованному ядру под mutex; data должен жить вместе с req (обычно в том же u_malloc-блоке). + * Ненулевой request_id получает MSG_SUBMITTED после сохранения либо отказ при отмене до исполнения. + * При -1 результата нет: вызывающий освобождает req и сам сообщает об отказе своему composer. */ struct chat_msg_submit; int gui_bridge_submit_message(struct chat_msg_submit* req); diff --git a/tools/chatgui/transport/gui_bridge_impl.cpp b/tools/chatgui/transport/gui_bridge_impl.cpp index 2bf6eeb8..2fea9eac 100644 --- a/tools/chatgui/transport/gui_bridge_impl.cpp +++ b/tools/chatgui/transport/gui_bridge_impl.cpp @@ -806,13 +806,23 @@ int gui_bridge_update_name(const char* name) { return 0; } +/* Отмена выполняется в uasync, но не вызывает обработчик ядра под bridge_mutex; результат копируется в Qt-очередь. */ +static void cancel_message_submit(void* arg) { + auto* request = static_cast(arg); + DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "composer submission cancelled: request=%llu", (unsigned long long)request->request_id); + if (!request->request_id) return; + uint8_t result[9] = {0}; + for (unsigned i = 0; i < 8; ++i) result[i] = (uint8_t)(request->request_id >> (8 * i)); + gui_bridge_post(CHAT_EVT_MSG_SUBMITTED, result, sizeof(result)); +} + int gui_bridge_submit_message(struct chat_msg_submit* req) { std::lock_guard guard(bridge_mutex); if (!req || !g_inst || !g_ua || !uasync_is_running(g_ua)) { DEBUG_ERROR(DEBUG_CATEGORY_CHAT_SYNC, "composer submission: core unavailable"); return -1; } req->inst = g_inst; - return post_command(chat_core_submit_trampoline, req, true); + return post_command(chat_core_submit_trampoline, req, true, cancel_message_submit); } int gui_bridge_is_uasync_ready(void) {