PR #23891 opened by Raja-89
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23891
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23891.patch

This PR addresses the teardown crash/deadlock issue when `batch_size > 0`.

Initially, it seemed like the deadlock was caused by `inference_done` during 
batching, but after debugging the core dump using GDB on the filter pipeline, I 
found the root cause was a multi-threading race condition during early 
teardown. 

When a filter is cancelled early (e.g., using `-frames:v 5` or pressing 'q'), 
the main thread calls `dnn_free_model_th` and destroys the `request_queue` and 
the Torch model. However, because the asynchronous threads are spawned with 
`pthread_detach`, they continue running. When the detached thread finishes 
inference and attempts to push the request back to the destroyed 
`request_queue`, it triggers a segmentation fault.

To fix this, I added a synchronization loop in `dnn_free_model_th` that forces 
the main thread to wait (`av_usleep`) until all allocated requests 
(`ctx->nireq`) have been safely returned to the queue. This guarantees that all 
detached threads have completely finished using the PyTorch model memory before 
the model is destroyed. This mirrors how the OpenVINO backend handles thread 
synchronization implicitly during teardown.



>From faa60a0980e65ccfb7c88c6664622c9cd30b1e22 Mon Sep 17 00:00:00 2001
From: Raja-89 <[email protected]>
Date: Thu, 23 Jul 2026 23:22:32 +0530
Subject: [PATCH] avfilter/dnn_backend_torch: Fix race condition during filter
 teardown

When the filter graph is torn down early (e.g. at EOF), the main thread frees 
the Torch model and destroys the request queue. If asynchronous inference 
threads are still active, they will crash when attempting to return their 
requests to the destroyed queue. This adds a synchronization loop in 
dnn_free_model_th to ensure all allocated requests have been safely returned to 
the pool before destroying the model.
---
 libavfilter/dnn/dnn_backend_torch.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/libavfilter/dnn/dnn_backend_torch.cpp 
b/libavfilter/dnn/dnn_backend_torch.cpp
index 9ba6d61377..121adc4a66 100644
--- a/libavfilter/dnn/dnn_backend_torch.cpp
+++ b/libavfilter/dnn/dnn_backend_torch.cpp
@@ -34,6 +34,7 @@ extern "C" {
 #include "libavutil/cpu.h"
 #include "queue.h"
 #include "safe_queue.h"
+#include "libavutil/time.h"
 }
 
 typedef struct THModel {
@@ -123,6 +124,9 @@ static void dnn_free_model_th(DNNModel **model)
     th_model = (THModel *)(*model);
 
     if (th_model->request_queue) {
+        while (ff_safe_queue_size(th_model->request_queue) < 
th_model->ctx->nireq) {
+            av_usleep(10000);
+        }
         while (ff_safe_queue_size(th_model->request_queue) != 0) {
             THRequestItem *item = (THRequestItem 
*)ff_safe_queue_pop_front(th_model->request_queue);
             destroy_request_item(&item);
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to