1#ifndef SRC_CLEANUP_QUEUE_H_ 2#define SRC_CLEANUP_QUEUE_H_ 3 4#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6#include <cstddef> 7#include <cstdint> 8#include <unordered_set> 9#include <vector> 10 11#include "memory_tracker.h" 12 13namespace node { 14 15class BaseObject; 16 17class CleanupQueue : public MemoryRetainer { 18 public: 19 typedef void (*Callback)(void*); 20 21 CleanupQueue() {} 22 23 // Not copyable. 24 CleanupQueue(const CleanupQueue&) = delete; 25 26 SET_MEMORY_INFO_NAME(CleanupQueue) 27 inline void MemoryInfo(node::MemoryTracker* tracker) const override; 28 inline size_t SelfSize() const override; 29 30 inline bool empty() const; 31 32 inline void Add(Callback cb, void* arg); 33 inline void Remove(Callback cb, void* arg); 34 void Drain(); 35 36 template <typename T> 37 inline void ForEachBaseObject(T&& iterator) const; 38 39 private: 40 class CleanupHookCallback { 41 public: 42 CleanupHookCallback(Callback fn, 43 void* arg, 44 uint64_t insertion_order_counter) 45 : fn_(fn), 46 arg_(arg), 47 insertion_order_counter_(insertion_order_counter) {} 48 49 // Only hashes `arg_`, since that is usually enough to identify the hook. 50 struct Hash { 51 size_t operator()(const CleanupHookCallback& cb) const; 52 }; 53 54 // Compares by `fn_` and `arg_` being equal. 55 struct Equal { 56 bool operator()(const CleanupHookCallback& a, 57 const CleanupHookCallback& b) const; 58 }; 59 60 private: 61 friend class CleanupQueue; 62 Callback fn_; 63 void* arg_; 64 65 // We keep track of the insertion order for these objects, so that we can 66 // call the callbacks in reverse order when we are cleaning up. 67 uint64_t insertion_order_counter_; 68 }; 69 70 std::vector<CleanupHookCallback> GetOrdered() const; 71 inline BaseObject* GetBaseObject(const CleanupHookCallback& callback) const; 72 73 // Use an unordered_set, so that we have efficient insertion and removal. 74 std::unordered_set<CleanupHookCallback, 75 CleanupHookCallback::Hash, 76 CleanupHookCallback::Equal> 77 cleanup_hooks_; 78 uint64_t cleanup_hook_counter_ = 0; 79}; 80 81} // namespace node 82 83#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 84 85#endif // SRC_CLEANUP_QUEUE_H_ 86