1 #ifndef SRC_REQ_WRAP_H_ 2 #define SRC_REQ_WRAP_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "async_wrap.h" 7 #include "util.h" 8 #include "v8.h" 9 10 namespace node { 11 12 class Environment; 13 14 class ReqWrapBase { 15 public: 16 explicit inline ReqWrapBase(Environment* env); 17 18 virtual ~ReqWrapBase() = default; 19 20 virtual void Cancel() = 0; 21 virtual AsyncWrap* GetAsyncWrap() = 0; 22 23 private: 24 friend int GenDebugSymbols(); 25 friend class Environment; 26 27 ListNode<ReqWrapBase> req_wrap_queue_; 28 }; 29 30 template <typename T> 31 class ReqWrap : public AsyncWrap, public ReqWrapBase { 32 public: 33 inline ReqWrap(Environment* env, 34 v8::Local<v8::Object> object, 35 AsyncWrap::ProviderType provider); 36 inline ~ReqWrap() override; 37 // Call this after the req has been dispatched, if that did not already 38 // happen by using Dispatch(). 39 inline void Dispatched(); 40 // Call this after a request has finished, if re-using this object is planned. 41 inline void Reset(); req()42 T* req() { return &req_; } 43 inline void Cancel() final; 44 inline AsyncWrap* GetAsyncWrap() override; 45 46 static ReqWrap* from_req(T* req); 47 48 template <typename LibuvFunction, typename... Args> 49 inline int Dispatch(LibuvFunction fn, Args... args); 50 51 private: 52 friend int GenDebugSymbols(); 53 54 // Adding `friend struct MakeLibuvRequestCallback` is not enough anymore 55 // for some reason. Consider this private. 56 public: 57 typedef void (*callback_t)(); 58 callback_t original_callback_ = nullptr; 59 60 protected: 61 // req_wrap_queue_ needs to be at a fixed offset from the start of the class 62 // because it is used by ContainerOf to calculate the address of the embedding 63 // ReqWrap. ContainerOf compiles down to simple, fixed pointer arithmetic. It 64 // is also used by src/node_postmortem_metadata.cc to calculate offsets and 65 // generate debug symbols for ReqWrap, which assumes that the position of 66 // members in memory are predictable. sizeof(req_) depends on the type of T, 67 // so req_wrap_queue_ would no longer be at a fixed offset if it came after 68 // req_. For more information please refer to 69 // `doc/contributing/node-postmortem-support.md` 70 T req_; 71 }; 72 73 } // namespace node 74 75 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 76 77 #endif // SRC_REQ_WRAP_H_ 78