From 16bcba31ed15594c8ff250153b34f34922334ad1 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 10 Aug 2026 15:41:34 -0500 Subject: [PATCH] Enter CONNECTING before the lock releases so an instant completion routes --- .../bluetooth_connection/bluetooth_connection_rp2.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/esphome/components/bluetooth_connection/bluetooth_connection_rp2.cpp b/esphome/components/bluetooth_connection/bluetooth_connection_rp2.cpp index 71be48ede4..9c9ad5827f 100644 --- a/esphome/components/bluetooth_connection/bluetooth_connection_rp2.cpp +++ b/esphome/components/bluetooth_connection/bluetooth_connection_rp2.cpp @@ -907,12 +907,16 @@ int RP2GattClient::try_gap_connect_() { status = gap_connect(this->peer_addr_, this->peer_addr_type_); if (status == 0) { connect_owner = this; + // Still under the lock: a synthesized failure completion can fire in + // the BTstack context the instant it releases, and completion routing + // requires CONNECTING — set after the fact, the event is discarded + // and the engine burns its whole budget waiting for it. + this->state_ = EngineState::CONNECTING; + this->connect_started_ = millis(); } } } if (status == 0) { - this->state_ = EngineState::CONNECTING; - this->connect_started_ = millis(); return 0; } if (status == ERROR_CODE_COMMAND_DISALLOWED) {