Clarify rcvevent reads are main-loop-only due to socket ownership

This commit is contained in:
J. Nick Koston
2026-02-23 22:14:15 -06:00
parent 44462d8453
commit d1dffafc86
2 changed files with 5 additions and 5 deletions

View File

@@ -634,7 +634,8 @@ void Application::unregister_socket_fd(int fd) {
void Application::yield_with_select_(uint32_t delay_ms) {
// Delay while monitoring sockets. When delay_ms is 0, always yield() to ensure other tasks run.
#if defined(USE_SOCKET_SELECT_SUPPORT) && defined(USE_ESP32)
// ESP32 fast path: no fd_set needed — is_socket_ready_() reads rcvevent directly (~215 ns per socket)
// ESP32 fast path: reads rcvevent directly via lwip_socket_dbg_get_socket() (~215 ns per socket).
// Safe because this runs on the main loop which owns socket lifetime (create, read, close).
if (delay_ms == 0) [[unlikely]] {
yield();
return;

View File

@@ -511,13 +511,12 @@ class Application {
#ifdef USE_SOCKET_SELECT_SUPPORT
/// Fast path for Socket::ready() via friendship - skips negative fd check.
/// Safe because: fd was validated in register_socket_fd() at registration time,
/// and Socket::ready() only calls this when loop_monitored_ is true (registration succeeded).
/// Main loop only — on ESP32, reads rcvevent via lwip_socket_dbg_get_socket()
/// which has no refcount; safe only because the main loop owns socket lifetime
/// (creates, reads, and closes sockets on the same thread).
#ifdef USE_ESP32
/// ESP32: direct rcvevent read — always fresh, no fd_set snapshot needed (~215 ns)
bool is_socket_ready_(int fd) const { return esphome_lwip_socket_has_data(fd); }
#else
/// Other platforms: check fd_set populated by select()
bool is_socket_ready_(int fd) const { return FD_ISSET(fd, &this->read_fds_); }
#endif
#endif