diff --git a/src/env.cc b/src/env.cc index 94fe595ac596ca..8e09b7333662f2 100644 --- a/src/env.cc +++ b/src/env.cc @@ -410,7 +410,7 @@ void Environment::RegisterHandleCleanups() { } void Environment::CleanupHandles() { - for (ReqWrap* request : req_wrap_queue_) + for (ReqWrapBase* request : req_wrap_queue_) request->Cancel(); for (HandleWrap* handle : handle_wrap_queue_) diff --git a/src/env.h b/src/env.h index 5cf2ee2c8b493e..8354e7be8ee1f4 100644 --- a/src/env.h +++ b/src/env.h @@ -860,8 +860,7 @@ class Environment { #endif typedef ListHead HandleWrapQueue; - typedef ListHead, &ReqWrap::req_wrap_queue_> - ReqWrapQueue; + typedef ListHead ReqWrapQueue; inline HandleWrapQueue* handle_wrap_queue() { return &handle_wrap_queue_; } inline ReqWrapQueue* req_wrap_queue() { return &req_wrap_queue_; } diff --git a/src/node_postmortem_metadata.cc b/src/node_postmortem_metadata.cc index 527bfb623e65de..05800f79b09ecc 100644 --- a/src/node_postmortem_metadata.cc +++ b/src/node_postmortem_metadata.cc @@ -28,15 +28,14 @@ V(Environment_HandleWrapQueue, head_, ListNode_HandleWrap, \ Environment::HandleWrapQueue::head_) \ V(ListNode_HandleWrap, next_, uintptr_t, ListNode::next_) \ - V(ReqWrap, req_wrap_queue_, ListNode_ReqWrapQueue, \ - ReqWrap::req_wrap_queue_) \ V(Environment_ReqWrapQueue, head_, ListNode_ReqWrapQueue, \ Environment::ReqWrapQueue::head_) \ - V(ListNode_ReqWrap, next_, uintptr_t, ListNode>::next_) + V(ListNode_ReqWrap, next_, uintptr_t, ListNode::next_) extern "C" { int nodedbg_const_ContextEmbedderIndex__kEnvironment__int; uintptr_t nodedbg_offset_ExternalString__data__uintptr_t; +uintptr_t nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue; #define V(Class, Member, Type, Accessor) \ NODE_EXTERN uintptr_t NODEDBG_OFFSET(Class, Member, Type); @@ -51,6 +50,9 @@ int GenDebugSymbols() { ContextEmbedderIndex::kEnvironment; nodedbg_offset_ExternalString__data__uintptr_t = NODE_OFF_EXTSTR_DATA; + nodedbg_offset_ReqWrap__req_wrap_queue___ListNode_ReqWrapQueue = + OffsetOf, ReqWrap>( + &ReqWrap::req_wrap_queue_); #define V(Class, Member, Type, Accessor) \ NODEDBG_OFFSET(Class, Member, Type) = OffsetOf(&Accessor); diff --git a/src/node_process_methods.cc b/src/node_process_methods.cc index be91a11f566baa..7c51e2026680f3 100644 --- a/src/node_process_methods.cc +++ b/src/node_process_methods.cc @@ -251,7 +251,8 @@ static void GetActiveRequests(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); std::vector> request_v; - for (auto w : *env->req_wrap_queue()) { + for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) { + AsyncWrap* w = req_wrap->GetAsyncWrap(); if (w->persistent().IsEmpty()) continue; request_v.push_back(w->GetOwner()); diff --git a/src/req_wrap-inl.h b/src/req_wrap-inl.h index 4f9da1c4f35d9e..5fb965414838bb 100644 --- a/src/req_wrap-inl.h +++ b/src/req_wrap-inl.h @@ -11,16 +11,16 @@ namespace node { +ReqWrapBase::ReqWrapBase(Environment* env) { + env->req_wrap_queue()->PushBack(this); +} + template ReqWrap::ReqWrap(Environment* env, v8::Local object, AsyncWrap::ProviderType provider) - : AsyncWrap(env, object, provider) { - - // FIXME(bnoordhuis) The fact that a reinterpret_cast is needed is - // arguably a good indicator that there should be more than one queue. - env->req_wrap_queue()->PushBack(reinterpret_cast*>(this)); - + : AsyncWrap(env, object, provider), + ReqWrapBase(env) { Reset(); } @@ -51,6 +51,11 @@ void ReqWrap::Cancel() { uv_cancel(reinterpret_cast(&req_)); } +template +AsyncWrap* ReqWrap::GetAsyncWrap() { + return this; +} + // Below is dark template magic designed to invoke libuv functions that // initialize uv_req_t instances in a unified fashion, to allow easier // tracking of active/inactive requests. diff --git a/src/req_wrap.h b/src/req_wrap.h index 8f8d0cf2885594..890eb6cb61848c 100644 --- a/src/req_wrap.h +++ b/src/req_wrap.h @@ -10,8 +10,24 @@ namespace node { +class ReqWrapBase { + public: + explicit inline ReqWrapBase(Environment* env); + + virtual ~ReqWrapBase() {} + + virtual void Cancel() = 0; + virtual AsyncWrap* GetAsyncWrap() = 0; + + private: + friend int GenDebugSymbols(); + friend class Environment; + + ListNode req_wrap_queue_; +}; + template -class ReqWrap : public AsyncWrap { +class ReqWrap : public AsyncWrap, public ReqWrapBase { public: inline ReqWrap(Environment* env, v8::Local object, @@ -23,7 +39,8 @@ class ReqWrap : public AsyncWrap { // Call this after a request has finished, if re-using this object is planned. inline void Reset(); T* req() { return &req_; } - inline void Cancel(); + inline void Cancel() final; + inline AsyncWrap* GetAsyncWrap() override; static ReqWrap* from_req(T* req); @@ -31,13 +48,10 @@ class ReqWrap : public AsyncWrap { inline int Dispatch(LibuvFunction fn, Args... args); private: - friend class Environment; friend int GenDebugSymbols(); template friend struct MakeLibuvRequestCallback; - ListNode req_wrap_queue_; - typedef void (*callback_t)(); callback_t original_callback_ = nullptr;