diff --git a/esphome/core/event_pool.h b/esphome/core/event_pool.h index 6d61e9a80d..198c0fe380 100644 --- a/esphome/core/event_pool.h +++ b/esphome/core/event_pool.h @@ -1,6 +1,6 @@ #pragma once -#ifdef USE_ESP32 +#if defined(USE_ESP32) || defined(USE_LIBRETINY) #include #include @@ -17,6 +17,10 @@ template class EventPool { ~EventPool() { // Clean up any remaining events in the free list + // IMPORTANT: This destructor assumes no concurrent access. The EventPool must not + // be destroyed while any thread might still call allocate() or release(). + // In practice, this is typically ensured by destroying the pool only during + // component shutdown when all producer/consumer threads have been stopped. T *event; RAMAllocator allocator(RAMAllocator::ALLOC_INTERNAL); while ((event = this->free_list_.pop()) != nullptr) { @@ -72,4 +76,4 @@ template class EventPool { } // namespace esphome -#endif +#endif // defined(USE_ESP32) || defined(USE_LIBRETINY) diff --git a/esphome/core/lock_free_queue.h b/esphome/core/lock_free_queue.h index ede7496737..1fc5d25048 100644 --- a/esphome/core/lock_free_queue.h +++ b/esphome/core/lock_free_queue.h @@ -1,11 +1,17 @@ #pragma once -#ifdef USE_ESP32 +#if defined(USE_ESP32) || defined(USE_LIBRETINY) #include #include + +#if defined(USE_ESP32) #include #include +#elif defined(USE_LIBRETINY) +#include +#include +#endif /* * Lock-free queue for single-producer single-consumer scenarios. @@ -13,6 +19,8 @@ * blocking each other. * * This is a Single-Producer Single-Consumer (SPSC) lock-free ring buffer. + * Available on platforms with FreeRTOS support (ESP32, LibreTiny). + * * Common use cases: * - BLE events: BLE task produces, main loop consumes * - MQTT messages: main task produces, MQTT thread consumes @@ -56,6 +64,9 @@ template class LockFreeQueue { uint8_t head_after = head_.load(std::memory_order_acquire); if (head_after == current_tail) { // Consumer just caught up to where tail was - might go to sleep, must notify + // Note: There's a benign race here - between reading head_after and calling + // xTaskNotifyGive(), the consumer could advance further. This would result + // in an unnecessary wake-up, but is harmless and extremely rare in practice. xTaskNotifyGive(task_to_notify_); } // Otherwise: consumer is still behind, no need to notify @@ -113,4 +124,4 @@ template class LockFreeQueue { } // namespace esphome -#endif +#endif // defined(USE_ESP32) || defined(USE_LIBRETINY)