@@ -370,7 +370,21 @@ void AsyncEventSource::_addClient(AsyncEventSourceClient *client) {
370370#ifdef ESP32
371371 std::lock_guard<std::recursive_mutex> lock (_client_queue_lock);
372372#endif
373- _clients.emplace_back (client);
373+
374+ // find first unique_ptr with nullptr and reuse it
375+ bool reused = false ;
376+ for (auto &c : _clients) {
377+ if (c.get () == nullptr ) {
378+ c.reset (client);
379+ reused = true ;
380+ break ;
381+ }
382+ }
383+
384+ if (!reused) {
385+ _clients.emplace_back (client);
386+ }
387+
374388 if (_connectcb) {
375389 _connectcb (client);
376390 }
@@ -387,7 +401,7 @@ void AsyncEventSource::_handleDisconnect(AsyncEventSourceClient *client) {
387401#endif
388402 for (auto i = _clients.begin (); i != _clients.end (); ++i) {
389403 if (i->get () == client) {
390- _clients. erase (i);
404+ i-> reset (); // reset the unique_ptr but do not remove the list entry yet to keep other iterators valid
391405 break ;
392406 }
393407 }
@@ -402,7 +416,7 @@ void AsyncEventSource::close() {
402416 std::lock_guard<std::recursive_mutex> lock (_client_queue_lock);
403417#endif
404418 for (const auto &c : _clients) {
405- if (c->connected ()) {
419+ if (c. get () != nullptr && c ->connected ()) {
406420 /* *
407421 * @brief: Fix self-deadlock by using recursive_mutex instead.
408422 * Due to c->close() shall call the callback function _onDisconnect()
@@ -413,6 +427,17 @@ void AsyncEventSource::close() {
413427 }
414428}
415429
430+ void AsyncEventSource::cleanup () {
431+ #ifdef ESP32
432+ std::lock_guard<std::recursive_mutex> lock (_client_queue_lock);
433+ #endif
434+
435+ // resize the list to remove unique_ptr with nullptr
436+ _clients.remove_if ([](const std::unique_ptr<AsyncEventSourceClient> &c) {
437+ return c.get () == nullptr ;
438+ });
439+ }
440+
416441// pmb fix
417442size_t AsyncEventSource::avgPacketsWaiting () const {
418443 size_t aql = 0 ;
@@ -421,7 +446,7 @@ size_t AsyncEventSource::avgPacketsWaiting() const {
421446 std::lock_guard<std::recursive_mutex> lock (_client_queue_lock);
422447#endif
423448 for (const auto &c : _clients) {
424- if (c->connected ()) {
449+ if (c. get () != nullptr && c ->connected ()) {
425450 aql += c->packetsWaiting ();
426451 ++nConnectedClients;
427452 }
@@ -437,7 +462,7 @@ AsyncEventSource::SendStatus AsyncEventSource::send(const char *message, const c
437462 size_t hits = 0 ;
438463 size_t miss = 0 ;
439464 for (const auto &c : _clients) {
440- if (c->connected ()) {
465+ if (c. get () != nullptr && c ->connected ()) {
441466 if (c->write (shared_msg)) {
442467 ++hits;
443468 } else {
@@ -454,7 +479,7 @@ size_t AsyncEventSource::count() const {
454479#endif
455480 size_t n_clients{0 };
456481 for (const auto &i : _clients) {
457- if (i->connected ()) {
482+ if (i. get () != nullptr && i ->connected ()) {
458483 ++n_clients;
459484 }
460485 }
@@ -476,7 +501,7 @@ void AsyncEventSource::_adjust_inflight_window() {
476501 if (clientCount) {
477502 size_t inflight = SSE_MAX_INFLIGH / clientCount;
478503 for (const auto &c : _clients) {
479- if (c->connected ()) {
504+ if (c. get () != nullptr && c ->connected ()) {
480505 c->set_max_inflight_bytes (inflight);
481506 }
482507 }
0 commit comments