From a20b7540ce2860a32985f6e5c103c05905b8c941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Tue, 29 Dec 2020 12:56:39 -0500 Subject: [PATCH] Replace use of LinkedList with std::list for shared websocket buffers Based on commit bd4631bd5fa8989471684c7aab0228d4e05e9902 of dumbfixes branch of 0xFEEDC0DE64 fork of ESPAsyncWebServer. Step one of removal of homebrewed LinkedList in favor of standard C++ containers. Incidentally, this also fixes an analog of bug #837 where removal of elements while iterating would invalidate the iterator and lead to memory corruption. --- src/AsyncWebSocket.cpp | 27 ++++++++++++++------------- src/AsyncWebSocket.h | 4 +++- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/AsyncWebSocket.cpp b/src/AsyncWebSocket.cpp index 9ebab12..8905b8e 100644 --- a/src/AsyncWebSocket.cpp +++ b/src/AsyncWebSocket.cpp @@ -934,7 +934,6 @@ AsyncWebSocket::AsyncWebSocket(const String& url) ,_clients(LinkedList([](AsyncWebSocketClient *c){ delete c; })) ,_cNextId(1) ,_enabled(true) - ,_buffers(LinkedList([](AsyncWebSocketMessageBuffer *b){ delete b; })) { _eventHandler = NULL; } @@ -1300,22 +1299,23 @@ void AsyncWebSocket::handleRequest(AsyncWebServerRequest *request){ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(size_t size) { - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(size); - if (buffer) { + AsyncWebSocketMessageBuffer * buffer{}; + { AsyncWebLockGuard l(_lock); - _buffers.add(buffer); + _buffers.emplace_back(size); + buffer = &_buffers.back(); } return buffer; } AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t size) { - AsyncWebSocketMessageBuffer * buffer = new AsyncWebSocketMessageBuffer(data, size); + AsyncWebSocketMessageBuffer * buffer{}; - if (buffer) { + { AsyncWebLockGuard l(_lock); - // Serial.printf("Add to global buffers = %u\n", _buffers.length() + 1); - _buffers.add(buffer); + _buffers.emplace_back(data, size); + buffer = &_buffers.back(); } return buffer; @@ -1324,11 +1324,12 @@ AsyncWebSocketMessageBuffer * AsyncWebSocket::makeBuffer(uint8_t * data, size_t void AsyncWebSocket::_cleanBuffers() { AsyncWebLockGuard l(_lock); - for(AsyncWebSocketMessageBuffer * c: _buffers){ - if(c && c->canDelete()){ - // Serial.printf("Remove from global buffers = %u\n", _buffers.length() - 1); - _buffers.remove(c); - } + + for (auto iter = std::begin(_buffers); iter != std::end(_buffers);){ + if(iter->canDelete()){ + iter = _buffers.erase(iter); + } else + iter++; } } diff --git a/src/AsyncWebSocket.h b/src/AsyncWebSocket.h index 5ebf1cc..3b39d90 100644 --- a/src/AsyncWebSocket.h +++ b/src/AsyncWebSocket.h @@ -33,6 +33,8 @@ #include "AsyncWebSynchronization.h" +#include + #ifdef ESP8266 #include #ifdef CRYPTO_HASH_h // include Hash.h from espressif framework if the first include was from the crypto library @@ -337,7 +339,7 @@ class AsyncWebSocket: public AsyncWebHandler { // messagebuffer functions/objects. AsyncWebSocketMessageBuffer * makeBuffer(size_t size = 0); AsyncWebSocketMessageBuffer * makeBuffer(uint8_t * data, size_t size); - LinkedList _buffers; + std::list _buffers; void _cleanBuffers(); AsyncWebSocketClientLinkedList getClients() const;