50 lines
1.2 KiB
C++
50 lines
1.2 KiB
C++
#pragma once
|
|
#include "freertos/semphr.h"
|
|
#include "freertos/portmacro.h"
|
|
#include "esp_log.h"
|
|
|
|
struct SemaphoreGuard {
|
|
public:
|
|
|
|
SemaphoreGuard(SemaphoreHandle_t semaphore) : semaphore(semaphore) { }
|
|
|
|
portBASE_TYPE take(TickType_t ticks_to_wait = portMAX_DELAY) {
|
|
if (this->semaphore == nullptr) {
|
|
ESP_LOGE("SemaphoreGuard", "Attempted to take a null semaphore");
|
|
return pdFALSE;
|
|
}
|
|
portBASE_TYPE result = xSemaphoreTake(this->semaphore, ticks_to_wait);
|
|
taken = (result == pdTRUE);
|
|
return result;
|
|
}
|
|
|
|
~SemaphoreGuard() {
|
|
if (taken) {
|
|
xSemaphoreGive(this->semaphore);
|
|
}
|
|
}
|
|
|
|
// allow move semantics
|
|
SemaphoreGuard(SemaphoreGuard&& other) noexcept
|
|
: semaphore(other.semaphore), taken(other.taken) {
|
|
other.taken = false;
|
|
}
|
|
SemaphoreGuard& operator=(SemaphoreGuard&& other) noexcept {
|
|
if (this != &other) {
|
|
// move from other
|
|
taken = other.taken;
|
|
other.taken = false;
|
|
semaphore = other.semaphore;
|
|
other.semaphore = nullptr;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
private:
|
|
// prevent copying
|
|
SemaphoreGuard(const SemaphoreGuard&) = delete;
|
|
SemaphoreGuard& operator=(const SemaphoreGuard&) = delete;
|
|
SemaphoreHandle_t semaphore = nullptr;
|
|
bool taken = false;
|
|
};
|