xref: /third_party/node/src/cleanup_queue.cc (revision 1cb0ef41)
1#include "cleanup_queue.h"  // NOLINT(build/include_inline)
2#include <algorithm>
3#include <vector>
4#include "cleanup_queue-inl.h"
5
6namespace node {
7
8std::vector<CleanupQueue::CleanupHookCallback> CleanupQueue::GetOrdered()
9    const {
10  // Copy into a vector, since we can't sort an unordered_set in-place.
11  std::vector<CleanupHookCallback> callbacks(cleanup_hooks_.begin(),
12                                             cleanup_hooks_.end());
13  // We can't erase the copied elements from `cleanup_hooks_` yet, because we
14  // need to be able to check whether they were un-scheduled by another hook.
15
16  std::sort(callbacks.begin(),
17            callbacks.end(),
18            [](const CleanupHookCallback& a, const CleanupHookCallback& b) {
19              // Sort in descending order so that the most recently inserted
20              // callbacks are run first.
21              return a.insertion_order_counter_ > b.insertion_order_counter_;
22            });
23
24  return callbacks;
25}
26
27void CleanupQueue::Drain() {
28  std::vector<CleanupHookCallback> callbacks = GetOrdered();
29
30  for (const CleanupHookCallback& cb : callbacks) {
31    if (cleanup_hooks_.count(cb) == 0) {
32      // This hook was removed from the `cleanup_hooks_` set during another
33      // hook that was run earlier. Nothing to do here.
34      continue;
35    }
36
37    cb.fn_(cb.arg_);
38    cleanup_hooks_.erase(cb);
39  }
40}
41
42size_t CleanupQueue::CleanupHookCallback::Hash::operator()(
43    const CleanupHookCallback& cb) const {
44  return std::hash<void*>()(cb.arg_);
45}
46
47bool CleanupQueue::CleanupHookCallback::Equal::operator()(
48    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
49  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
50}
51
52}  // namespace node
53