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