diff options
| author | 2023-06-17 17:56:07 +0100 | |
|---|---|---|
| committer | 2023-06-17 18:20:00 +0100 | |
| commit | 71ed446a7b7c56d3f9c767cc28fa500bb1a81d15 (patch) | |
| tree | 1ba64f9e00455cc3f79b7cb18e19fb9566fd0d71 /src | |
| parent | Make internal bug messages more consistent. (diff) | |
Clean up object culling and fix a rare crash.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cull.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
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 <typeinfo> #endif +#include <unordered_set> Cullable::Cullable() { @@ -77,39 +79,48 @@ void CullList::Apply() working.clear(); } - std::set<Cullable*> gone; - std::vector<Cullable*> queue; - queue.reserve(list.size() + 32); - for (auto* c : list) + std::unordered_set<Cullable*> 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(); } } |
