Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix executing process.nextTick's callbacks #155

Merged
merged 3 commits into from
Jan 10, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 19 additions & 5 deletions common/api/atom_bindings.cc
Expand Up @@ -17,7 +17,7 @@ namespace {
static int kMaxCallStackSize = 200; // Same with WebKit.

// 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.
static uv_async_t g_callback_uv_handle;
Expand All @@ -28,8 +28,22 @@ RefCountedV8Function g_v8_callback;
// Dummy class type that used for crashing the program.
struct DummyClass { bool crash; };

// Dummy async handler that does nothing.
void UvNoOp(uv_async_t* handle, int status) {
// Async handler to call next process.nextTick callbacks.
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.
Expand Down Expand Up @@ -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);

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);
}

Expand Down Expand Up @@ -133,7 +147,7 @@ void AtomBindings::Crash(const v8::FunctionCallbackInfo<v8::Value>& args) {
// static
void AtomBindings::ActivateUVLoop(
const v8::FunctionCallbackInfo<v8::Value>& args) {
uv_async_send(&g_dummy_uv_handle);
uv_async_send(&g_next_tick_uv_handle);
}

// static
Expand Down
2 changes: 1 addition & 1 deletion common/node_bindings.cc
Expand Up @@ -199,7 +199,7 @@ void NodeBindings::UvRunOnce() {
// Enter node context while dealing with uv events, by default the global
// env would be used unless user specified another one (this happens for
// 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());

// Deal with uv events.
Expand Down
2 changes: 1 addition & 1 deletion common/node_bindings.h
Expand Up @@ -40,7 +40,7 @@ class NodeBindings {

// Gets/sets the environment to wrap uv loop.
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:
explicit NodeBindings(bool is_browser);
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -7,6 +7,7 @@
"coffeelint": "~0.6.1",
"mocha": "~1.13.0",
"pathwatcher": "0.13.0",
"q": "0.9.7",
"walkdir": "~0.0.7",
"runas": "0.3.0",
"formidable": "~1.0.14",
Expand Down
4 changes: 2 additions & 2 deletions renderer/atom_renderer_client.cc
Expand Up @@ -62,7 +62,7 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame,
web_page_envs_.push_back(env);

// 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);
}

Expand Down Expand Up @@ -91,7 +91,7 @@ void AtomRendererClient::WillReleaseScriptContext(
// env->Dispose();

// 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] :
NULL;
node_bindings_->set_uv_env(env);
Expand Down
10 changes: 10 additions & 0 deletions spec/modules-spec.coffee
Expand Up @@ -30,3 +30,13 @@ describe 'third-party module', ->
watcher.close()
done()
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()