Acknowledge PM media submissions after local commit or preparation failure

This commit is contained in:
evgeny committed 2026-10-29 13:34:26 +01:00
1 parent dae19c06d7
commit 4fd5ebf57a
3 files changed
+13 -4

No files matched your search

+7 -2
View File
@@ -52,6 +52,7 @@ struct dm_file_job {
char input[1024], cipher[1024], plain[1024], temp[1024], output[1024];
int error;
uint64_t generation;
uint64_t request_id;
unsigned held;
};
@@ -567,6 +568,7 @@ static void dm_file_done(void* arg, int error) {
DEBUG_INFO(DEBUG_CATEGORY_DM, "dm_media: prepared conv=%s bytes=%llu name=%s", job->conv,
(unsigned long long)job->size, job->info.name);
chat_event_attachment(inst, 1, job->conv, job->id, 1);
chat_event_submitted(inst, job->request_id, 1);
dm_job_free(job);
return;
}
@@ -627,6 +629,7 @@ fail:
DEBUG_WARN(DEBUG_CATEGORY_DM, "dm_media: file task failed/cancelled work=%d error=%d worker=%d closing=%d",
job->work, error, job->error, media->closing);
if (job->work == DM_FILE_PREPARE) {
chat_event_submitted(inst, job->request_id, 0);
chat_event_attachment(inst, 1, job->conv, job->id, 2);
dm_file_remove(job->plain); dm_file_remove(job->cipher);
if (job->remove_source) dm_file_remove(job->input);
@@ -718,7 +721,7 @@ static int dm_file_lookup(void* arg, uint64_t group, uint64_t peer, const uint8_
/* Путь исходника копируется; caller может освободить строку после возврата. */
int dm_send_file(struct UTUN_INSTANCE* inst, const char* conv, const char* path, const struct attachment_info* info,
int remove_source) {
int remove_source, uint64_t request_id) {
struct dm_media_state* media = inst ? inst->dm_media : NULL;
if (!media || media->closing || !inst->media_async || !conv || !path || attachment_validate(info) || strlen(path) >= 1024) {
DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: invalid file send arguments/state");
@@ -731,6 +734,7 @@ int dm_send_file(struct UTUN_INSTANCE* inst, const char* conv, const char* path,
if (!job) { DEBUG_ERROR(DEBUG_CATEGORY_DM, "dm_media: preparation allocation failed"); return -1; }
job->media = media; job->work = DM_FILE_PREPARE; job->author = inst->node_id;
job->generation = dm_history_generation(inst, conv);
job->request_id = request_id;
if (!dm_history_current(inst, conv, job->generation)) { u_free(job); return -1; }
snprintf(job->conv, sizeof(job->conv), "%s", conv); job->info = *info; job->remove_source = remove_source;
snprintf(job->input, sizeof(job->input), "%s", path);
@@ -775,8 +779,9 @@ void dm_send_file_trampoline(void* arg) {
if (!req) return;
uint64_t generation = req->generation ? req->generation : dm_history_generation(req->inst, req->conv);
int current = dm_history_current(req->inst, req->conv, generation);
if (!current || dm_send_file(req->inst, req->conv, req->path, &req->info, req->remove_source)) {
if (!current || dm_send_file(req->inst, req->conv, req->path, &req->info, req->remove_source, req->request_id)) {
DEBUG_WARN(DEBUG_CATEGORY_DM, "DM files: send rejected conv=%s generation=%llu", req->conv, (unsigned long long)generation);
chat_event_submitted(req->inst, req->request_id, 0);
const uint8_t rejected[16] = {0};
if (current) chat_event_attachment(req->inst, 1, req->conv, rejected, 2);
if (req->remove_source) {
+4 -2
View File
@@ -56,13 +56,15 @@ void dm_media_destroy(struct UTUN_INSTANCE* inst);
* готовность/ошибка подготовки сообщается CHAT_EVT_ATTACHMENT_PREPARATION, включая до возврата 0.
* Беседа должна быть видимой; до 4 одновременных подготовок, plaintext до DM_MEDIA_MAX_SIZE.
* remove_source=1 передаёт worker собственный временный файл приложения для удаления; при -1 его убирает caller.
* Успех подготовки означает commit file-сообщения, не доставку. Пользовательский исходник: remove_source=0. */
* Успех подготовки означает commit file-сообщения, не доставку. Пользовательский исходник: remove_source=0.
* request_id!=0 получает CHAT_EVT_MSG_SUBMITTED после commit/ошибки; при возврате -1 событие посылает caller. */
int dm_send_file(struct UTUN_INSTANCE* inst, const char* conv, const char* path, const struct attachment_info* info,
int remove_source);
int remove_source, uint64_t request_id);
struct dm_file_req {
struct UTUN_INSTANCE* inst; /* Заимствованное ядро до callback. */
char conv[64]; /* Десятичный ID беседы с NUL. */
uint64_t generation; /* Ожидаемое поколение; 0=захватить при входе в uasync. */
uint64_t request_id; /* Корреляция результата локального commit, 0=без подтверждения. */
char path[1024]; /* Путь исходника с NUL; копируется при принятии. */
struct attachment_info info; /* Проверенные метаданные вложения. */
int remove_source; /* Только принадлежащий приложению временный файл. */
+2
View File
@@ -108,11 +108,13 @@ static void attachment_publish(struct attachment_send_req* req, int error) {
if (file) {
file->inst = req->inst; file->info = req->info; file->remove_source = 1;
file->generation = req->dm_generation;
file->request_id = req->request_id;
snprintf(file->conv, sizeof(file->conv), "%s", req->target);
snprintf(file->path, sizeof(file->path), "%s", req->output);
dm_send_file_trampoline(file);
} else {
DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "attachment: PM dispatch allocation failed");
chat_event_submitted(req->inst, req->request_id, 0);
chat_event_attachment(req->inst, req->is_dm, req->target, req->id, 2);
if (remove(req->output)) DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "attachment: rejected output cleanup failed");
}