diff options
author | Trevor Norris <trev.norris@gmail.com> | 2014-12-09 05:02:09 +0100 |
---|---|---|
committer | Bert Belder <bertbelder@gmail.com> | 2014-12-09 17:57:17 +0100 |
commit | bd83c3966d4564709e8449b3c699af6ece27ff12 (patch) | |
tree | 69be93abab35fb0ad8f5e13bfd28c89244488139 /src/pipe_wrap.cc | |
parent | afe27e34cfc46e86334e2c17b6cbeb0afa316fff (diff) | |
download | android-node-v8-bd83c3966d4564709e8449b3c699af6ece27ff12.tar.gz android-node-v8-bd83c3966d4564709e8449b3c699af6ece27ff12.tar.bz2 android-node-v8-bd83c3966d4564709e8449b3c699af6ece27ff12.zip |
async-wrap: explicitly pass parent
When instantiating a new AsyncWrap allow the parent AsyncWrap to be
passed. This is useful for cases like TCP incoming connections, so the
connection can be tied to the server receiving the connection.
Because the current architecture instantiates the *Wrap inside a
v8::FunctionCallback, the parent pointer is currently wrapped inside a
new v8::External every time and passed as an argument. This adds ~80ns
to instantiation time.
A future optimization would be to add the v8::External as the data field
when creating the v8::FunctionTemplate, change the pointer just before
making the call then NULL'ing it out afterwards. This adds enough code
complexity that it will not be attempted until the current approach
demonstrates it is a bottle neck.
PR-URL: https://github.com/joyent/node/pull/8110
Signed-off-by: Trevor Norris <trev.norris@gmail.com>
Reviewed-by: Fedor Indutny <fedor@indutny.com>
Reviewed-by: Alexis Campailla <alexis@janeasystems.com>
Reviewed-by: Julien Gilli <julien.gilli@joyent.com>
Diffstat (limited to 'src/pipe_wrap.cc')
-rw-r--r-- | src/pipe_wrap.cc | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 512b438218..b91ebe0e5e 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); |