From b1d4725de1a52847f851e943db33fc3cf80be7da Mon Sep 17 00:00:00 2001 From: morris Date: Tue, 30 Jun 2026 16:52:23 +0800 Subject: [PATCH] fix(jpeg): release platform mutex on semaphore/pm-lock allocation failure jpeg_acquire_codec_handle acquires s_jpeg_platform.mutex at entry but two ESP_RETURN_ON_* macros (semaphore-create and PM-lock-create failure) return without releasing it. Replace with ESP_GOTO_ON_* that jumps to a cleanup label which frees partial resources, NULLs the codec pointer, and releases the mutex. --- components/esp_driver_jpeg/jpeg_common.c | 28 ++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/components/esp_driver_jpeg/jpeg_common.c b/components/esp_driver_jpeg/jpeg_common.c index 28f9b54a2b9..60c3b71357c 100644 --- a/components/esp_driver_jpeg/jpeg_common.c +++ b/components/esp_driver_jpeg/jpeg_common.c @@ -40,6 +40,7 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec) #endif esp_err_t ret = ESP_OK; bool new_codec = false; + bool bus_clock_enabled = false; jpeg_codec_t *codec = NULL; _lock_acquire(&s_jpeg_platform.mutex); if (!s_jpeg_platform.jpeg_codec) { @@ -50,7 +51,7 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec) codec->intr_priority = -1; codec->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; codec->codec_mutex = xSemaphoreCreateBinaryWithCaps(JPEG_MEM_ALLOC_CAPS); - ESP_RETURN_ON_FALSE(codec->codec_mutex, ESP_ERR_NO_MEM, TAG, "No memory for codec mutex"); + ESP_GOTO_ON_FALSE(codec->codec_mutex, ESP_ERR_NO_MEM, err, TAG, "No memory for codec mutex"); SLIST_INIT(&codec->jpeg_isr_handler_list); xSemaphoreGive(codec->codec_mutex); // init the clock @@ -58,8 +59,10 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec) jpeg_ll_enable_bus_clock(true); jpeg_ll_reset_module_register(); } + bus_clock_enabled = true; #if CONFIG_PM_ENABLE - ESP_RETURN_ON_ERROR(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "jpeg_codec", &codec->pm_lock), TAG, "create pm lock failed"); + ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "jpeg_codec", &codec->pm_lock), + err, TAG, "create pm lock failed"); #endif jpeg_hal_init(&codec->hal); } else { @@ -78,6 +81,27 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec) *jpeg_new_codec = s_jpeg_platform.jpeg_codec; _lock_release(&s_jpeg_platform.mutex); return ret; + +err: + if (codec) { + if (codec->codec_mutex) { + vSemaphoreDeleteWithCaps(codec->codec_mutex); + } +#if CONFIG_PM_ENABLE + if (codec->pm_lock) { + esp_pm_lock_delete(codec->pm_lock); + } +#endif + if (bus_clock_enabled) { + PERIPH_RCC_ATOMIC() { + jpeg_ll_enable_bus_clock(false); + } + } + free(codec); + } + s_jpeg_platform.jpeg_codec = NULL; + _lock_release(&s_jpeg_platform.mutex); + return ret; } esp_err_t jpeg_release_codec_handle(jpeg_codec_handle_t jpeg_codec)