diff --git a/esphome/components/mqtt/mqtt_backend_esp32.cpp b/esphome/components/mqtt/mqtt_backend_esp32.cpp index ae3d06a28f..fbfaeb4c5b 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.cpp +++ b/esphome/components/mqtt/mqtt_backend_esp32.cpp @@ -198,8 +198,8 @@ void MQTTBackendESP32::mqtt_event_handler(void *handler_args, esp_event_base_t b return; } event->populate(*static_cast(event_data)); - // Push always succeeds: pool is sized to queue capacity (N-1), so if - // allocate() returned non-null, the queue is guaranteed to have room. + // Push always succeeds: pool is sized to queue capacity (SIZE-1), so if + // allocate() returned non-null, the queue cannot be full. instance->mqtt_event_queue_.push(event); // Wake main loop immediately to process MQTT event instead of waiting for select() timeout diff --git a/esphome/components/mqtt/mqtt_backend_esp32.h b/esphome/components/mqtt/mqtt_backend_esp32.h index fb6d380fbd..58d1b29b32 100644 --- a/esphome/components/mqtt/mqtt_backend_esp32.h +++ b/esphome/components/mqtt/mqtt_backend_esp32.h @@ -258,7 +258,8 @@ class MQTTBackendESP32 final : public MQTTBackend { bool skip_cert_cn_check_{false}; #if defined(USE_MQTT_IDF_ENQUEUE) static void esphome_mqtt_task(void *params); - EventPool mqtt_outbound_pool_; + // Pool sized to queue capacity (SIZE-1) — see mqtt_event_pool_ comment. + EventPool mqtt_outbound_pool_; NotifyingLockFreeQueue mqtt_queue_; TaskHandle_t task_handle_{nullptr}; bool enqueue_(MqttQueueTypeT type, const char *topic, int qos = 0, bool retain = false, const char *payload = NULL, @@ -277,8 +278,8 @@ class MQTTBackendESP32 final : public MQTTBackend { // buffer that holds N-1 elements (one slot distinguishes full from empty). // This guarantees allocate() returns nullptr before push() can fail, which: // 1. Prevents leaking a pool slot (the Nth allocate succeeds but push fails) - // 2. Ensures only the main loop ever calls release(), preserving the SPSC - // contract on the pool's internal free list + // 2. Avoids needing release() on the producer path after a failed push(), + // preserving the SPSC contract on the pool's internal free list EventPool mqtt_event_pool_; LockFreeQueue mqtt_event_queue_;