• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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_
79