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.
This commit is contained in:
morris
2026-06-30 16:52:23 +08:00
parent 80aa3978b3
commit 4196c7ae5c

View File

@@ -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)