/src/node/src/callback_queue.h
Line | Count | Source |
1 | | #ifndef SRC_CALLBACK_QUEUE_H_ |
2 | | #define SRC_CALLBACK_QUEUE_H_ |
3 | | |
4 | | #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
5 | | |
6 | | #include <atomic> |
7 | | #include <memory> |
8 | | |
9 | | namespace node { |
10 | | |
11 | | namespace CallbackFlags { |
12 | | enum Flags { |
13 | | kUnrefed = 0, |
14 | | kRefed = 1, |
15 | | }; |
16 | | } |
17 | | |
18 | | // A queue of C++ functions that take Args... as arguments and return R |
19 | | // (this is similar to the signature of std::function). |
20 | | // New entries are added using `CreateCallback()`/`Push()`, and removed using |
21 | | // `Shift()`. |
22 | | // The `refed` flag is left for easier use in situations in which some of these |
23 | | // should be run even if nothing else is keeping the event loop alive. |
24 | | template <typename R, typename... Args> |
25 | | class CallbackQueue { |
26 | | public: |
27 | | class Callback { |
28 | | public: |
29 | | explicit inline Callback(CallbackFlags::Flags flags); |
30 | | |
31 | 81.1k | virtual ~Callback() = default; |
32 | | virtual R Call(Args... args) = 0; |
33 | | |
34 | | inline CallbackFlags::Flags flags() const; |
35 | | |
36 | | private: |
37 | | inline std::unique_ptr<Callback> get_next(); |
38 | | inline void set_next(std::unique_ptr<Callback> next); |
39 | | |
40 | | CallbackFlags::Flags flags_; |
41 | | std::unique_ptr<Callback> next_; |
42 | | |
43 | | friend class CallbackQueue; |
44 | | }; |
45 | | |
46 | | template <typename Fn> |
47 | | inline std::unique_ptr<Callback> CreateCallback( |
48 | | Fn&& fn, CallbackFlags::Flags); |
49 | | |
50 | | inline std::unique_ptr<Callback> Shift(); |
51 | | inline void Push(std::unique_ptr<Callback> cb); |
52 | | // ConcatMove adds elements from 'other' to the end of this list, and clears |
53 | | // 'other' afterwards. |
54 | | inline void ConcatMove(CallbackQueue&& other); |
55 | | |
56 | | // size() is atomic and may be called from any thread. |
57 | | inline size_t size() const; |
58 | | |
59 | | private: |
60 | | template <typename Fn> |
61 | | class CallbackImpl final : public Callback { |
62 | | public: |
63 | | CallbackImpl(Fn&& callback, CallbackFlags::Flags flags); |
64 | | R Call(Args... args) override; |
65 | | |
66 | | private: |
67 | | Fn callback_; |
68 | | }; |
69 | | |
70 | | std::atomic<size_t> size_ {0}; |
71 | | std::unique_ptr<Callback> head_; |
72 | | Callback* tail_ = nullptr; |
73 | | }; |
74 | | |
75 | | } // namespace node |
76 | | |
77 | | #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS |
78 | | |
79 | | #endif // SRC_CALLBACK_QUEUE_H_ |