mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
[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:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user