diff --git a/src/cleanup_queue-inl.h b/src/cleanup_queue-inl.h index 5d9a56e6b07956..d1fbd8241d9919 100644 --- a/src/cleanup_queue-inl.h +++ b/src/cleanup_queue-inl.h @@ -39,7 +39,9 @@ void CleanupQueue::Remove(Callback cb, void* arg) { template void CleanupQueue::ForEachBaseObject(T&& iterator) const { - for (const auto& hook : cleanup_hooks_) { + std::vector callbacks = GetOrdered(); + + for (const auto& hook : callbacks) { BaseObject* obj = GetBaseObject(hook); if (obj != nullptr) iterator(obj); } diff --git a/src/cleanup_queue.cc b/src/cleanup_queue.cc index 6290b6796c5327..5923db6b89d4b4 100644 --- a/src/cleanup_queue.cc +++ b/src/cleanup_queue.cc @@ -5,7 +5,8 @@ namespace node { -void CleanupQueue::Drain() { +std::vector CleanupQueue::GetOrdered() + const { // Copy into a vector, since we can't sort an unordered_set in-place. std::vector callbacks(cleanup_hooks_.begin(), cleanup_hooks_.end()); @@ -20,6 +21,12 @@ void CleanupQueue::Drain() { return a.insertion_order_counter_ > b.insertion_order_counter_; }); + return callbacks; +} + +void CleanupQueue::Drain() { + std::vector callbacks = GetOrdered(); + for (const CleanupHookCallback& cb : callbacks) { if (cleanup_hooks_.count(cb) == 0) { // This hook was removed from the `cleanup_hooks_` set during another diff --git a/src/cleanup_queue.h b/src/cleanup_queue.h index 64e04e1856a197..2ca333aca855ff 100644 --- a/src/cleanup_queue.h +++ b/src/cleanup_queue.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "memory_tracker.h" @@ -66,6 +67,7 @@ class CleanupQueue : public MemoryRetainer { uint64_t insertion_order_counter_; }; + std::vector GetOrdered() const; inline BaseObject* GetBaseObject(const CleanupHookCallback& callback) const; // Use an unordered_set, so that we have efficient insertion and removal.