Merge pull request #155 from atom/fix-q

Fix executing process.nextTick's callbacks
This commit is contained in:
Cheng Zhao 2014-01-10 02:13:07 -08:00
commit dc880b16f1
6 changed files with 34 additions and 9 deletions

View file

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

View file

@ -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.

View file

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

View file

@ -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",

View file

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

View file

@ -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()