diff options
-rw-r--r-- | src/async-wrap.cc | 8 | ||||
-rw-r--r-- | src/async-wrap.h | 2 | ||||
-rw-r--r-- | src/cares_wrap.cc | 15 | ||||
-rw-r--r-- | src/connect_wrap.cc | 5 | ||||
-rw-r--r-- | src/connect_wrap.h | 1 | ||||
-rw-r--r-- | src/fs_event_wrap.cc | 1 | ||||
-rw-r--r-- | src/js_stream.cc | 2 | ||||
-rw-r--r-- | src/node_crypto.cc | 3 | ||||
-rw-r--r-- | src/node_crypto.h | 1 | ||||
-rw-r--r-- | src/node_file.cc | 7 | ||||
-rw-r--r-- | src/node_http_parser.cc | 1 | ||||
-rw-r--r-- | src/node_stat_watcher.cc | 2 | ||||
-rw-r--r-- | src/node_zlib.cc | 2 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 4 | ||||
-rw-r--r-- | src/process_wrap.cc | 2 | ||||
-rw-r--r-- | src/req-wrap-inl.h | 1 | ||||
-rw-r--r-- | src/signal_wrap.cc | 1 | ||||
-rw-r--r-- | src/stream_base.h | 8 | ||||
-rw-r--r-- | src/stream_wrap.cc | 3 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 3 | ||||
-rw-r--r-- | src/timer_wrap.cc | 2 | ||||
-rw-r--r-- | src/tls_wrap.cc | 1 | ||||
-rw-r--r-- | src/tty_wrap.cc | 2 | ||||
-rw-r--r-- | src/udp_wrap.cc | 10 | ||||
-rw-r--r-- | test/parallel/test-async-wrap-getasyncid.js | 241 |
25 files changed, 326 insertions, 2 deletions
diff --git a/src/async-wrap.cc b/src/async-wrap.cc index 304e5d0c95..11ed67d242 100644 --- a/src/async-wrap.cc +++ b/src/async-wrap.cc @@ -180,6 +180,14 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) { } +void AsyncWrap::GetAsyncId(const FunctionCallbackInfo<Value>& args) { + AsyncWrap* wrap; + args.GetReturnValue().Set(-1); + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + args.GetReturnValue().Set(wrap->get_id()); +} + + void AsyncWrap::Initialize(Local<Object> target, Local<Value> unused, Local<Context> context) { diff --git a/src/async-wrap.h b/src/async-wrap.h index ecf8db9fc5..7ccae02cce 100644 --- a/src/async-wrap.h +++ b/src/async-wrap.h @@ -85,6 +85,8 @@ class AsyncWrap : public BaseObject { v8::Local<v8::Value> unused, v8::Local<v8::Context> context); + static void GetAsyncId(const v8::FunctionCallbackInfo<v8::Value>& args); + static void DestroyIdsCb(uv_idle_t* handle); inline ProviderType provider_type() const; diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 7a9102ff3d..15c261b6f1 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -104,6 +104,7 @@ inline const char* ToErrorCodeString(int status) { class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> { public: GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj); + ~GetAddrInfoReqWrap(); size_t self_size() const override { return sizeof(*this); } }; @@ -114,10 +115,15 @@ GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env, Wrap(req_wrap_obj, this); } +GetAddrInfoReqWrap::~GetAddrInfoReqWrap() { + ClearWrap(object()); +} + class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> { public: GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj); + ~GetNameInfoReqWrap(); size_t self_size() const override { return sizeof(*this); } }; @@ -128,6 +134,10 @@ GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env, Wrap(req_wrap_obj, this); } +GetNameInfoReqWrap::~GetNameInfoReqWrap() { + ClearWrap(object()); +} + int cmp_ares_tasks(const node_ares_task* a, const node_ares_task* b) { if (a->sock < b->sock) @@ -293,6 +303,7 @@ class QueryWrap : public AsyncWrap { : AsyncWrap(env, req_wrap_obj, AsyncWrap::PROVIDER_QUERYWRAP) { if (env->in_domain()) req_wrap_obj->Set(env->domain_string(), env->domain_array()->Get(0)); + Wrap(req_wrap_obj, this); } ~QueryWrap() override { @@ -1388,10 +1399,12 @@ void Initialize(Local<Object> target, auto is_construct_call_callback = [](const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); }; Local<FunctionTemplate> aiw = FunctionTemplate::New(env->isolate(), is_construct_call_callback); aiw->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(aiw, "getAsyncId", AsyncWrap::GetAsyncId); aiw->SetClassName( FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetAddrInfoReqWrap"), @@ -1400,6 +1413,7 @@ void Initialize(Local<Object> target, Local<FunctionTemplate> niw = FunctionTemplate::New(env->isolate(), is_construct_call_callback); niw->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(niw, "getAsyncId", AsyncWrap::GetAsyncId); niw->SetClassName( FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "GetNameInfoReqWrap"), @@ -1408,6 +1422,7 @@ void Initialize(Local<Object> target, Local<FunctionTemplate> qrw = FunctionTemplate::New(env->isolate(), is_construct_call_callback); qrw->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(qrw, "getAsyncId", AsyncWrap::GetAsyncId); qrw->SetClassName( FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "QueryReqWrap"), diff --git a/src/connect_wrap.cc b/src/connect_wrap.cc index df3f093e73..e373b5a36e 100644 --- a/src/connect_wrap.cc +++ b/src/connect_wrap.cc @@ -19,4 +19,9 @@ ConnectWrap::ConnectWrap(Environment* env, Wrap(req_wrap_obj, this); } + +ConnectWrap::~ConnectWrap() { + ClearWrap(object()); +} + } // namespace node diff --git a/src/connect_wrap.h b/src/connect_wrap.h index 28d4872d7e..7b16a54487 100644 --- a/src/connect_wrap.h +++ b/src/connect_wrap.h @@ -15,6 +15,7 @@ class ConnectWrap : public ReqWrap<uv_connect_t> { ConnectWrap(Environment* env, v8::Local<v8::Object> req_wrap_obj, AsyncWrap::ProviderType provider); + ~ConnectWrap(); size_t self_size() const override { return sizeof(*this); } }; diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index bc3b33027a..228c3a344e 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -94,6 +94,7 @@ void FSEventWrap::Initialize(Local<Object> target, t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(fsevent_string); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "start", Start); env->SetProtoMethod(t, "close", Close); diff --git a/src/js_stream.cc b/src/js_stream.cc index e51c4ae9b3..1d20e1c6d7 100644 --- a/src/js_stream.cc +++ b/src/js_stream.cc @@ -221,6 +221,8 @@ void JSStream::Initialize(Local<Object> target, t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "JSStream")); t->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(t, "doAlloc", DoAlloc); env->SetProtoMethod(t, "doRead", DoRead); env->SetProtoMethod(t, "doAfterWrite", DoAfterWrite); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 87e008acd9..dac4a2e76b 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2737,6 +2737,7 @@ void Connection::Initialize(Environment* env, Local<Object> target) { t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Connection")); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "encIn", Connection::EncIn); env->SetProtoMethod(t, "clearOut", Connection::ClearOut); env->SetProtoMethod(t, "clearIn", Connection::ClearIn); @@ -6258,12 +6259,14 @@ void InitCrypto(Local<Object> target, Local<FunctionTemplate> pb = FunctionTemplate::New(env->isolate()); pb->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PBKDF2")); + env->SetProtoMethod(pb, "getAsyncId", AsyncWrap::GetAsyncId); Local<ObjectTemplate> pbt = pb->InstanceTemplate(); pbt->SetInternalFieldCount(1); env->set_pbkdf2_constructor_template(pbt); Local<FunctionTemplate> rb = FunctionTemplate::New(env->isolate()); rb->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "RandomBytes")); + env->SetProtoMethod(rb, "getAsyncId", AsyncWrap::GetAsyncId); Local<ObjectTemplate> rbt = rb->InstanceTemplate(); rbt->SetInternalFieldCount(1); env->set_randombytes_constructor_template(rbt); diff --git a/src/node_crypto.h b/src/node_crypto.h index 90e268456a..ad1b493596 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -408,6 +408,7 @@ class Connection : public AsyncWrap, public SSLWrap<Connection> { bio_write_(nullptr), hello_offset_(0) { MakeWeak<Connection>(this); + Wrap(wrap, this); hello_parser_.Start(SSLWrap<Connection>::OnClientHello, OnClientHelloParseEnd, this); diff --git a/src/node_file.cc b/src/node_file.cc index 4a0b1527d6..7a3be9db54 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -110,7 +110,10 @@ class FSReqWrap: public ReqWrap<uv_fs_t> { Wrap(object(), this); } - ~FSReqWrap() { ReleaseEarly(); } + ~FSReqWrap() { + ReleaseEarly(); + ClearWrap(object()); + } void* operator new(size_t size) = delete; void* operator new(size_t size, char* storage) { return storage; } @@ -151,6 +154,7 @@ void FSReqWrap::Dispose() { void NewFSReqWrap(const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); } @@ -1474,6 +1478,7 @@ void InitFs(Local<Object> target, Local<FunctionTemplate> fst = FunctionTemplate::New(env->isolate(), NewFSReqWrap); fst->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(fst, "getAsyncId", AsyncWrap::GetAsyncId); fst->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "FSReqWrap"), fst->GetFunction()); diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index d504f42f35..531a83392c 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -785,6 +785,7 @@ void InitHttpParser(Local<Object> target, #undef V target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "methods"), methods); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "close", Parser::Close); env->SetProtoMethod(t, "execute", Parser::Execute); env->SetProtoMethod(t, "finish", Parser::Finish); diff --git a/src/node_stat_watcher.cc b/src/node_stat_watcher.cc index 9eeed77476..18bf2c5419 100644 --- a/src/node_stat_watcher.cc +++ b/src/node_stat_watcher.cc @@ -49,6 +49,7 @@ void StatWatcher::Initialize(Environment* env, Local<Object> target) { t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "StatWatcher")); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "start", StatWatcher::Start); env->SetProtoMethod(t, "stop", StatWatcher::Stop); @@ -66,6 +67,7 @@ StatWatcher::StatWatcher(Environment* env, Local<Object> wrap) : AsyncWrap(env, wrap, AsyncWrap::PROVIDER_STATWATCHER), watcher_(new uv_fs_poll_t) { MakeWeak<StatWatcher>(this); + Wrap(wrap, this); uv_fs_poll_init(env->event_loop(), watcher_); watcher_->data = static_cast<void*>(this); } diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 054023ca10..e4adda5202 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -88,6 +88,7 @@ class ZCtx : public AsyncWrap { refs_(0), gzip_id_bytes_read_(0) { MakeWeak<ZCtx>(this); + Wrap(wrap, this); } @@ -678,6 +679,7 @@ void InitZlib(Local<Object> target, z->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(z, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(z, "write", ZCtx::Write<true>); env->SetProtoMethod(z, "writeSync", ZCtx::Write<false>); env->SetProtoMethod(z, "init", ZCtx::Init); diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 132b2662f5..8c251f1f74 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -69,6 +69,8 @@ void PipeWrap::Initialize(Local<Object> target, t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Pipe")); t->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(t, "close", HandleWrap::Close); env->SetProtoMethod(t, "unref", HandleWrap::Unref); env->SetProtoMethod(t, "ref", HandleWrap::Ref); @@ -95,9 +97,11 @@ void PipeWrap::Initialize(Local<Object> target, // Create FunctionTemplate for PipeConnectWrap. auto constructor = [](const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); }; auto cwt = FunctionTemplate::New(env->isolate(), constructor); cwt->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(cwt, "getAsyncId", AsyncWrap::GetAsyncId); cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "PipeConnectWrap"), cwt->GetFunction()); diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 2780adad74..cae0788927 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -55,6 +55,8 @@ class ProcessWrap : public HandleWrap { constructor->InstanceTemplate()->SetInternalFieldCount(1); constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Process")); + env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(constructor, "close", HandleWrap::Close); env->SetProtoMethod(constructor, "spawn", Spawn); diff --git a/src/req-wrap-inl.h b/src/req-wrap-inl.h index 84af22023d..e21fb1bdad 100644 --- a/src/req-wrap-inl.h +++ b/src/req-wrap-inl.h @@ -30,7 +30,6 @@ template <typename T> ReqWrap<T>::~ReqWrap() { CHECK_EQ(req_.data, this); // Assert that someone has called Dispatched(). CHECK_EQ(false, persistent().IsEmpty()); - ClearWrap(object()); persistent().Reset(); } diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index 36b862ce82..ccd1b0ec41 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -51,6 +51,7 @@ class SignalWrap : public HandleWrap { constructor->InstanceTemplate()->SetInternalFieldCount(1); constructor->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "Signal")); + env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(constructor, "close", HandleWrap::Close); env->SetProtoMethod(constructor, "ref", HandleWrap::Ref); env->SetProtoMethod(constructor, "unref", HandleWrap::Unref); diff --git a/src/stream_base.h b/src/stream_base.h index e2ef8d8d39..581c5405aa 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -53,6 +53,10 @@ class ShutdownWrap : public ReqWrap<uv_shutdown_t>, Wrap(req_wrap_obj, this); } + ~ShutdownWrap() { + ClearWrap(object()); + } + static ShutdownWrap* from_req(uv_shutdown_t* req) { return ContainerOf(&ShutdownWrap::req_, req); } @@ -98,6 +102,10 @@ class WriteWrap: public ReqWrap<uv_write_t>, Wrap(obj, this); } + ~WriteWrap() { + ClearWrap(object()); + } + void* operator new(size_t size) = delete; void* operator new(size_t size, char* storage) { return storage; } diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 83c375b54b..065505af19 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -62,11 +62,13 @@ void StreamWrap::Initialize(Local<Object> target, auto is_construct_call_callback = [](const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); }; Local<FunctionTemplate> sw = FunctionTemplate::New(env->isolate(), is_construct_call_callback); sw->InstanceTemplate()->SetInternalFieldCount(1); sw->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap")); + env->SetProtoMethod(sw, "getAsyncId", AsyncWrap::GetAsyncId); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ShutdownWrap"), sw->GetFunction()); @@ -74,6 +76,7 @@ void StreamWrap::Initialize(Local<Object> target, FunctionTemplate::New(env->isolate(), is_construct_call_callback); ww->InstanceTemplate()->SetInternalFieldCount(1); ww->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap")); + env->SetProtoMethod(ww, "getAsyncId", AsyncWrap::GetAsyncId); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "WriteWrap"), ww->GetFunction()); env->set_write_wrap_constructor_function(ww->GetFunction()); diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index f2525b1fb1..931b637751 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -84,6 +84,7 @@ void TCPWrap::Initialize(Local<Object> target, "onconnection"), Null(env->isolate())); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "close", HandleWrap::Close); @@ -116,9 +117,11 @@ void TCPWrap::Initialize(Local<Object> target, // Create FunctionTemplate for TCPConnectWrap. auto constructor = [](const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); }; auto cwt = FunctionTemplate::New(env->isolate(), constructor); cwt->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(cwt, "getAsyncId", AsyncWrap::GetAsyncId); cwt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "TCPConnectWrap"), cwt->GetFunction()); diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index 382bcaacb6..609d087e33 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -57,6 +57,8 @@ class TimerWrap : public HandleWrap { env->SetTemplateMethod(constructor, "now", Now); + env->SetProtoMethod(constructor, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(constructor, "close", HandleWrap::Close); env->SetProtoMethod(constructor, "ref", HandleWrap::Ref); env->SetProtoMethod(constructor, "unref", HandleWrap::Unref); diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 6f2d0e4c16..05349b2f55 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -939,6 +939,7 @@ void TLSWrap::Initialize(Local<Object> target, t->InstanceTemplate()->SetInternalFieldCount(1); t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap")); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); env->SetProtoMethod(t, "receive", Receive); env->SetProtoMethod(t, "start", Start); env->SetProtoMethod(t, "setVerifyMode", SetVerifyMode); diff --git a/src/tty_wrap.cc b/src/tty_wrap.cc index b6e3efcc10..f3f1edfe5d 100644 --- a/src/tty_wrap.cc +++ b/src/tty_wrap.cc @@ -53,6 +53,8 @@ void TTYWrap::Initialize(Local<Object> target, t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TTY")); t->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); + env->SetProtoMethod(t, "close", HandleWrap::Close); env->SetProtoMethod(t, "unref", HandleWrap::Unref); env->SetProtoMethod(t, "ref", HandleWrap::Ref); diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 4f5388080e..fe2b10661f 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -54,6 +54,7 @@ using v8::Value; class SendWrap : public ReqWrap<uv_udp_send_t> { public: SendWrap(Environment* env, Local<Object> req_wrap_obj, bool have_callback); + ~SendWrap(); inline bool have_callback() const; size_t msg_size; size_t self_size() const override { return sizeof(*this); } @@ -71,6 +72,11 @@ SendWrap::SendWrap(Environment* env, } +SendWrap::~SendWrap() { + ClearWrap(object()); +} + + inline bool SendWrap::have_callback() const { return have_callback_; } @@ -78,6 +84,7 @@ inline bool SendWrap::have_callback() const { static void NewSendWrap(const FunctionCallbackInfo<Value>& args) { CHECK(args.IsConstructCall()); + ClearWrap(args.This()); } @@ -129,6 +136,8 @@ void UDPWrap::Initialize(Local<Object> target, env->SetProtoMethod(t, "unref", HandleWrap::Unref); env->SetProtoMethod(t, "hasRef", HandleWrap::HasRef); + env->SetProtoMethod(t, "getAsyncId", AsyncWrap::GetAsyncId); + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "UDP"), t->GetFunction()); env->set_udp_constructor_function(t->GetFunction()); @@ -136,6 +145,7 @@ void UDPWrap::Initialize(Local<Object> target, Local<FunctionTemplate> swt = FunctionTemplate::New(env->isolate(), NewSendWrap); swt->InstanceTemplate()->SetInternalFieldCount(1); + env->SetProtoMethod(swt, "getAsyncId", AsyncWrap::GetAsyncId); swt->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap")); target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "SendWrap"), swt->GetFunction()); diff --git a/test/parallel/test-async-wrap-getasyncid.js b/test/parallel/test-async-wrap-getasyncid.js new file mode 100644 index 0000000000..5e2ce3a820 --- /dev/null +++ b/test/parallel/test-async-wrap-getasyncid.js @@ -0,0 +1,241 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const fs = require('fs'); +const net = require('net'); +const providers = Object.assign({}, process.binding('async_wrap').Providers); + +// Make sure that all Providers are tested. +{ + const hooks = require('async_hooks').createHook({ + init(id, type) { + if (type === 'NONE') + throw new Error('received a provider type of NONE'); + delete providers[type]; + }, + }).enable(); + process.on('beforeExit', common.mustCall(() => { + process.removeAllListeners('uncaughtException'); + hooks.disable(); + delete providers.NONE; // Should never be used. + const obj_keys = Object.keys(providers); + if (obj_keys.length > 0) + process._rawDebug(obj_keys); + assert.strictEqual(obj_keys.length, 0); + })); +} + +function testUninitialized(req, ctor_name) { + assert.strictEqual(typeof req.getAsyncId, 'function'); + assert.strictEqual(req.getAsyncId(), -1); + assert.strictEqual(req.constructor.name, ctor_name); +} + +function testInitialized(req, ctor_name) { + assert.strictEqual(typeof req.getAsyncId, 'function'); + assert(Number.isSafeInteger(req.getAsyncId())); + assert(req.getAsyncId() > 0); + assert.strictEqual(req.constructor.name, ctor_name); +} + + +{ + const cares = process.binding('cares_wrap'); + const dns = require('dns'); + + testUninitialized(new cares.GetAddrInfoReqWrap(), 'GetAddrInfoReqWrap'); + testUninitialized(new cares.GetNameInfoReqWrap(), 'GetNameInfoReqWrap'); + testUninitialized(new cares.QueryReqWrap(), 'QueryReqWrap'); + + testInitialized(dns.lookup('www.google.com', () => {}), 'GetAddrInfoReqWrap'); + testInitialized(dns.lookupService('::1', 22, () => {}), 'GetNameInfoReqWrap'); + testInitialized(dns.resolve6('::1', () => {}), 'QueryReqWrap'); +} + + +{ + const FSEvent = process.binding('fs_event_wrap').FSEvent; + testInitialized(new FSEvent(), 'FSEvent'); +} + + +{ + const JSStream = process.binding('js_stream').JSStream; + testInitialized(new JSStream(), 'JSStream'); +} + + +if (common.hasCrypto) { + const tls = require('tls'); + // SecurePair + testInitialized(tls.createSecurePair().ssl, 'Connection'); +} + + +if (common.hasCrypto) { + const crypto = require('crypto'); + + // The handle for PBKDF2 and RandomBytes isn't returned by the function call, + // so need to check it from the callback. + + const mc = common.mustCall(function pb() { + testInitialized(this, 'PBKDF2'); + }); + crypto.pbkdf2('password', 'salt', 1, 20, 'sha256', mc); + + crypto.randomBytes(1, common.mustCall(function rb() { + testInitialized(this, 'RandomBytes'); + })); +} + + +{ + const binding = process.binding('fs'); + const path = require('path'); + + const FSReqWrap = binding.FSReqWrap; + const req = new FSReqWrap(); + req.oncomplete = () => { }; + + testUninitialized(req, 'FSReqWrap'); + binding.access(path._makeLong('../'), fs.F_OK, req); + testInitialized(req, 'FSReqWrap'); + + const StatWatcher = binding.StatWatcher; + testInitialized(new StatWatcher(), 'StatWatcher'); +} + + +{ + const HTTPParser = process.binding('http_parser').HTTPParser; + testInitialized(new HTTPParser(), 'HTTPParser'); +} + + +{ + const Gzip = require('zlib').Gzip; + testInitialized(new Gzip()._handle, 'Zlib'); +} + + +{ + const binding = process.binding('pipe_wrap'); + const handle = new binding.Pipe(); + testInitialized(handle, 'Pipe'); + const req = new binding.PipeConnectWrap(); + testUninitialized(req, 'PipeConnectWrap'); + req.address = common.PIPE; + req.oncomplete = common.mustCall(() => handle.close()); + handle.connect(req, req.address, req.oncomplete); + testInitialized(req, 'PipeConnectWrap'); +} + + +{ + const Process = process.binding('process_wrap').Process; + testInitialized(new Process(), 'Process'); +} + + +{ + const Signal = process.binding('signal_wrap').Signal; + testInitialized(new Signal(), 'Signal'); +} + + +{ + const binding = process.binding('stream_wrap'); + testUninitialized(new binding.WriteWrap(), 'WriteWrap'); +} + +{ + const stream_wrap = process.binding('stream_wrap'); + const tcp_wrap = process.binding('tcp_wrap'); + const server = net.createServer(common.mustCall((socket) => { + socket.on('data', (x) => { + socket.end(); + socket.destroy(); + }); + socket.resume(); + })).listen(0, common.localhostIPv4, common.mustCall(() => { + const handle = new tcp_wrap.TCP(); + const req = new tcp_wrap.TCPConnectWrap(); + const sreq = new stream_wrap.ShutdownWrap(); + const wreq = new stream_wrap.WriteWrap(); + testInitialized(handle, 'TCP'); + testUninitialized(req, 'TCPConnectWrap'); + testUninitialized(sreq, 'ShutdownWrap'); + + sreq.oncomplete = common.mustCall(() => { + handle.close(); + server.close(); + }); + + wreq.handle = handle; + wreq.oncomplete = common.mustCall(() => { + handle.shutdown(sreq); + testInitialized(sreq, 'ShutdownWrap'); + }); + wreq.async = true; + + req.oncomplete = common.mustCall(() => { + // Use a long string to make sure the write happens asynchronously. + const err = handle.writeLatin1String(wreq, 'hi'.repeat(100000)); + if (err) + throw new Error(`write failed: ${process.binding('uv').errname(err)}`); + testInitialized(wreq, 'WriteWrap'); + }); + req.address = common.localhostIPv4; + req.port = server.address().port; + const err = handle.connect(req, req.address, req.port); + assert.strictEqual(err, 0); + testInitialized(req, 'TCPConnectWrap'); + })); +} + + +{ + const TimerWrap = process.binding('timer_wrap').Timer; + testInitialized(new TimerWrap(), 'Timer'); +} + + +if (common.hasCrypto) { + const TCP = process.binding('tcp_wrap').TCP; + const tcp = new TCP(); + + const ca = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii'); + const cert = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii'); + const key = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii'); + const credentials = require('tls').createSecureContext({ ca, cert, key }); + + // TLSWrap is exposed, but needs to be instantiated via tls_wrap.wrap(). + const tls_wrap = process.binding('tls_wrap'); + testInitialized( + tls_wrap.wrap(tcp._externalStream, credentials.context, true), 'TLSWrap'); +} + + +{ + const tty_wrap = process.binding('tty_wrap'); + if (tty_wrap.isTTY(0)) { + testInitialized(new tty_wrap.TTY(0, false), 'TTY'); + } +} + + +{ + const binding = process.binding('udp_wrap'); + const handle = new binding.UDP(); + const req = new binding.SendWrap(); + testInitialized(handle, 'UDP'); + testUninitialized(req, 'SendWrap'); + + handle.bind('0.0.0.0', common.PORT, undefined); + req.address = '127.0.0.1'; + req.port = common.PORT; + req.oncomplete = () => handle.close(); + handle.send(req, [Buffer.alloc(1)], 1, req.port, req.address, true); + testInitialized(req, 'SendWrap'); +} |