#include "cleanup_queue.h" // NOLINT(build/include_inline) #include #include #include "cleanup_queue-inl.h" namespace node { void CleanupQueue::Drain() { // Copy into a vector, since we can't sort an unordered_set in-place. 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_; }); for (const CleanupHookCallback& cb : callbacks) { if (cleanup_hooks_.count(cb) == 0) { // This hook was removed from the `cleanup_hooks_` set during another // hook that was run earlier. Nothing to do here. continue; } cb.fn_(cb.arg_); cleanup_hooks_.erase(cb); } } size_t CleanupQueue::CleanupHookCallback::Hash::operator()( const CleanupHookCallback& cb) const { return std::hash()(cb.arg_); } bool CleanupQueue::CleanupHookCallback::Equal::operator()( const CleanupHookCallback& a, const CleanupHookCallback& b) const { return a.fn_ == b.fn_ && a.arg_ == b.arg_; } } // namespace node