[socket] Cache lwip_sock pointers and inline ready() chain (#14408)

This commit is contained in:
J. Nick Koston
2026-03-03 07:03:02 -10:00
committed by GitHub
parent b6f0bb9b6b
commit d53ff7892a
10 changed files with 190 additions and 89 deletions
+17 -16
View File
@@ -11,11 +11,15 @@ namespace esphome::socket {
BSDSocketImpl::BSDSocketImpl(int fd, bool monitor_loop) {
this->fd_ = fd;
// Register new socket with the application for select() if monitoring requested
if (monitor_loop && this->fd_ >= 0) {
// Only set loop_monitored_ to true if registration succeeds
this->loop_monitored_ = App.register_socket_fd(this->fd_);
}
if (!monitor_loop || this->fd_ < 0)
return;
#ifdef USE_LWIP_FAST_SELECT
// Cache lwip_sock pointer and register for monitoring (hooks callback internally)
this->cached_sock_ = esphome_lwip_get_sock(this->fd_);
this->loop_monitored_ = App.register_socket(this->cached_sock_);
#else
this->loop_monitored_ = App.register_socket_fd(this->fd_);
#endif
}
BSDSocketImpl::~BSDSocketImpl() {
@@ -26,10 +30,17 @@ BSDSocketImpl::~BSDSocketImpl() {
int BSDSocketImpl::close() {
if (!this->closed_) {
// Unregister from select() before closing if monitored
// Unregister before closing to avoid dangling pointer in monitored set
#ifdef USE_LWIP_FAST_SELECT
if (this->loop_monitored_) {
App.unregister_socket(this->cached_sock_);
this->cached_sock_ = nullptr;
}
#else
if (this->loop_monitored_) {
App.unregister_socket_fd(this->fd_);
}
#endif
int ret = ::close(this->fd_);
this->closed_ = true;
return ret;
@@ -48,8 +59,6 @@ int BSDSocketImpl::setblocking(bool blocking) {
return 0;
}
bool BSDSocketImpl::ready() const { return socket_ready_fd(this->fd_, this->loop_monitored_); }
size_t BSDSocketImpl::getpeername_to(std::span<char, SOCKADDR_STR_LEN> buf) {
struct sockaddr_storage storage;
socklen_t len = sizeof(storage);
@@ -86,14 +95,6 @@ std::unique_ptr<Socket> socket_loop_monitored(int domain, int type, int protocol
return create_socket(domain, type, protocol, true);
}
std::unique_ptr<ListenSocket> socket_listen(int domain, int type, int protocol) {
return create_socket(domain, type, protocol, false);
}
std::unique_ptr<ListenSocket> socket_listen_loop_monitored(int domain, int type, int protocol) {
return create_socket(domain, type, protocol, true);
}
} // namespace esphome::socket
#endif // USE_SOCKET_IMPL_BSD_SOCKETS