mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 23:37:34 +00:00
[mqtt] Fix outbound EventPool/LockFreeQueue sizing off-by-one
Size the outbound pool to N-1 to match queue capacity, same as the inbound pool fix in the previous commit.
This commit is contained in:
@@ -198,8 +198,8 @@ void MQTTBackendESP32::mqtt_event_handler(void *handler_args, esp_event_base_t b
|
||||
return;
|
||||
}
|
||||
event->populate(*static_cast<esp_mqtt_event_t *>(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
|
||||
|
||||
@@ -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<struct QueueElement, MQTT_QUEUE_LENGTH> mqtt_outbound_pool_;
|
||||
// Pool sized to queue capacity (SIZE-1) — see mqtt_event_pool_ comment.
|
||||
EventPool<struct QueueElement, MQTT_QUEUE_LENGTH - 1> mqtt_outbound_pool_;
|
||||
NotifyingLockFreeQueue<struct QueueElement, MQTT_QUEUE_LENGTH> 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<Event, MQTT_EVENT_QUEUE_LENGTH - 1> mqtt_event_pool_;
|
||||
LockFreeQueue<Event, MQTT_EVENT_QUEUE_LENGTH> mqtt_event_queue_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user