aboutsummaryrefslogtreecommitdiff
path: root/src/cull.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2023-06-17 17:56:07 +0100
committerGravatar Sadie Powell2023-06-17 18:20:00 +0100
commit71ed446a7b7c56d3f9c767cc28fa500bb1a81d15 (patch)
tree1ba64f9e00455cc3f79b7cb18e19fb9566fd0d71 /src/cull.cpp
parentMake internal bug messages more consistent. (diff)
Clean up object culling and fix a rare crash.
Diffstat (limited to 'src/cull.cpp')
-rw-r--r--src/cull.cpp33
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();
}
}