aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-11-24 14:34:11 +0800
committerYuqian Yang <crupest@crupest.life>2025-11-24 14:34:11 +0800
commitcfe37d586d2513e0bfe9e4754a6c08c86773fb0e (patch)
treea1d12c83b056d7266078a1db6a4612458fc6f381
parentf8360f3242d99c2a560532ade1598205400c1292 (diff)
downloadcru-cfe37d586d2513e0bfe9e4754a6c08c86773fb0e.tar.gz
cru-cfe37d586d2513e0bfe9e4754a6c08c86773fb0e.tar.bz2
cru-cfe37d586d2513e0bfe9e4754a6c08c86773fb0e.zip
Fix delete later in delete later destructor.
-rw-r--r--include/cru/base/SelfResolvable.h8
-rw-r--r--src/platform/gui/UiApplication.cpp17
2 files changed, 12 insertions, 13 deletions
diff --git a/include/cru/base/SelfResolvable.h b/include/cru/base/SelfResolvable.h
index 308de486..6cf5117a 100644
--- a/include/cru/base/SelfResolvable.h
+++ b/include/cru/base/SelfResolvable.h
@@ -81,13 +81,7 @@ class ObjectResolver {
};
/**
- * @remarks
- * This class is not copyable and movable since subclass is polymorphic and
- * copying is then nonsense. However, you can even delete move capability in
- * subclass because it may also be nonsense for subclass. The move capability is
- * optional.
- *
- * Whether this class needs to be thread-safe still has to be considered.
+ * Currently the implementation is NOT thread-safe.
*/
template <typename T>
class SelfResolvable {
diff --git a/src/platform/gui/UiApplication.cpp b/src/platform/gui/UiApplication.cpp
index 56570125..de92e61a 100644
--- a/src/platform/gui/UiApplication.cpp
+++ b/src/platform/gui/UiApplication.cpp
@@ -8,14 +8,19 @@ namespace cru::platform::gui {
void DeleteLaterPool::Add(Object* object) { pool_.push_back(object); }
void DeleteLaterPool::Clean() {
- std::unordered_set<Object*> deleted;
- for (auto object : pool_) {
- if (!deleted.contains(object)) {
- deleted.insert(object);
- delete object;
+ // Destructors of objects might add more objects to delete later. So the safe
+ // implementation is to copy current pool to avoid modification during
+ // iteration.
+ while (!pool_.empty()) {
+ std::vector<Object*> copy = std::move(pool_);
+ std::unordered_set<Object*> deleted;
+ for (auto object : copy) {
+ if (!deleted.contains(object)) {
+ deleted.insert(object);
+ delete object;
+ }
}
}
- pool_.clear();
}
namespace {