From b2660743470be1562a782f850a28349ceaf039ad Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Wed, 26 Aug 2015 04:37:50 -0700 Subject: [PATCH] env: introduce `KickNextTick` There might be a need to "kick off" the next tick queue and execute events on it. Normally it is done through the `MakeCallback` interface, but in case when it is not - we need a way to "kick them off" manually. PR-URL: https://github.com/nodejs/node/pull/2355 Reviewed-By: Trevor Norris --- src/env.cc | 35 +++++++++++++++++++++++++++++++++++ src/env.h | 2 ++ src/node.cc | 27 +-------------------------- src/node_internals.h | 2 ++ 4 files changed, 40 insertions(+), 26 deletions(-) diff --git a/src/env.cc b/src/env.cc index 3deb4db09e..e28866efd0 100644 --- a/src/env.cc +++ b/src/env.cc @@ -10,6 +10,7 @@ using v8::Local; using v8::Message; using v8::StackFrame; using v8::StackTrace; +using v8::TryCatch; void Environment::PrintSyncTrace() const { if (!trace_sync_io_) @@ -55,4 +56,38 @@ void Environment::PrintSyncTrace() const { fflush(stderr); } + +bool Environment::KickNextTick() { + TickInfo* info = tick_info(); + + if (info->in_tick()) { + return true; + } + + if (info->length() == 0) { + isolate()->RunMicrotasks(); + } + + if (info->length() == 0) { + info->set_index(0); + return true; + } + + info->set_in_tick(true); + + // process nextTicks after call + TryCatch try_catch; + try_catch.SetVerbose(true); + tick_callback_function()->Call(process_object(), 0, nullptr); + + info->set_in_tick(false); + + if (try_catch.HasCaught()) { + info->set_last_threw(true); + return false; + } + + return true; +} + } // namespace node diff --git a/src/env.h b/src/env.h index 1801ffecd3..5830b02b58 100644 --- a/src/env.h +++ b/src/env.h @@ -424,6 +424,8 @@ class Environment { void PrintSyncTrace() const; inline void set_trace_sync_io(bool value); + bool KickNextTick(); + inline uint32_t* heap_statistics_buffer() const; inline void set_heap_statistics_buffer(uint32_t* pointer); diff --git a/src/node.cc b/src/node.cc index 3c6441a6f2..084fe900cd 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1026,7 +1026,6 @@ Handle MakeCallback(Environment* env, // If you hit this assertion, you forgot to enter the v8::Context first. CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); - Local process = env->process_object(); Local object, domain; bool has_async_queue = false; bool has_domain = false; @@ -1092,32 +1091,8 @@ Handle MakeCallback(Environment* env, return Undefined(env->isolate()); } - Environment::TickInfo* tick_info = env->tick_info(); - - if (tick_info->in_tick()) { - return ret; - } - - if (tick_info->length() == 0) { - env->isolate()->RunMicrotasks(); - } - - if (tick_info->length() == 0) { - tick_info->set_index(0); - return ret; - } - - tick_info->set_in_tick(true); - - // process nextTicks after call - env->tick_callback_function()->Call(process, 0, nullptr); - - tick_info->set_in_tick(false); - - if (try_catch.HasCaught()) { - tick_info->set_last_threw(true); + if (!env->KickNextTick()) return Undefined(env->isolate()); - } return ret; } diff --git a/src/node_internals.h b/src/node_internals.h index 8f35433b2f..ffb5ec7ad9 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -69,6 +69,8 @@ v8::Handle MakeCallback(Environment* env, int argc = 0, v8::Handle* argv = nullptr); +bool KickNextTick(); + // Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // Sets address and port properties on the info object and returns it. // If |info| is omitted, a new object is returned.