Skip to content

Commit bc467de

Browse files
committed
Added RAII shutdown to esp-timer/src/esp_timer/timer.h and esp-timer/src/esp_timer/timer.cpp: new destructor/deinit, task stop flag, and task loops now clear their handles and exit so deinit waits for clean teardown before freeing mutexes and queues.
1 parent ec60c56 commit bc467de

2 files changed

Lines changed: 58 additions & 5 deletions

File tree

src/esp_timer/timer.cpp

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,41 @@
33
#include <algorithm>
44
#include <type_traits>
55

6+
ESPTimer::~ESPTimer() {
7+
deinit();
8+
}
9+
10+
void ESPTimer::deinit() {
11+
if (!initialized_) return;
12+
13+
running_.store(false, std::memory_order_release);
14+
15+
auto waitForTaskExit = [&](TaskHandle_t& handle) {
16+
while (handle) {
17+
vTaskDelay(pdMS_TO_TICKS(1));
18+
}
19+
};
20+
21+
waitForTaskExit(hTimeout_);
22+
waitForTaskExit(hInterval_);
23+
waitForTaskExit(hSec_);
24+
waitForTaskExit(hMs_);
25+
waitForTaskExit(hMin_);
26+
27+
timeouts_.clear();
28+
intervals_.clear();
29+
secs_.clear();
30+
mss_.clear();
31+
mins_.clear();
32+
33+
if (mutex_) {
34+
vSemaphoreDelete(mutex_);
35+
mutex_ = nullptr;
36+
}
37+
38+
initialized_ = false;
39+
}
40+
641
// Internal lock utilities
742
void ESPTimer::lock() {
843
if (mutex_) {
@@ -31,6 +66,8 @@ void ESPTimer::init(const ESPTimerConfig& cfg) {
3166
mutex_ = xSemaphoreCreateMutex();
3267
}
3368

69+
running_.store(true, std::memory_order_release);
70+
3471
auto createTask = [&](TaskFunction_t fn, const char* name, uint16_t stack, UBaseType_t prio,
3572
TaskHandle_t* handle, int8_t core) {
3673
BaseType_t ok;
@@ -340,7 +377,7 @@ void ESPTimer::minTaskTrampoline(void* arg) { static_cast<ESPTimer*>(arg)->minTa
340377

341378
// Task loops
342379
void ESPTimer::timeoutTask() {
343-
for (;;) {
380+
while (running_.load(std::memory_order_acquire)) {
344381
const uint32_t now = millis();
345382
std::vector<std::function<void()>> toCall;
346383

@@ -365,10 +402,12 @@ void ESPTimer::timeoutTask() {
365402

366403
vTaskDelay(pdMS_TO_TICKS(1));
367404
}
405+
hTimeout_ = nullptr;
406+
vTaskDelete(nullptr);
368407
}
369408

370409
void ESPTimer::intervalTask() {
371-
for (;;) {
410+
while (running_.load(std::memory_order_acquire)) {
372411
const uint32_t now = millis();
373412
std::vector<std::function<void()>> toCall;
374413

@@ -394,10 +433,12 @@ void ESPTimer::intervalTask() {
394433

395434
vTaskDelay(pdMS_TO_TICKS(1));
396435
}
436+
hInterval_ = nullptr;
437+
vTaskDelete(nullptr);
397438
}
398439

399440
void ESPTimer::secTask() {
400-
for (;;) {
441+
while (running_.load(std::memory_order_acquire)) {
401442
const uint32_t now = millis();
402443
struct Call { std::function<void(int)> fn; int arg; };
403444
std::vector<Call> toCall;
@@ -432,10 +473,12 @@ void ESPTimer::secTask() {
432473

433474
vTaskDelay(pdMS_TO_TICKS(10));
434475
}
476+
hSec_ = nullptr;
477+
vTaskDelete(nullptr);
435478
}
436479

437480
void ESPTimer::msTask() {
438-
for (;;) {
481+
while (running_.load(std::memory_order_acquire)) {
439482
const uint32_t now = millis();
440483
struct Call { std::function<void(uint32_t)> fn; uint32_t arg; };
441484
std::vector<Call> toCall;
@@ -467,10 +510,12 @@ void ESPTimer::msTask() {
467510

468511
vTaskDelay(pdMS_TO_TICKS(1));
469512
}
513+
hMs_ = nullptr;
514+
vTaskDelete(nullptr);
470515
}
471516

472517
void ESPTimer::minTask() {
473-
for (;;) {
518+
while (running_.load(std::memory_order_acquire)) {
474519
const uint32_t now = millis();
475520
struct Call { std::function<void(int)> fn; int arg; };
476521
std::vector<Call> toCall;
@@ -505,4 +550,6 @@ void ESPTimer::minTask() {
505550

506551
vTaskDelay(pdMS_TO_TICKS(100));
507552
}
553+
hMin_ = nullptr;
554+
vTaskDelete(nullptr);
508555
}

src/esp_timer/timer.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <Arduino.h>
44
#include <functional>
55
#include <vector>
6+
#include <atomic>
67
#include <freertos/FreeRTOS.h>
78
#include <freertos/task.h>
89
#include <freertos/semphr.h>
@@ -41,7 +42,11 @@ struct ESPTimerConfig {
4142

4243
class ESPTimer {
4344
public:
45+
~ESPTimer();
46+
4447
void init(const ESPTimerConfig& cfg = ESPTimerConfig());
48+
void deinit();
49+
bool initialized() const { return initialized_; }
4550

4651
// Scheduling
4752
uint32_t setTimeout(std::function<void()> cb, uint32_t delayMs);
@@ -137,6 +142,7 @@ class ESPTimer {
137142

138143
ESPTimerConfig cfg_{};
139144
bool initialized_ = false;
145+
std::atomic<bool> running_{false};
140146
uint32_t nextId_ = 1;
141147

142148
uint32_t nextId();

0 commit comments

Comments
 (0)