This commit adds the case handling if the asynchronous execution of a request fails by checking the exit status of the thread when joining before starting another execution. On failure, it does the cleanup as well.
Unified · Split
| @@ -23,6 +23,9 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include "dnn_backend_common.h" |
| 25 | 25 | |
| 26 | +#define DNN_ASYNC_SUCCESS (void *)0 | |
| 27 | +#define DNN_ASYNC_FAIL (void *)-1 | |
| 28 | + | |
| 26 | 29 | int ff_check_exec_params(void *ctx, DNNBackendType backend, DNNFunctionType func_type, DNNExecBaseParams *exec_params) |
| 27 | 30 | { |
| 28 | 31 | if (!exec_params) { |
| @@ -79,18 +82,25 @@ static void *async_thread_routine(void *args) · 50 unmodified lines | ||
| 79 | 82 | DNNAsyncExecModule *async_module = args; |
| 80 | 83 | void *request = async_module->args; |
| 81 | 84 | |
| 82 | − async_module->start_inference(request); | |
| 85 | + if (async_module->start_inference(request) != DNN_SUCCESS) { | |
| 86 | + return DNN_ASYNC_FAIL; | |
| 87 | + } | |
| 83 | 88 | async_module->callback(request); |
| 84 | − return NULL; | |
| 89 | + return DNN_ASYNC_SUCCESS; | |
| 85 | 90 | } |
| 86 | 91 | |
| 87 | 92 | DNNReturnType ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module) |
| 88 | 93 | { |
| 94 | + void *status = 0; | |
| 89 | 95 | if (!async_module) { |
| 90 | 96 | return DNN_ERROR; |
| 91 | 97 | } |
| 92 | 98 | #if HAVE_PTHREAD_CANCEL |
| 93 | − pthread_join(async_module->thread_id, NULL); | |
| 99 | + pthread_join(async_module->thread_id, &status); | |
| 100 | + if (status == DNN_ASYNC_FAIL) { | |
| 101 | + av_log(NULL, AV_LOG_ERROR, "Last Inference Failed.\n"); | |
| 102 | + return DNN_ERROR; | |
| 103 | + } | |
| 94 | 104 | #endif |
| 95 | 105 | async_module->start_inference = NULL; |
| 96 | 106 | async_module->callback = NULL; |
| @@ -101,6 +111,7 @@ DNNReturnType ff_dnn_async_module_cleanup(DNNAsyncExecModule *async_module) · 4 unmodified lines | ||
| 101 | 111 | DNNReturnType ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_module) |
| 102 | 112 | { |
| 103 | 113 | int ret; |
| 114 | + void *status = 0; | |
| 104 | 115 | |
| 105 | 116 | if (!async_module) { |
| 106 | 117 | av_log(ctx, AV_LOG_ERROR, "async_module is null when starting async inference.\n"); |
| @@ -108,7 +119,11 @@ DNNReturnType ff_dnn_start_inference_async(void *ctx, DNNAsyncExecModule *async_ · 1 unmodified line | ||
| 108 | 119 | } |
| 109 | 120 | |
| 110 | 121 | #if HAVE_PTHREAD_CANCEL |
| 111 | − pthread_join(async_module->thread_id, NULL); | |
| 122 | + pthread_join(async_module->thread_id, &status); | |
| 123 | + if (status == DNN_ASYNC_FAIL) { | |
| 124 | + av_log(ctx, AV_LOG_ERROR, "Unable to start inference as previous inference failed.\n"); | |
| 125 | + return DNN_ERROR; | |
| 126 | + } | |
| 112 | 127 | ret = pthread_create(&async_module->thread_id, NULL, async_thread_routine, async_module); |
| 113 | 128 | if (ret != 0) { |
| 114 | 129 | av_log(ctx, AV_LOG_ERROR, "Unable to start async inference.\n"); |
| @@ -91,6 +91,7 @@ AVFILTER_DEFINE_CLASS(dnn_tensorflow); · 90 unmodified lines | ||
| 91 | 91 | |
| 92 | 92 | static DNNReturnType execute_model_tf(TFRequestItem *request, Queue *inference_queue); |
| 93 | 93 | static void infer_completion_callback(void *args); |
| 94 | +static inline void destroy_request_item(TFRequestItem **arg); | |
| 94 | 95 | |
| 95 | 96 | static void free_buffer(void *data, size_t length) |
| 96 | 97 | { |
| @@ -172,6 +173,10 @@ static DNNReturnType tf_start_inference(void *args) · 75 unmodified lines | ||
| 172 | 173 | request->status); |
| 173 | 174 | if (TF_GetCode(request->status) != TF_OK) { |
| 174 | 175 | av_log(&tf_model->ctx, AV_LOG_ERROR, "%s", TF_Message(request->status)); |
| 176 | + tf_free_request(infer_request); | |
| 177 | + if (ff_safe_queue_push_back(tf_model->request_queue, request) < 0) { | |
| 178 | + destroy_request_item(&request); | |
| 179 | + } | |
| 175 | 180 | return DNN_ERROR; |
| 176 | 181 | } |
| 177 | 182 | return DNN_SUCCESS; |
| @@ -1095,7 +1100,10 @@ static DNNReturnType execute_model_tf(TFRequestItem *request, Queue *inference_q · 917 unmodified lines | ||
| 1095 | 1100 | } |
| 1096 | 1101 | |
| 1097 | 1102 | if (task->async) { |
| 1098 | − return ff_dnn_start_inference_async(ctx, &request->exec_module); | |
| 1103 | + if (ff_dnn_start_inference_async(ctx, &request->exec_module) != DNN_SUCCESS) { | |
| 1104 | + goto err; | |
| 1105 | + } | |
| 1106 | + return DNN_SUCCESS; | |
| 1099 | 1107 | } else { |
| 1100 | 1108 | if (tf_start_inference(request) != DNN_SUCCESS) { |
| 1101 | 1109 | goto err; |