save copy on each loop if no reads (common case)

This commit is contained in:
J. Nick Koston
2025-05-27 13:19:45 -05:00
parent c2c1b88408
commit 4089a9fc9e
2 changed files with 19 additions and 4 deletions

View File

@@ -142,10 +142,18 @@ void Application::loop() {
}
}
this->socket_fds_changed_ = false;
// When socket list changes, we need to copy the new base_read_fds_
this->read_fds_is_cleared_ = false;
}
// Copy base fd_set before each select
this->read_fds_ = this->base_read_fds_;
// Copy base fd_set only if necessary
// If read_fds_ is already cleared (all zeros), we can skip the copy
// We only need to copy if:
// 1. Socket list changed (handled above)
// 2. read_fds_ contains set bits from previous select
if (!this->read_fds_is_cleared_) {
this->read_fds_ = this->base_read_fds_;
}
// Convert delay_time (milliseconds) to timeval
struct timeval tv;
@@ -174,11 +182,17 @@ void Application::loop() {
ESP_LOGW(TAG, "select() failed with errno %d", errno);
delay(delay_time);
}
// Error case - assume we need to copy next time
this->read_fds_is_cleared_ = false;
} else if (ret > 0) {
ESP_LOGVV(TAG, "select() woke early: %d socket(s) ready (saved up to %ums)", ret, delay_time);
// Some fds were ready - read_fds_ has set bits, we'll need to copy next time
this->read_fds_is_cleared_ = false;
} else {
// ret == 0: timeout occurred (normal)
ESP_LOGVV(TAG, "select() timeout after %ums (no sockets ready)", delay_time);
// Timeout clears all bits in read_fds_ - we can skip the copy next time
this->read_fds_is_cleared_ = true;
}
} else {
// No sockets registered, use regular delay

View File

@@ -586,8 +586,9 @@ class Application {
bool socket_fds_changed_{false}; // Flag to rebuild base_read_fds_ when socket_fds_ changes
int max_fd_{-1}; // Highest file descriptor number for select()
#if defined(FD_SETSIZE) && !defined(USE_SOCKET_IMPL_LWIP_TCP)
fd_set base_read_fds_{}; // Cached fd_set rebuilt only when socket_fds_ changes
fd_set read_fds_{}; // Working fd_set for select(), copied from base_read_fds_
fd_set base_read_fds_{}; // Cached fd_set rebuilt only when socket_fds_ changes
fd_set read_fds_{}; // Working fd_set for select(), copied from base_read_fds_
bool read_fds_is_cleared_{false}; // True when read_fds_ is already cleared (all zeros)
#endif
};