From efce5856d8598c8bb39c89b4583c7eced1c9b9b6 Mon Sep 17 00:00:00 2001 From: "Valentin V. Bartenev" Date: Wed, 6 May 2026 23:11:26 +0300 Subject: [PATCH] Web: refactor sendWhole loop to eliminate per-iteration branch The previous while loop computed a ternary `chunk_len` on every iteration to handle the final partial chunk as a special case, and called vTaskDelay(1) after every chunk including the last one, adding an unnecessary yield immediately before the terminating null chunk. Restructure the loop using the identity: last_size = ((len - 1) % kWebPageChunkSize) + 1 This gives `last_size` in [1, kWebPageChunkSize] for any non-zero `len`, so the final partial chunk is always non-empty and can be sent after the loop without a special case. The for loop then iterates only over full kWebPageChunkSize chunks, making every iteration identical and branch-free, and vTaskDelay(1) is called only after full chunks. Also add a `len == 0` guard to short-circuit immediately when there is nothing to send, and remove the best-effort terminator send on the error path since a failed send makes a follow-up send equally likely to fail. --- src/helpers/web/WebPanelServer.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/helpers/web/WebPanelServer.cpp b/src/helpers/web/WebPanelServer.cpp index 79a50541..c87f0842 100644 --- a/src/helpers/web/WebPanelServer.cpp +++ b/src/helpers/web/WebPanelServer.cpp @@ -68,20 +68,25 @@ esp_err_t sendChunk(httpd_req_t* req, const char* text) { #define sendProgmem(req, mem) sendWhole(req, mem, sizeof(mem) - 1) esp_err_t sendWhole(httpd_req_t* req, const char* text, const size_t len) { - if (text == nullptr) { + if (text == nullptr || len == 0) { return httpd_resp_send_chunk(req, nullptr, 0); } - size_t offset = 0; - while (offset < len) { - const size_t chunk_len = ((len - offset) > kWebPageChunkSize) ? kWebPageChunkSize : (len - offset); - if (httpd_resp_send_chunk(req, &text[offset], chunk_len) != ESP_OK) { - httpd_resp_send_chunk(req, nullptr, 0); + const size_t last_size = ((len - 1) % kWebPageChunkSize) + 1; + const char* last = text + (len - last_size); + + for (const char* p = text; p < last; p += kWebPageChunkSize) { + if (httpd_resp_send_chunk(req, p, kWebPageChunkSize) != ESP_OK) { return ESP_FAIL; } - offset += chunk_len; + vTaskDelay(1); } + + if (httpd_resp_send_chunk(req, last, last_size) != ESP_OK) { + return ESP_FAIL; + } + return httpd_resp_send_chunk(req, nullptr, 0); }