/* SPDX-License-Identifier: GPL-3.0-only */ /* Shared recursive gate for administrative command execution origins. */ #include "admin_command_gate.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" static portMUX_TYPE s_lock = portMUX_INITIALIZER_UNLOCKED; static SemaphoreHandle_t s_gate; esp_err_t admin_command_gate_take(void) { taskENTER_CRITICAL(&s_lock); SemaphoreHandle_t gate = s_gate; taskEXIT_CRITICAL(&s_lock); if (gate == NULL) { SemaphoreHandle_t candidate = xSemaphoreCreateRecursiveMutex(); if (candidate == NULL) { return ESP_ERR_NO_MEM; } taskENTER_CRITICAL(&s_lock); if (s_gate == NULL) { s_gate = candidate; candidate = NULL; } gate = s_gate; taskEXIT_CRITICAL(&s_lock); if (candidate != NULL) { vSemaphoreDelete(candidate); } } return xSemaphoreTakeRecursive(gate, portMAX_DELAY) == pdTRUE ? ESP_OK : ESP_FAIL; } void admin_command_gate_give(void) { taskENTER_CRITICAL(&s_lock); SemaphoreHandle_t gate = s_gate; taskEXIT_CRITICAL(&s_lock); if (gate != NULL) { (void)xSemaphoreGiveRecursive(gate); } }