45 lines
1.2 KiB
C
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);
|
|
}
|
|
}
|