mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
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:
@@ -40,6 +40,7 @@ esp_err_t jpeg_acquire_codec_handle(jpeg_codec_handle_t *jpeg_new_codec)
|
|||||||
#endif
|
#endif
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
bool new_codec = false;
|
bool new_codec = false;
|
||||||
|
bool bus_clock_enabled = false;
|
||||||
jpeg_codec_t *codec = NULL;
|
jpeg_codec_t *codec = NULL;
|
||||||
_lock_acquire(&s_jpeg_platform.mutex);
|
_lock_acquire(&s_jpeg_platform.mutex);
|
||||||
if (!s_jpeg_platform.jpeg_codec) {
|
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->intr_priority = -1;
|
||||||
codec->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
codec->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
|
||||||
codec->codec_mutex = xSemaphoreCreateBinaryWithCaps(JPEG_MEM_ALLOC_CAPS);
|
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);
|
SLIST_INIT(&codec->jpeg_isr_handler_list);
|
||||||
xSemaphoreGive(codec->codec_mutex);
|
xSemaphoreGive(codec->codec_mutex);
|
||||||
// init the clock
|
// 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_enable_bus_clock(true);
|
||||||
jpeg_ll_reset_module_register();
|
jpeg_ll_reset_module_register();
|
||||||
}
|
}
|
||||||
|
bus_clock_enabled = true;
|
||||||
#if CONFIG_PM_ENABLE
|
#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
|
#endif
|
||||||
jpeg_hal_init(&codec->hal);
|
jpeg_hal_init(&codec->hal);
|
||||||
} else {
|
} 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;
|
*jpeg_new_codec = s_jpeg_platform.jpeg_codec;
|
||||||
_lock_release(&s_jpeg_platform.mutex);
|
_lock_release(&s_jpeg_platform.mutex);
|
||||||
return ret;
|
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)
|
esp_err_t jpeg_release_codec_handle(jpeg_codec_handle_t jpeg_codec)
|
||||||
|
|||||||
Reference in New Issue
Block a user