[mdns] Drain deferred packets from the UdpContext queue instead of a counter

UdpContext::next() already says whether a packet is queued, so the
volatile counter (which clang-tidy also rejects for ++/--) is not needed
and the drain stays correct after close() released the context.
This commit is contained in:
J. Nick Koston
2026-09-05 21:56:39 +02:00
parent a121bf17f0
commit e626e955d0
2 changed files with 11 additions and 16 deletions
+1 -1
View File
@@ -192,7 +192,7 @@ async def to_code(config: ConfigType) -> None:
if CORE.using_arduino:
if CORE.is_esp8266:
cg.add_library("ESP8266mDNS", None)
# mdns_esp8266.cpp owns a guarded MDNSResponder instead of the library global
# No MDNS global in the build; mdns_esp8266.cpp owns a guarded MDNSResponder
cg.add_build_flag("-DNO_GLOBAL_MDNS")
elif CORE.is_rp2:
cg.add_library("LEAmDNS", None)
+10 -15
View File
@@ -13,10 +13,11 @@
namespace esphome::mdns {
// Main-loop calls into LEAmDNS (update(), close()) can yield inside UdpContext::sendTimeout();
// a packet arriving then re-enters LEAmDNS from lwIP on the same UdpContext and both sides free
// the same tx pbufs (#18760). Received packets are only counted during such a call and drained
// from the main loop afterwards.
// Main-loop calls into LEAmDNS that send (update() and close(); begin(), addService() and
// the scheduled restart never reach a send) can yield inside UdpContext::sendTimeout(); a
// packet arriving then re-enters LEAmDNS from lwIP on the same UdpContext and both sides
// free the same tx pbufs (#18760). Received packets stay queued during such a call and are
// processed from the main loop afterwards.
class GuardedMDNSResponder : public ::esp8266::MDNSImplementation::MDNSResponder {
public:
void update_guarded() { this->run_guarded_(&GuardedMDNSResponder::update); }
@@ -29,28 +30,22 @@ class GuardedMDNSResponder : public ::esp8266::MDNSImplementation::MDNSResponder
(this->*fn)();
return;
}
// Set every time: a restart replaces the context together with its stock handler.
// Runs from lwIP in the SYS context.
// Set every time: a restart replaces the context together with its stock handler
ctx->onRx([this]() {
if (this->in_loop_call_) {
this->pending_rx_++;
} else {
if (!this->in_loop_call_) {
this->_callProcess();
}
});
this->pending_rx_ = 0;
this->in_loop_call_ = true;
(this->*fn)();
// Still counting here, so packets arriving during a yield in the drain queue behind it
while (this->pending_rx_ > 0) {
this->pending_rx_--;
this->_process(false);
// close() releases the context; a yield in here queues further packets for this loop too
while (this->m_pUDPContext != nullptr && this->m_pUDPContext->next()) {
this->_parseMessage();
}
this->in_loop_call_ = false;
}
volatile bool in_loop_call_{false};
volatile uint8_t pending_rx_{0};
};
static GuardedMDNSResponder mdns_responder; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)