Browse Source

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 <trev.norris@gmail.com>
v4.0.0-rc
Fedor Indutny 9 years ago
parent
commit
b266074347
  1. 35
      src/env.cc
  2. 2
      src/env.h
  3. 27
      src/node.cc
  4. 2
      src/node_internals.h

35
src/env.cc

@ -10,6 +10,7 @@ using v8::Local;
using v8::Message; using v8::Message;
using v8::StackFrame; using v8::StackFrame;
using v8::StackTrace; using v8::StackTrace;
using v8::TryCatch;
void Environment::PrintSyncTrace() const { void Environment::PrintSyncTrace() const {
if (!trace_sync_io_) if (!trace_sync_io_)
@ -55,4 +56,38 @@ void Environment::PrintSyncTrace() const {
fflush(stderr); 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 } // namespace node

2
src/env.h

@ -424,6 +424,8 @@ class Environment {
void PrintSyncTrace() const; void PrintSyncTrace() const;
inline void set_trace_sync_io(bool value); inline void set_trace_sync_io(bool value);
bool KickNextTick();
inline uint32_t* heap_statistics_buffer() const; inline uint32_t* heap_statistics_buffer() const;
inline void set_heap_statistics_buffer(uint32_t* pointer); inline void set_heap_statistics_buffer(uint32_t* pointer);

27
src/node.cc

@ -1026,7 +1026,6 @@ Handle<Value> MakeCallback(Environment* env,
// If you hit this assertion, you forgot to enter the v8::Context first. // If you hit this assertion, you forgot to enter the v8::Context first.
CHECK_EQ(env->context(), env->isolate()->GetCurrentContext()); CHECK_EQ(env->context(), env->isolate()->GetCurrentContext());
Local<Object> process = env->process_object();
Local<Object> object, domain; Local<Object> object, domain;
bool has_async_queue = false; bool has_async_queue = false;
bool has_domain = false; bool has_domain = false;
@ -1092,32 +1091,8 @@ Handle<Value> MakeCallback(Environment* env,
return Undefined(env->isolate()); return Undefined(env->isolate());
} }
Environment::TickInfo* tick_info = env->tick_info(); if (!env->KickNextTick())
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);
return Undefined(env->isolate()); return Undefined(env->isolate());
}
return ret; return ret;
} }

2
src/node_internals.h

@ -69,6 +69,8 @@ v8::Handle<v8::Value> MakeCallback(Environment* env,
int argc = 0, int argc = 0,
v8::Handle<v8::Value>* argv = nullptr); v8::Handle<v8::Value>* argv = nullptr);
bool KickNextTick();
// Convert a struct sockaddr to a { address: '1.2.3.4', port: 1234 } JS object. // 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. // Sets address and port properties on the info object and returns it.
// If |info| is omitted, a new object is returned. // If |info| is omitted, a new object is returned.

Loading…
Cancel
Save