mirror of https://github.com/nodejs/node.git
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>pull/2355/merge
parent
972a57cb20
commit
b266074347
35
src/env.cc
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
|
||||||
|
|
|
@ -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
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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…
Reference in New Issue