From ba409427c62e53a5ddfe32e16e4ae8413c5b3405 Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 1 Oct 2026 17:51:09 +0300 Subject: [PATCH] Bound media worker concurrency and reject incomplete file copies --- src/media_async/media_async.c | 15 +++++++++++---- src/media_async/media_async.h | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/media_async/media_async.c b/src/media_async/media_async.c index 62c9efb3..429eba3c 100644 --- a/src/media_async/media_async.c +++ b/src/media_async/media_async.c @@ -87,6 +87,9 @@ void media_async_submit(struct media_async* ma, struct UASYNC* ua, if (done) done(arg, MEDIA_ASYNC_CANCELLED); return; } + unsigned active = 0; + for (struct ma_thread_ctx* pending = ma->jobs; pending; pending = pending->next) active++; + if (active >= 16) { DEBUG_WARN(DEBUG_CATEGORY_MEDIA, "media task limit reached active=%u", active); done(arg, -1); return; } struct ma_thread_ctx* job = u_calloc(1, sizeof(*job)); if (!job) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "media task allocation failed"); done(arg, -1); return; } job->owner = ma; job->ua = ua; job->work = work; job->data = data; job->done = done; job->arg = arg; @@ -114,8 +117,9 @@ int ma_sha256_file(const char* path, uint8_t hash_out[32]) { uint8_t buf[65536]; size_t rd; while ((rd = fread(buf, 1, sizeof(buf), f)) > 0) SHA256_Update(&ctx, buf, rd); - fclose(f); - + int error = ferror(f); + if (fclose(f)) error = 1; + if (error) { DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "ma_sha256_file: read/close failed path=%s", path); return -1; } SHA256_Final(hash_out, &ctx); return 0; } @@ -162,8 +166,11 @@ int ma_copy_file(const char* src, const char* dst) { fclose(s); fclose(d); return -1; } } - fclose(s); fclose(d); - return 0; + int error = ferror(s); + if (fclose(s)) error = 1; + if (fclose(d)) error = 1; + if (error) DEBUG_ERROR(DEBUG_CATEGORY_MEDIA, "ma_copy_file: read/close failed src=%s dst=%s", src, dst); + return error ? -1 : 0; } int ma_file_size(const char* path) { diff --git a/src/media_async/media_async.h b/src/media_async/media_async.h index 47ae18cd..4bb605cc 100644 --- a/src/media_async/media_async.h +++ b/src/media_async/media_async.h @@ -26,7 +26,7 @@ struct media_async* media_async_create(void); * вызывает ожидающие done и освобождает ma; NULL допустим. */ void media_async_destroy(struct media_async* ma); -/* Передать задачу; data/arg остаются у вызывающего до done. При ошибке done +/* Передать задачу (не более 16 активных); data/arg остаются у вызывающего до done. При ошибке done * может быть вызван синхронно. Ошибку самой work передают через data, а не err. */ void media_async_submit(struct media_async* ma, struct UASYNC* ua, ma_work_fn work, void* data,