mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 14:46:40 +00:00
Optimize OTA loop to avoid unnecessary stack allocations (#9129)
This commit is contained in:
parent
8ba22183b9
commit
40a5638005
@ -26,19 +26,19 @@ void ESPHomeOTAComponent::setup() {
|
|||||||
ota::register_ota_platform(this);
|
ota::register_ota_platform(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
server_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
this->server_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
||||||
if (server_ == nullptr) {
|
if (this->server_ == nullptr) {
|
||||||
ESP_LOGW(TAG, "Could not create socket");
|
ESP_LOGW(TAG, "Could not create socket");
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int enable = 1;
|
int enable = 1;
|
||||||
int err = server_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
int err = this->server_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err);
|
ESP_LOGW(TAG, "Socket unable to set reuseaddr: errno %d", err);
|
||||||
// we can still continue
|
// we can still continue
|
||||||
}
|
}
|
||||||
err = server_->setblocking(false);
|
err = this->server_->setblocking(false);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err);
|
ESP_LOGW(TAG, "Socket unable to set nonblocking mode: errno %d", err);
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
@ -54,14 +54,14 @@ void ESPHomeOTAComponent::setup() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = server_->bind((struct sockaddr *) &server, sizeof(server));
|
err = this->server_->bind((struct sockaddr *) &server, sizeof(server));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
|
ESP_LOGW(TAG, "Socket unable to bind: errno %d", errno);
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = server_->listen(4);
|
err = this->server_->listen(4);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ESP_LOGW(TAG, "Socket unable to listen: errno %d", errno);
|
ESP_LOGW(TAG, "Socket unable to listen: errno %d", errno);
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
@ -82,7 +82,14 @@ void ESPHomeOTAComponent::dump_config() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPHomeOTAComponent::loop() { this->handle_(); }
|
void ESPHomeOTAComponent::loop() {
|
||||||
|
// Skip handle_() call if no client connected and no incoming connections
|
||||||
|
// This optimization reduces idle loop overhead when OTA is not active
|
||||||
|
// Note: No need to check server_ for null as the component is marked failed in setup() if server_ creation fails
|
||||||
|
if (this->client_ != nullptr || this->server_->ready()) {
|
||||||
|
this->handle_();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const uint8_t FEATURE_SUPPORTS_COMPRESSION = 0x01;
|
static const uint8_t FEATURE_SUPPORTS_COMPRESSION = 0x01;
|
||||||
|
|
||||||
@ -101,23 +108,21 @@ void ESPHomeOTAComponent::handle_() {
|
|||||||
size_t size_acknowledged = 0;
|
size_t size_acknowledged = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (client_ == nullptr) {
|
if (this->client_ == nullptr) {
|
||||||
// Check if the server socket is ready before accepting
|
// We already checked server_->ready() in loop(), so we can accept directly
|
||||||
if (this->server_->ready()) {
|
struct sockaddr_storage source_addr;
|
||||||
struct sockaddr_storage source_addr;
|
socklen_t addr_len = sizeof(source_addr);
|
||||||
socklen_t addr_len = sizeof(source_addr);
|
this->client_ = this->server_->accept((struct sockaddr *) &source_addr, &addr_len);
|
||||||
client_ = server_->accept((struct sockaddr *) &source_addr, &addr_len);
|
if (this->client_ == nullptr)
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
if (client_ == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int enable = 1;
|
int enable = 1;
|
||||||
int err = client_->setsockopt(IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(int));
|
int err = this->client_->setsockopt(IPPROTO_TCP, TCP_NODELAY, &enable, sizeof(int));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
ESP_LOGW(TAG, "Socket could not enable TCP nodelay, errno %d", errno);
|
ESP_LOGW(TAG, "Socket could not enable TCP nodelay, errno %d", errno);
|
||||||
client_->close();
|
this->client_->close();
|
||||||
client_ = nullptr;
|
this->client_ = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user