• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
13 namespace node {
14 
15 class BaseObject;
16 
17 class CleanupQueue : public MemoryRetainer {
18  public:
19   typedef void (*Callback)(void*);
20 
CleanupQueue()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:
CleanupHookCallback(Callback fn,void * arg,uint64_t insertion_order_counter)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