Restore comments from original code to minimize diff

This commit is contained in:
J. Nick Koston
2026-02-28 23:03:53 -10:00
parent 164001b50c
commit 8cedf8f882
2 changed files with 35 additions and 1 deletions
@@ -330,6 +330,11 @@ void LWIPRawImpl::init() {
}
void LWIPRawImpl::s_err_fn(void *arg, err_t err) {
// "If a connection is aborted because of an error, the application is alerted of this event by
// the err callback."
// pcb is already freed when this callback is called
// ERR_RST: connection was reset by remote host
// ERR_ABRT: aborted through tcp_abort or TCP timer
auto *arg_this = reinterpret_cast<LWIPRawImpl *>(arg);
ESP_LOGVV(TAG, "socket %p: err(err=%d)", arg_this, err);
arg_this->pcb_ = nullptr;
@@ -343,6 +348,8 @@ err_t LWIPRawImpl::s_recv_fn(void *arg, struct tcp_pcb *pcb, struct pbuf *pb, er
err_t LWIPRawImpl::recv_fn(struct pbuf *pb, err_t err) {
LWIP_LOG("recv(pb=%p err=%d)", pb, err);
if (err != 0) {
// "An error code if there has been an error receiving Only return ERR_ABRT if you have
// called tcp_abort from within the callback function!"
this->rx_closed_ = true;
return ERR_OK;
}
@@ -477,6 +484,10 @@ int LWIPRawImpl::internal_output_() {
LWIP_LOG("tcp_output(%p)", this->pcb_);
err_t err = tcp_output(this->pcb_);
if (err == ERR_ABRT) {
// sometimes lwip returns ERR_ABRT for no apparent reason
// the connection works fine afterwards, and back with ESPAsyncTCP we
// indirectly also ignored this error
// FIXME: figure out where this is returned and what it means in this context
LWIP_LOG(" -> err ERR_ABRT");
return 0;
}
@@ -604,6 +615,10 @@ int LWIPRawListenImpl::listen(int backlog) {
err_t LWIPRawListenImpl::accept_fn_(struct tcp_pcb *newpcb, err_t err) {
LWIP_LOG("accept(newpcb=%p err=%d)", newpcb, err);
if (err != ERR_OK || newpcb == nullptr) {
// "An error code if there has been an error accepting. Only return ERR_ABRT if you have
// called tcp_abort from within the callback function!"
// https://www.nongnu.org/lwip/2_1_x/tcp_8h.html#a00517abce6856d6c82f0efebdafb734d
// nothing to do here, we just don't push it to the queue
return ERR_OK;
}
// Check if we've reached the maximum accept queue size
+20 -1
View File
@@ -68,6 +68,7 @@ class LWIPRawImpl : public LWIPRawCommon {
void init();
// Non-listening sockets return error
std::unique_ptr<LWIPRawImpl> accept(struct sockaddr *, socklen_t *) {
errno = EINVAL;
return nullptr;
@@ -75,6 +76,8 @@ class LWIPRawImpl : public LWIPRawCommon {
std::unique_ptr<LWIPRawImpl> accept_loop_monitored(struct sockaddr *addr, socklen_t *addrlen) {
return this->accept(addr, addrlen);
}
// Regular sockets can't be converted to listening - this shouldn't happen
// as listen() should only be called on sockets created for listening
int listen(int) {
errno = EOPNOTSUPP;
return -1;
@@ -88,6 +91,7 @@ class LWIPRawImpl : public LWIPRawCommon {
ssize_t write(const void *buf, size_t len);
ssize_t writev(const struct iovec *iov, int iovcnt);
ssize_t sendto(const void *, size_t, int, const struct sockaddr *, socklen_t) {
// return ::sendto(fd_, buf, len, flags, to, tolen);
errno = ENOSYS;
return -1;
}
@@ -99,6 +103,7 @@ class LWIPRawImpl : public LWIPRawCommon {
return -1;
}
if (blocking) {
// blocking operation not supported
errno = EINVAL;
return -1;
}
@@ -171,9 +176,23 @@ class LWIPRawListenImpl : public LWIPRawCommon {
err_t accept_fn_(struct tcp_pcb *newpcb, err_t err);
static err_t s_accept_fn(void *arg, struct tcp_pcb *newpcb, err_t err);
// Accept queue - holds incoming connections briefly until the event loop calls accept()
// This is NOT a connection pool - just a temporary queue between LWIP callbacks and the main loop
// 3 slots is plenty since connections are pulled out quickly by the event loop
//
// Memory analysis: std::array<3> vs original std::queue implementation:
// - std::queue uses std::deque internally which on 32-bit systems needs:
// 24 bytes (deque object) + 32+ bytes (map array) + heap allocations
// Total: ~56+ bytes minimum, plus heap fragmentation
// - std::array<3>: 12 bytes fixed (3 pointers × 4 bytes)
// Saves ~44+ bytes RAM per listening socket + avoids ALL heap allocations
// Used on ESP8266 and RP2040 (platforms using LWIP_TCP implementation)
//
// By using a separate listening socket class, regular connected sockets save
// 16 bytes (12 bytes array + 1 byte count + 3 bytes padding) of memory overhead on 32-bit systems
static constexpr size_t MAX_ACCEPTED_SOCKETS = 3;
std::array<std::unique_ptr<LWIPRawImpl>, MAX_ACCEPTED_SOCKETS> accepted_sockets_;
uint8_t accepted_socket_count_ = 0;
uint8_t accepted_socket_count_ = 0; // Number of sockets currently in queue
};
} // namespace esphome::socket