diff --git a/src/cleanup_queue-inl.h b/src/cleanup_queue-inl.h index ac86d06ada7c8b..b44f3d4b4c2b80 100644 --- a/src/cleanup_queue-inl.h +++ b/src/cleanup_queue-inl.h @@ -3,6 +3,8 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#include + #include "cleanup_queue.h" #include "util.h" @@ -29,6 +31,18 @@ void CleanupQueue::Remove(Callback cb, void* arg) { cleanup_hooks_.erase(search); } +constexpr std::strong_ordering CleanupQueue::CleanupHookCallback::operator<=>( + const CleanupHookCallback& other) const noexcept { + if (insertion_order_counter_ > other.insertion_order_counter_) { + return std::strong_ordering::greater; + } + + if (insertion_order_counter_ < other.insertion_order_counter_) { + return std::strong_ordering::less; + } + return std::strong_ordering::equivalent; +} + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/cleanup_queue.cc b/src/cleanup_queue.cc index 5923db6b89d4b4..9745258794bc49 100644 --- a/src/cleanup_queue.cc +++ b/src/cleanup_queue.cc @@ -1,5 +1,6 @@ #include "cleanup_queue.h" // NOLINT(build/include_inline) #include +#include > #include #include "cleanup_queue-inl.h" @@ -8,27 +9,20 @@ namespace node { 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()); + std::vector callbacks(cleanup_hooks_.begin(), cleanup_hooks_.end()); // We can't erase the copied elements from `cleanup_hooks_` yet, because we // need to be able to check whether they were un-scheduled by another hook. - std::sort(callbacks.begin(), - callbacks.end(), - [](const CleanupHookCallback& a, const CleanupHookCallback& b) { - // Sort in descending order so that the most recently inserted - // callbacks are run first. - return a.insertion_order_counter_ > b.insertion_order_counter_; - }); + // Sort in descending order so that the most recently inserted callbacks are + // run first. + std::ranges::sort(callbacks, std::greater()); return callbacks; } void CleanupQueue::Drain() { - std::vector callbacks = GetOrdered(); - - for (const CleanupHookCallback& cb : callbacks) { - if (cleanup_hooks_.count(cb) == 0) { + for (const CleanupHookCallback& cb : GetOrdered()) { + if (!cleanup_hooks_.contains(cb)) { // This hook was removed from the `cleanup_hooks_` set during another // hook that was run earlier. Nothing to do here. continue; diff --git a/src/cleanup_queue.h b/src/cleanup_queue.h index 7edc828eb654a8..c9ea8bb928bbed 100644 --- a/src/cleanup_queue.h +++ b/src/cleanup_queue.h @@ -3,6 +3,7 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS +#include #include #include #include @@ -41,6 +42,9 @@ class CleanupQueue : public MemoryRetainer { arg_(arg), insertion_order_counter_(insertion_order_counter) {} + constexpr std::strong_ordering operator<=>( + const CleanupHookCallback& other) const noexcept; + // Only hashes `arg_`, since that is usually enough to identify the hook. struct Hash { size_t operator()(const CleanupHookCallback& cb) const;