| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 28aac7f commit 3eaa593
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,32 +24,39 @@ inline AsyncWrap::AsyncWrap(Environment* env, | |||
| 24 | 24 | // Shift provider value over to prevent id collision. | |
| 25 | 25 | persistent().SetWrapperClassId(NODE_ASYNC_ID_OFFSET + provider); | |
| 26 | 26 | ||
| 27 | - // Check user controlled flag to see if the init callback should run. | ||
| 28 | - if (!env->using_asyncwrap()) | ||
| 29 | - return; | ||
| 27 | + v8::Local<v8::Function> init_fn = env->async_hooks_init_function(); | ||
| 30 | 28 | ||
| 31 | - // If callback hooks have not been enabled, and there is no parent, return. | ||
| 32 | - if (!env->async_wrap_callbacks_enabled() && parent == nullptr) | ||
| 29 | + // No init callback exists, no reason to go on. | ||
| 30 | + if (init_fn.IsEmpty()) | ||
| 33 | 31 | return; | |
| 34 | 32 | ||
| 35 | - // If callback hooks have not been enabled and parent has no queue, return. | ||
| 36 | - if (!env->async_wrap_callbacks_enabled() && !parent->has_async_queue()) | ||
| 33 | + // If async wrap callbacks are disabled and no parent was passed that has | ||
| 34 | + // run the init callback then return. | ||
| 35 | + if (!env->async_wrap_callbacks_enabled() && | ||
| 36 | + (parent == nullptr || !parent->ran_init_callback())) | ||
| 37 | 37 | return; | |
| 38 | 38 | ||
| 39 | 39 | v8::HandleScope scope(env->isolate()); | |
| 40 | - v8::TryCatch try_catch; | ||
| 41 | 40 | ||
| 42 | - v8::Local<v8::Value> n = v8::Int32::New(env->isolate(), provider); | ||
| 43 | - env->async_hooks_init_function()->Call(object, 1, &n); | ||
| 41 | + v8::Local<v8::Value> argv[] = { | ||
| 42 | + v8::Int32::New(env->isolate(), provider), | ||
| 43 | + Null(env->isolate()) | ||
| 44 | + }; | ||
| 45 | + | ||
| 46 | + if (parent != nullptr) | ||
| 47 | + argv[1] = parent->object(); | ||
| 48 | + | ||
| 49 | + v8::MaybeLocal<v8::Value> ret = | ||
| 50 | + init_fn->Call(env->context(), object, ARRAY_SIZE(argv), argv); | ||
| 44 | 51 | ||
| 45 | - if (try_catch.HasCaught()) | ||
| 52 | + if (ret.IsEmpty()) | ||
| 46 | 53 | FatalError("node::AsyncWrap::AsyncWrap", "init hook threw"); | |
| 47 | 54 | ||
| 48 | - bits_ |= 1; // has_async_queue() is true now. | ||
| 55 | + bits_ |= 1; // ran_init_callback() is true now. | ||
| 49 | 56 | } | |
| 50 | 57 | ||
| 51 | 58 | ||
| 52 | - inline bool AsyncWrap::has_async_queue() const { | ||
| 59 | + inline bool AsyncWrap::ran_init_callback() const { | ||
| 53 | 60 | return static_cast<bool>(bits_ & 1); | |
| 54 | 61 | } | |
| 55 | 62 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -123,8 +123,6 @@ static void SetupHooks(const FunctionCallbackInfo<Value>& args) { | |||
| 123 | 123 | env->set_async_hooks_init_function(args[0].As<Function>()); | |
| 124 | 124 | env->set_async_hooks_pre_function(args[1].As<Function>()); | |
| 125 | 125 | env->set_async_hooks_post_function(args[2].As<Function>()); | |
| 126 | - | ||
| 127 | - env->set_using_asyncwrap(true); | ||
| 128 | 126 | } | |
| 129 | 127 | ||
| 130 | 128 | ||
@@ -146,6 +144,10 @@ static void Initialize(Local<Object> target, | |||
| 146 | 144 | NODE_ASYNC_PROVIDER_TYPES(V) | |
| 147 | 145 | #undef V | |
| 148 | 146 | target->Set(FIXED_ONE_BYTE_STRING(isolate, "Providers"), async_providers); | |
| 147 | + | ||
| 148 | + env->set_async_hooks_init_function(Local<Function>()); | ||
| 149 | + env->set_async_hooks_pre_function(Local<Function>()); | ||
| 150 | + env->set_async_hooks_post_function(Local<Function>()); | ||
| 149 | 151 | } | |
| 150 | 152 | ||
| 151 | 153 | ||
@@ -164,6 +166,8 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb, | |||
| 164 | 166 | Local<Value>* argv) { | |
| 165 | 167 | CHECK(env()->context() == env()->isolate()->GetCurrentContext()); | |
| 166 | 168 | ||
| 169 | + Local<Function> pre_fn = env()->async_hooks_pre_function(); | ||
| 170 | + Local<Function> post_fn = env()->async_hooks_post_function(); | ||
| 167 | 171 | Local<Object> context = object(); | |
| 168 | 172 | Local<Object> process = env()->process_object(); | |
| 169 | 173 | Local<Object> domain; | |
@@ -179,7 +183,7 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb, | |||
| 179 | 183 | } | |
| 180 | 184 | } | |
| 181 | 185 | ||
| 182 | - TryCatch try_catch; | ||
| 186 | + TryCatch try_catch(env()->isolate()); | ||
| 183 | 187 | try_catch.SetVerbose(true); | |
| 184 | 188 | ||
| 185 | 189 | if (has_domain) { | |
@@ -191,9 +195,9 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb, | |||
| 191 | 195 | } | |
| 192 | 196 | } | |
| 193 | 197 | ||
| 194 | - if (has_async_queue()) { | ||
| 198 | + if (ran_init_callback() && !pre_fn.IsEmpty()) { | ||
| 195 | 199 | try_catch.SetVerbose(false); | |
| 196 | - env()->async_hooks_pre_function()->Call(context, 0, nullptr); | ||
| 200 | + pre_fn->Call(context, 0, nullptr); | ||
| 197 | 201 | if (try_catch.HasCaught()) | |
| 198 | 202 | FatalError("node::AsyncWrap::MakeCallback", "pre hook threw"); | |
| 199 | 203 | try_catch.SetVerbose(true); | |
@@ -205,9 +209,9 @@ Local<Value> AsyncWrap::MakeCallback(const Local<Function> cb, | |||
| 205 | 209 | return Undefined(env()->isolate()); | |
| 206 | 210 | } | |
| 207 | 211 | ||
| 208 | - if (has_async_queue()) { | ||
| 212 | + if (ran_init_callback() && !post_fn.IsEmpty()) { | ||
| 209 | 213 | try_catch.SetVerbose(false); | |
| 210 | - env()->async_hooks_post_function()->Call(context, 0, nullptr); | ||
| 214 | + post_fn->Call(context, 0, nullptr); | ||
| 211 | 215 | if (try_catch.HasCaught()) | |
| 212 | 216 | FatalError("node::AsyncWrap::MakeCallback", "post hook threw"); | |
| 213 | 217 | try_catch.SetVerbose(true); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -70,7 +70,7 @@ class AsyncWrap : public BaseObject { | |||
| 70 | 70 | ||
| 71 | 71 | private: | |
| 72 | 72 | inline AsyncWrap(); | |
| 73 | - inline bool has_async_queue() const; | ||
| 73 | + inline bool ran_init_callback() const; | ||
| 74 | 74 | ||
| 75 | 75 | // When the async hooks init JS function is called from the constructor it is | |
| 76 | 76 | // expected the context object will receive a _asyncQueue object property | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -208,7 +208,6 @@ inline Environment::Environment(v8::Local<v8::Context> context, | |||
| 208 | 208 | isolate_data_(IsolateData::GetOrCreate(context->GetIsolate(), loop)), | |
| 209 | 209 | timer_base_(uv_now(loop)), | |
| 210 | 210 | using_domains_(false), | |
| 211 | - using_asyncwrap_(false), | ||
| 212 | 211 | printed_error_(false), | |
| 213 | 212 | trace_sync_io_(false), | |
| 214 | 213 | debugger_agent_(this), | |
@@ -348,14 +347,6 @@ inline void Environment::set_using_domains(bool value) { | |||
| 348 | 347 | using_domains_ = value; | |
| 349 | 348 | } | |
| 350 | 349 | ||
| 351 | - inline bool Environment::using_asyncwrap() const { | ||
| 352 | - return using_asyncwrap_; | ||
| 353 | - } | ||
| 354 | - | ||
| 355 | - inline void Environment::set_using_asyncwrap(bool value) { | ||
| 356 | - using_asyncwrap_ = value; | ||
| 357 | - } | ||
| 358 | - | ||
| 359 | 350 | inline bool Environment::printed_error() const { | |
| 360 | 351 | return printed_error_; | |
| 361 | 352 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -435,9 +435,6 @@ class Environment { | |||
| 435 | 435 | inline bool using_domains() const; | |
| 436 | 436 | inline void set_using_domains(bool value); | |
| 437 | 437 | ||
| 438 | - inline bool using_asyncwrap() const; | ||
| 439 | - inline void set_using_asyncwrap(bool value); | ||
| 440 | - | ||
| 441 | 438 | inline bool printed_error() const; | |
| 442 | 439 | inline void set_printed_error(bool value); | |
| 443 | 440 | ||
@@ -537,7 +534,6 @@ class Environment { | |||
| 537 | 534 | ares_channel cares_channel_; | |
| 538 | 535 | ares_task_list cares_task_list_; | |
| 539 | 536 | bool using_domains_; | |
| 540 | - bool using_asyncwrap_; | ||
| 541 | 537 | bool printed_error_; | |
| 542 | 538 | bool trace_sync_io_; | |
| 543 | 539 | debugger::Agent debugger_agent_; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1040,15 +1040,19 @@ Local<Value> MakeCallback(Environment* env, | |||
| 1040 | 1040 | // If you hit this assertion, you forgot to enter the v8::Context first. | |
| 1041 | 1041 | CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); | |
| 1042 | 1042 | ||
| 1043 | + Local<Function> pre_fn = env->async_hooks_pre_function(); | ||
| 1044 | + Local<Function> post_fn = env->async_hooks_post_function(); | ||
| 1043 | 1045 | Local<Object> object, domain; | |
| 1044 | - bool has_async_queue = false; | ||
| 1046 | + bool ran_init_callback = false; | ||
| 1045 | 1047 | bool has_domain = false; | |
| 1046 | 1048 | ||
| 1049 | + // TODO(trevnorris): Adding "_asyncQueue" to the "this" in the init callback | ||
| 1050 | + // is a horrible way to detect usage. Rethink how detection should happen. | ||
| 1047 | 1051 | if (recv->IsObject()) { | |
| 1048 | 1052 | object = recv.As<Object>(); | |
| 1049 | 1053 | Local<Value> async_queue_v = object->Get(env->async_queue_string()); | |
| 1050 | 1054 | if (async_queue_v->IsObject()) | |
| 1051 | - has_async_queue = true; | ||
| 1055 | + ran_init_callback = true; | ||
| 1052 | 1056 | } | |
| 1053 | 1057 | ||
| 1054 | 1058 | if (env->using_domains()) { | |
@@ -1074,19 +1078,19 @@ Local<Value> MakeCallback(Environment* env, | |||
| 1074 | 1078 | } | |
| 1075 | 1079 | } | |
| 1076 | 1080 | ||
| 1077 | - if (has_async_queue) { | ||
| 1081 | + if (ran_init_callback && !pre_fn.IsEmpty()) { | ||
| 1078 | 1082 | try_catch.SetVerbose(false); | |
| 1079 | - env->async_hooks_pre_function()->Call(object, 0, nullptr); | ||
| 1083 | + pre_fn->Call(object, 0, nullptr); | ||
| 1080 | 1084 | if (try_catch.HasCaught()) | |
| 1081 | 1085 | FatalError("node::MakeCallback", "pre hook threw"); | |
| 1082 | 1086 | try_catch.SetVerbose(true); | |
| 1083 | 1087 | } | |
| 1084 | 1088 | ||
| 1085 | 1089 | Local<Value> ret = callback->Call(recv, argc, argv); | |
| 1086 | 1090 | ||
| 1087 | - if (has_async_queue) { | ||
| 1091 | + if (ran_init_callback && !post_fn.IsEmpty()) { | ||
| 1088 | 1092 | try_catch.SetVerbose(false); | |
| 1089 | - env->async_hooks_post_function()->Call(object, 0, nullptr); | ||
| 1093 | + post_fn->Call(object, 0, nullptr); | ||
| 1090 | 1094 | if (try_catch.HasCaught()) | |
| 1091 | 1095 | FatalError("node::MakeCallback", "post hook threw"); | |
| 1092 | 1096 | try_catch.SetVerbose(true); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,46 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const net = require('net'); | ||
| 6 | + const async_wrap = process.binding('async_wrap'); | ||
| 7 | + const providers = Object.keys(async_wrap.Providers); | ||
| 8 | + | ||
| 9 | + let cntr = 0; | ||
| 10 | + let server; | ||
| 11 | + let client; | ||
| 12 | + | ||
| 13 | + function init(type, parent) { | ||
| 14 | + if (parent) { | ||
| 15 | + cntr++; | ||
| 16 | + // Cannot assert in init callback or will abort. | ||
| 17 | + process.nextTick(() => { | ||
| 18 | + assert.equal(providers[type], 'TCPWRAP'); | ||
| 19 | + assert.equal(parent, server._handle, 'server doesn\'t match parent'); | ||
| 20 | + assert.equal(this, client._handle, 'client doesn\'t match context'); | ||
| 21 | + }); | ||
| 22 | + } | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + function noop() { } | ||
| 26 | + | ||
| 27 | + async_wrap.setupHooks(init, noop, noop); | ||
| 28 | + async_wrap.enable(); | ||
| 29 | + | ||
| 30 | + server = net.createServer(function(c) { | ||
| 31 | + client = c; | ||
| 32 | + // Allow init callback to run before closing. | ||
| 33 | + setImmediate(() => { | ||
| 34 | + c.end(); | ||
| 35 | + this.close(); | ||
| 36 | + }); | ||
| 37 | + }).listen(common.PORT, function() { | ||
| 38 | + net.connect(common.PORT, noop); | ||
| 39 | + }); | ||
| 40 | + | ||
| 41 | + async_wrap.disable(); | ||
| 42 | + | ||
| 43 | + process.on('exit', function() { | ||
| 44 | + // init should have only been called once with a parent. | ||
| 45 | + assert.equal(cntr, 1); | ||
| 46 | + }); | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,43 @@ | |||
| 1 | + 'use strict'; | ||
| 2 | + | ||
| 3 | + const common = require('../common'); | ||
| 4 | + const assert = require('assert'); | ||
| 5 | + const net = require('net'); | ||
| 6 | + const async_wrap = process.binding('async_wrap'); | ||
| 7 | + | ||
| 8 | + let cntr = 0; | ||
| 9 | + let server; | ||
| 10 | + let client; | ||
| 11 | + | ||
| 12 | + function init(type, parent) { | ||
| 13 | + if (parent) { | ||
| 14 | + cntr++; | ||
| 15 | + // Cannot assert in init callback or will abort. | ||
| 16 | + process.nextTick(() => { | ||
| 17 | + assert.equal(parent, server._handle, 'server doesn\'t match parent'); | ||
| 18 | + assert.equal(this, client._handle, 'client doesn\'t match context'); | ||
| 19 | + }); | ||
| 20 | + } | ||
| 21 | + } | ||
| 22 | + | ||
| 23 | + function noop() { } | ||
| 24 | + | ||
| 25 | + async_wrap.setupHooks(init, noop, noop); | ||
| 26 | + async_wrap.enable(); | ||
| 27 | + | ||
| 28 | + server = net.createServer(function(c) { | ||
| 29 | + client = c; | ||
| 30 | + // Allow init callback to run before closing. | ||
| 31 | + setImmediate(() => { | ||
| 32 | + c.end(); | ||
| 33 | + this.close(); | ||
| 34 | + }); | ||
| 35 | + }).listen(common.PORT, function() { | ||
| 36 | + net.connect(common.PORT, noop); | ||
| 37 | + }); | ||
| 38 | + | ||
| 39 | + | ||
| 40 | + process.on('exit', function() { | ||
| 41 | + // init should have only been called once with a parent. | ||
| 42 | + assert.equal(cntr, 1); | ||
| 43 | + }); | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments