From 71ed446a7b7c56d3f9c767cc28fa500bb1a81d15 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Sat, 17 Jun 2023 17:56:07 +0100 Subject: Clean up object culling and fix a rare crash. --- src/cull.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'src/cull.cpp') diff --git a/src/cull.cpp b/src/cull.cpp index beae5494b..4957773e2 100644 --- a/src/cull.cpp +++ b/src/cull.cpp @@ -24,9 +24,11 @@ #include "inspircd.h" + #ifdef INSPIRCD_ENABLE_RTTI # include #endif +#include Cullable::Cullable() { @@ -77,39 +79,48 @@ void CullList::Apply() working.clear(); } - std::set gone; - std::vector queue; - queue.reserve(list.size() + 32); - for (auto* c : list) + std::unordered_set culled; + culled.reserve(list.size() + 32); + + // IMPORTANT: we can't use a range-based for loop here as culling an object + // may invalidate the list iterators. + for (size_t idx = 0; idx < list.size(); ++idx) { - if (gone.insert(c).second) + auto* c = list[idx]; + if (culled.insert(c).second) { #ifdef INSPIRCD_ENABLE_RTTI - ServerInstance->Logs.Debug("CULLLIST", "Deleting {} @{}", typeid(*c).name(), + ServerInstance->Logs.Debug("CULLLIST", "Culling {} @{}", typeid(*c).name(), fmt::ptr(c)); #endif c->Cull(); - queue.push_back(c); } else { #ifdef INSPIRCD_ENABLE_RTTI - ServerInstance->Logs.Debug("CULLLIST", "WARNING: Object {} @{} culled twice!", + ServerInstance->Logs.Debug("CULLLIST", "BUG: {} @{} was added to the cull list twice!", typeid(*c).name(), fmt::ptr(c)); #else - ServerInstance->Logs.Debug("CULLLIST", "WARNING: Object @{} culled twice!", + ServerInstance->Logs.Debug("CULLLIST", "BUG: @{} was added to the cull list twice!", fmt::ptr(c)); #endif } } list.clear(); - for (auto* c : queue) + for (auto* c : culled) + { +#ifdef INSPIRCD_ENABLE_RTTI + ServerInstance->Logs.Debug("CULLLIST", "Deleting {} @{}", typeid(*c).name(), + fmt::ptr(c)); +#endif delete c; + } if (!list.empty()) { - ServerInstance->Logs.Debug("CULLLIST", "WARNING: %zu objects added to the cull list from a destructor", list.size()); + ServerInstance->Logs.Debug("CULLLIST", "BUG: {} objects were added to the cull list from a destructor", + list.size()); Apply(); } } -- cgit v1.3.1-10-gc9f91