Merge pull request #155 from atom/fix-q
Fix executing process.nextTick's callbacks
This commit is contained in:
commit
dc880b16f1
6 changed files with 34 additions and 9 deletions
|
@ -17,7 +17,7 @@ namespace {
|
||||||
static int kMaxCallStackSize = 200; // Same with WebKit.
|
static int kMaxCallStackSize = 200; // Same with WebKit.
|
||||||
|
|
||||||
// Async handle to wake up uv loop.
|
// Async handle to wake up uv loop.
|
||||||
static uv_async_t g_dummy_uv_handle;
|
static uv_async_t g_next_tick_uv_handle;
|
||||||
|
|
||||||
// Async handle to execute the stored v8 callback.
|
// Async handle to execute the stored v8 callback.
|
||||||
static uv_async_t g_callback_uv_handle;
|
static uv_async_t g_callback_uv_handle;
|
||||||
|
@ -28,8 +28,22 @@ RefCountedV8Function g_v8_callback;
|
||||||
// Dummy class type that used for crashing the program.
|
// Dummy class type that used for crashing the program.
|
||||||
struct DummyClass { bool crash; };
|
struct DummyClass { bool crash; };
|
||||||
|
|
||||||
// Dummy async handler that does nothing.
|
// Async handler to call next process.nextTick callbacks.
|
||||||
void UvNoOp(uv_async_t* handle, int status) {
|
void UvCallNextTick(uv_async_t* handle, int status) {
|
||||||
|
node::Environment* env = node::Environment::GetCurrent(node_isolate);
|
||||||
|
node::Environment::TickInfo* tick_info = env->tick_info();
|
||||||
|
|
||||||
|
if (tick_info->in_tick())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (tick_info->length() == 0) {
|
||||||
|
tick_info->set_index(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tick_info->set_in_tick(true);
|
||||||
|
env->tick_callback_function()->Call(env->process_object(), 0, NULL);
|
||||||
|
tick_info->set_in_tick(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Async handler to execute the stored v8 callback.
|
// Async handler to execute the stored v8 callback.
|
||||||
|
@ -60,7 +74,7 @@ v8::Handle<v8::Object> DumpStackFrame(v8::Handle<v8::StackFrame> stack_frame) {
|
||||||
node::node_module_struct* GetBuiltinModule(const char *name, bool is_browser);
|
node::node_module_struct* GetBuiltinModule(const char *name, bool is_browser);
|
||||||
|
|
||||||
AtomBindings::AtomBindings() {
|
AtomBindings::AtomBindings() {
|
||||||
uv_async_init(uv_default_loop(), &g_dummy_uv_handle, UvNoOp);
|
uv_async_init(uv_default_loop(), &g_next_tick_uv_handle, UvCallNextTick);
|
||||||
uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback);
|
uv_async_init(uv_default_loop(), &g_callback_uv_handle, UvOnCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +147,7 @@ void AtomBindings::Crash(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
// static
|
// static
|
||||||
void AtomBindings::ActivateUVLoop(
|
void AtomBindings::ActivateUVLoop(
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
uv_async_send(&g_dummy_uv_handle);
|
uv_async_send(&g_next_tick_uv_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
|
@ -199,7 +199,7 @@ void NodeBindings::UvRunOnce() {
|
||||||
// Enter node context while dealing with uv events, by default the global
|
// Enter node context while dealing with uv events, by default the global
|
||||||
// env would be used unless user specified another one (this happens for
|
// env would be used unless user specified another one (this happens for
|
||||||
// renderer process, which wraps the uv loop with web page context).
|
// renderer process, which wraps the uv loop with web page context).
|
||||||
node::Environment* env = get_uv_env() ? get_uv_env() : global_env;
|
node::Environment* env = uv_env() ? uv_env() : global_env;
|
||||||
v8::Context::Scope context_scope(env->context());
|
v8::Context::Scope context_scope(env->context());
|
||||||
|
|
||||||
// Deal with uv events.
|
// Deal with uv events.
|
||||||
|
|
|
@ -40,7 +40,7 @@ class NodeBindings {
|
||||||
|
|
||||||
// Gets/sets the environment to wrap uv loop.
|
// Gets/sets the environment to wrap uv loop.
|
||||||
void set_uv_env(node::Environment* env) { uv_env_ = env; }
|
void set_uv_env(node::Environment* env) { uv_env_ = env; }
|
||||||
node::Environment* get_uv_env() const { return uv_env_; }
|
node::Environment* uv_env() const { return uv_env_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit NodeBindings(bool is_browser);
|
explicit NodeBindings(bool is_browser);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"coffeelint": "~0.6.1",
|
"coffeelint": "~0.6.1",
|
||||||
"mocha": "~1.13.0",
|
"mocha": "~1.13.0",
|
||||||
"pathwatcher": "0.13.0",
|
"pathwatcher": "0.13.0",
|
||||||
|
"q": "0.9.7",
|
||||||
"walkdir": "~0.0.7",
|
"walkdir": "~0.0.7",
|
||||||
"runas": "0.3.0",
|
"runas": "0.3.0",
|
||||||
"formidable": "~1.0.14",
|
"formidable": "~1.0.14",
|
||||||
|
|
|
@ -62,7 +62,7 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame,
|
||||||
web_page_envs_.push_back(env);
|
web_page_envs_.push_back(env);
|
||||||
|
|
||||||
// Make uv loop being wrapped by window context.
|
// Make uv loop being wrapped by window context.
|
||||||
if (node_bindings_->get_uv_env() == NULL)
|
if (node_bindings_->uv_env() == NULL)
|
||||||
node_bindings_->set_uv_env(env);
|
node_bindings_->set_uv_env(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ void AtomRendererClient::WillReleaseScriptContext(
|
||||||
// env->Dispose();
|
// env->Dispose();
|
||||||
|
|
||||||
// Wrap the uv loop with another environment.
|
// Wrap the uv loop with another environment.
|
||||||
if (env == node_bindings_->get_uv_env()) {
|
if (env == node_bindings_->uv_env()) {
|
||||||
node::Environment* env = web_page_envs_.size() > 0 ? web_page_envs_[0] :
|
node::Environment* env = web_page_envs_.size() > 0 ? web_page_envs_[0] :
|
||||||
NULL;
|
NULL;
|
||||||
node_bindings_->set_uv_env(env);
|
node_bindings_->set_uv_env(env);
|
||||||
|
|
|
@ -30,3 +30,13 @@ describe 'third-party module', ->
|
||||||
watcher.close()
|
watcher.close()
|
||||||
done()
|
done()
|
||||||
fs.writeFileSync file, 'content2'
|
fs.writeFileSync file, 'content2'
|
||||||
|
|
||||||
|
describe 'q', ->
|
||||||
|
Q = require 'q'
|
||||||
|
|
||||||
|
describe 'Q.when', ->
|
||||||
|
it 'emits the fullfil callback', (done) ->
|
||||||
|
Q(true).then (val) ->
|
||||||
|
assert.equal val, true
|
||||||
|
console.log 'test'
|
||||||
|
done()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue