xref: /third_party/node/src/cleanup_queue.h (revision 1cb0ef41)
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