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