Files
ESP32_Serial_Swiss_Army_Knife/src/admin_command_gate.c
T

45 lines
1.2 KiB
C

/* 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);
}
}