mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
Restore comments from original code to minimize diff
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user