diff options
-rw-r--r-- | src/async-wrap-inl.h | 3 | ||||
-rw-r--r-- | src/async-wrap.h | 3 | ||||
-rw-r--r-- | src/handle_wrap.cc | 5 | ||||
-rw-r--r-- | src/handle_wrap.h | 3 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 24 | ||||
-rw-r--r-- | src/pipe_wrap.h | 8 | ||||
-rw-r--r-- | src/stream_wrap.cc | 21 | ||||
-rw-r--r-- | src/stream_wrap.h | 3 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 24 | ||||
-rw-r--r-- | src/tcp_wrap.h | 5 | ||||
-rw-r--r-- | src/udp_wrap.cc | 20 | ||||
-rw-r--r-- | src/udp_wrap.h | 5 |
12 files changed, 89 insertions, 35 deletions
diff --git a/src/async-wrap-inl.h b/src/async-wrap-inl.h index 7a298a1497b..73a177872e9 100644 --- a/src/async-wrap-inl.h +++ b/src/async-wrap-inl.h @@ -35,7 +35,8 @@ namespace node { inline AsyncWrap::AsyncWrap(Environment* env, v8::Handle<v8::Object> object, - ProviderType provider) + ProviderType provider, + AsyncWrap* parent) : BaseObject(env, object), provider_type_(provider) { } diff --git a/src/async-wrap.h b/src/async-wrap.h index 5a2c35ac941..ea8dfd3f012 100644 --- a/src/async-wrap.h +++ b/src/async-wrap.h @@ -63,7 +63,8 @@ class AsyncWrap : public BaseObject { inline AsyncWrap(Environment* env, v8::Handle<v8::Object> object, - ProviderType provider); + ProviderType provider, + AsyncWrap* parent = nullptr); inline virtual ~AsyncWrap() override = default; diff --git a/src/handle_wrap.cc b/src/handle_wrap.cc index f4e34effc66..b42fa004460 100644 --- a/src/handle_wrap.cc +++ b/src/handle_wrap.cc @@ -83,8 +83,9 @@ void HandleWrap::Close(const FunctionCallbackInfo<Value>& args) { HandleWrap::HandleWrap(Environment* env, Handle<Object> object, uv_handle_t* handle, - AsyncWrap::ProviderType provider) - : AsyncWrap(env, object, provider), + AsyncWrap::ProviderType provider, + AsyncWrap* parent) + : AsyncWrap(env, object, provider, parent), flags_(0), handle__(handle) { handle__->data = this; diff --git a/src/handle_wrap.h b/src/handle_wrap.h index 13457e7cc53..8c5898e134a 100644 --- a/src/handle_wrap.h +++ b/src/handle_wrap.h @@ -67,7 +67,8 @@ class HandleWrap : public AsyncWrap { HandleWrap(Environment* env, v8::Handle<v8::Object> object, uv_handle_t* handle, - AsyncWrap::ProviderType provider); + AsyncWrap::ProviderType provider, + AsyncWrap* parent = nullptr); virtual ~HandleWrap() override; private: diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 512b438218e..b91ebe0e5ed 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -21,6 +21,7 @@ #include "pipe_wrap.h" +#include "async-wrap.h" #include "env.h" #include "env-inl.h" #include "handle_wrap.h" @@ -37,6 +38,7 @@ namespace node { using v8::Boolean; using v8::Context; using v8::EscapableHandleScope; +using v8::External; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -74,12 +76,13 @@ uv_pipe_t* PipeWrap::UVHandle() { } -Local<Object> PipeWrap::Instantiate(Environment* env) { +Local<Object> PipeWrap::Instantiate(Environment* env, AsyncWrap* parent) { EscapableHandleScope handle_scope(env->isolate()); CHECK_EQ(false, env->pipe_constructor_template().IsEmpty()); Local<Function> constructor = env->pipe_constructor_template()->GetFunction(); CHECK_EQ(false, constructor.IsEmpty()); - Local<Object> instance = constructor->NewInstance(); + Local<Value> ptr = External::New(env->isolate(), parent); + Local<Object> instance = constructor->NewInstance(1, &ptr); CHECK_EQ(false, instance.IsEmpty()); return handle_scope.Escape(instance); } @@ -147,15 +150,24 @@ void PipeWrap::New(const FunctionCallbackInfo<Value>& args) { // normal function. CHECK(args.IsConstructCall()); Environment* env = Environment::GetCurrent(args); - new PipeWrap(env, args.This(), args[0]->IsTrue()); + if (args[0]->IsExternal()) { + void* ptr = args[0].As<External>()->Value(); + new PipeWrap(env, args.This(), false, static_cast<AsyncWrap*>(ptr)); + } else { + new PipeWrap(env, args.This(), args[0]->IsTrue(), nullptr); + } } -PipeWrap::PipeWrap(Environment* env, Handle<Object> object, bool ipc) +PipeWrap::PipeWrap(Environment* env, + Handle<Object> object, + bool ipc, + AsyncWrap* parent) : StreamWrap(env, object, reinterpret_cast<uv_stream_t*>(&handle_), - AsyncWrap::PROVIDER_PIPEWRAP) { + AsyncWrap::PROVIDER_PIPEWRAP, + parent) { int r = uv_pipe_init(env->event_loop(), &handle_, ipc); CHECK_EQ(r, 0); // How do we proxy this error up to javascript? // Suggestion: uv_pipe_init() returns void. @@ -214,7 +226,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) { } // Instanciate the client javascript object and handle. - Local<Object> client_obj = Instantiate(env); + Local<Object> client_obj = Instantiate(env, pipe_wrap); // Unwrap the client javascript object. PipeWrap* wrap = Unwrap<PipeWrap>(client_obj); diff --git a/src/pipe_wrap.h b/src/pipe_wrap.h index 92492c42b73..959f28f4dca 100644 --- a/src/pipe_wrap.h +++ b/src/pipe_wrap.h @@ -22,6 +22,7 @@ #ifndef SRC_PIPE_WRAP_H_ #define SRC_PIPE_WRAP_H_ +#include "async-wrap.h" #include "env.h" #include "stream_wrap.h" @@ -31,13 +32,16 @@ class PipeWrap : public StreamWrap { public: uv_pipe_t* UVHandle(); - static v8::Local<v8::Object> Instantiate(Environment* env); + static v8::Local<v8::Object> Instantiate(Environment* env, AsyncWrap* parent); static void Initialize(v8::Handle<v8::Object> target, v8::Handle<v8::Value> unused, v8::Handle<v8::Context> context); private: - PipeWrap(Environment* env, v8::Handle<v8::Object> object, bool ipc); + PipeWrap(Environment* env, + v8::Handle<v8::Object> object, + bool ipc, + AsyncWrap* parent); static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void Bind(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 9d56793b1de..2d13ae0f888 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -81,8 +81,13 @@ void StreamWrap::Initialize(Handle<Object> target, StreamWrap::StreamWrap(Environment* env, Local<Object> object, uv_stream_t* stream, - AsyncWrap::ProviderType provider) - : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(stream), provider), + AsyncWrap::ProviderType provider, + AsyncWrap* parent) + : HandleWrap(env, + object, + reinterpret_cast<uv_handle_t*>(stream), + provider, + parent), stream_(stream), default_callbacks_(this), callbacks_(&default_callbacks_), @@ -140,12 +145,14 @@ void StreamWrap::OnAlloc(uv_handle_t* handle, template <class WrapType, class UVType> -static Local<Object> AcceptHandle(Environment* env, uv_stream_t* pipe) { +static Local<Object> AcceptHandle(Environment* env, + uv_stream_t* pipe, + AsyncWrap* parent) { EscapableHandleScope scope(env->isolate()); Local<Object> wrap_obj; UVType* handle; - wrap_obj = WrapType::Instantiate(env); + wrap_obj = WrapType::Instantiate(env, parent); if (wrap_obj.IsEmpty()) return Local<Object>(); @@ -751,11 +758,11 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle, Local<Object> pending_obj; if (pending == UV_TCP) { - pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(env, handle); + pending_obj = AcceptHandle<TCPWrap, uv_tcp_t>(env, handle, wrap()); } else if (pending == UV_NAMED_PIPE) { - pending_obj = AcceptHandle<PipeWrap, uv_pipe_t>(env, handle); + pending_obj = AcceptHandle<PipeWrap, uv_pipe_t>(env, handle, wrap()); } else if (pending == UV_UDP) { - pending_obj = AcceptHandle<UDPWrap, uv_udp_t>(env, handle); + pending_obj = AcceptHandle<UDPWrap, uv_udp_t>(env, handle, wrap()); } else { CHECK_EQ(pending, UV_UNKNOWN_HANDLE); } diff --git a/src/stream_wrap.h b/src/stream_wrap.h index 93c9f046e01..ded78eeecb2 100644 --- a/src/stream_wrap.h +++ b/src/stream_wrap.h @@ -177,7 +177,8 @@ class StreamWrap : public HandleWrap { StreamWrap(Environment* env, v8::Local<v8::Object> object, uv_stream_t* stream, - AsyncWrap::ProviderType provider); + AsyncWrap::ProviderType provider, + AsyncWrap* parent = nullptr); ~StreamWrap() { if (!callbacks_gc_ && callbacks_ != &default_callbacks_) { diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index 9c1aeee6490..3b280990436 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -39,6 +39,7 @@ namespace node { using v8::Boolean; using v8::Context; using v8::EscapableHandleScope; +using v8::External; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -70,12 +71,13 @@ static void NewTCPConnectWrap(const FunctionCallbackInfo<Value>& args) { } -Local<Object> TCPWrap::Instantiate(Environment* env) { +Local<Object> TCPWrap::Instantiate(Environment* env, AsyncWrap* parent) { EscapableHandleScope handle_scope(env->isolate()); CHECK_EQ(env->tcp_constructor_template().IsEmpty(), false); Local<Function> constructor = env->tcp_constructor_template()->GetFunction(); CHECK_EQ(constructor.IsEmpty(), false); - Local<Object> instance = constructor->NewInstance(); + Local<Value> ptr = External::New(env->isolate(), parent); + Local<Object> instance = constructor->NewInstance(1, &ptr); CHECK_EQ(instance.IsEmpty(), false); return handle_scope.Escape(instance); } @@ -166,16 +168,25 @@ void TCPWrap::New(const FunctionCallbackInfo<Value>& args) { // normal function. CHECK(args.IsConstructCall()); Environment* env = Environment::GetCurrent(args); - TCPWrap* wrap = new TCPWrap(env, args.This()); + TCPWrap* wrap; + if (args.Length() == 0) { + wrap = new TCPWrap(env, args.This(), nullptr); + } else if (args[0]->IsExternal()) { + void* ptr = args[0].As<External>()->Value(); + wrap = new TCPWrap(env, args.This(), static_cast<AsyncWrap*>(ptr)); + } else { + UNREACHABLE(); + } CHECK(wrap); } -TCPWrap::TCPWrap(Environment* env, Handle<Object> object) +TCPWrap::TCPWrap(Environment* env, Handle<Object> object, AsyncWrap* parent) : StreamWrap(env, object, reinterpret_cast<uv_stream_t*>(&handle_), - AsyncWrap::PROVIDER_TCPWRAP) { + AsyncWrap::PROVIDER_TCPWRAP, + parent) { int r = uv_tcp_init(env->event_loop(), &handle_); CHECK_EQ(r, 0); // How do we proxy this error up to javascript? // Suggestion: uv_tcp_init() returns void. @@ -325,7 +336,8 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) { if (status == 0) { // Instantiate the client javascript object and handle. - Local<Object> client_obj = Instantiate(env); + Local<Object> client_obj = + Instantiate(env, static_cast<AsyncWrap*>(tcp_wrap)); // Unwrap the client javascript object. TCPWrap* wrap = Unwrap<TCPWrap>(client_obj); diff --git a/src/tcp_wrap.h b/src/tcp_wrap.h index c9981f572db..c923b387f0e 100644 --- a/src/tcp_wrap.h +++ b/src/tcp_wrap.h @@ -22,6 +22,7 @@ #ifndef SRC_TCP_WRAP_H_ #define SRC_TCP_WRAP_H_ +#include "async-wrap.h" #include "env.h" #include "stream_wrap.h" @@ -29,7 +30,7 @@ namespace node { class TCPWrap : public StreamWrap { public: - static v8::Local<v8::Object> Instantiate(Environment* env); + static v8::Local<v8::Object> Instantiate(Environment* env, AsyncWrap* parent); static void Initialize(v8::Handle<v8::Object> target, v8::Handle<v8::Value> unused, v8::Handle<v8::Context> context); @@ -37,7 +38,7 @@ class TCPWrap : public StreamWrap { uv_tcp_t* UVHandle(); private: - TCPWrap(Environment* env, v8::Handle<v8::Object> object); + TCPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent); ~TCPWrap(); static void New(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 42b5f1f03a3..e58503b40ac 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -34,6 +34,8 @@ namespace node { using v8::Context; +using v8::EscapableHandleScope; +using v8::External; using v8::Function; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -78,7 +80,7 @@ static void NewSendWrap(const FunctionCallbackInfo<Value>& args) { } -UDPWrap::UDPWrap(Environment* env, Handle<Object> object) +UDPWrap::UDPWrap(Environment* env, Handle<Object> object, AsyncWrap* parent) : HandleWrap(env, object, reinterpret_cast<uv_handle_t*>(&handle_), @@ -140,7 +142,15 @@ void UDPWrap::Initialize(Handle<Object> target, void UDPWrap::New(const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); Environment* env = Environment::GetCurrent(args); - new UDPWrap(env, args.This()); + if (args.Length() == 0) { + new UDPWrap(env, args.This(), nullptr); + } else if (args[0]->IsExternal()) { + new UDPWrap(env, + args.This(), + static_cast<AsyncWrap*>(args[0].As<External>()->Value())); + } else { + UNREACHABLE(); + } } @@ -423,10 +433,12 @@ void UDPWrap::OnRecv(uv_udp_t* handle, } -Local<Object> UDPWrap::Instantiate(Environment* env) { +Local<Object> UDPWrap::Instantiate(Environment* env, AsyncWrap* parent) { // If this assert fires then Initialize hasn't been called yet. CHECK_EQ(env->udp_constructor_function().IsEmpty(), false); - return env->udp_constructor_function()->NewInstance(); + EscapableHandleScope scope(env->isolate()); + Local<Value> ptr = External::New(env->isolate(), parent); + return scope.Escape(env->udp_constructor_function()->NewInstance(1, &ptr)); } diff --git a/src/udp_wrap.h b/src/udp_wrap.h index fea298031ac..9e62d82c31f 100644 --- a/src/udp_wrap.h +++ b/src/udp_wrap.h @@ -22,6 +22,7 @@ #ifndef SRC_UDP_WRAP_H_ #define SRC_UDP_WRAP_H_ +#include "async-wrap.h" #include "env.h" #include "handle_wrap.h" #include "req_wrap.h" @@ -53,11 +54,11 @@ class UDPWrap: public HandleWrap { static void SetBroadcast(const v8::FunctionCallbackInfo<v8::Value>& args); static void SetTTL(const v8::FunctionCallbackInfo<v8::Value>& args); - static v8::Local<v8::Object> Instantiate(Environment* env); + static v8::Local<v8::Object> Instantiate(Environment* env, AsyncWrap* parent); uv_udp_t* UVHandle(); private: - UDPWrap(Environment* env, v8::Handle<v8::Object> object); + UDPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent); static void DoBind(const v8::FunctionCallbackInfo<v8::Value>& args, int family); |