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