Wrap uv loop with web page context in renderer.

This commit is contained in:
Cheng Zhao 2014-01-09 21:35:29 +08:00
parent 968fc71b78
commit e7b7efeb0a
3 changed files with 21 additions and 3 deletions

View file

@ -66,6 +66,7 @@ NodeBindings::NodeBindings(bool is_browser)
message_loop_(NULL),
uv_loop_(uv_default_loop()),
embed_closed_(false),
uv_env_(NULL),
weak_factory_(this) {
}
@ -193,9 +194,13 @@ void NodeBindings::RunMessageLoop() {
void NodeBindings::UvRunOnce() {
DCHECK(!is_browser_ || BrowserThread::CurrentlyOn(BrowserThread::UI));
// Enter node context while dealing with uv events.
v8::HandleScope handle_scope(node_isolate);
v8::Context::Scope context_scope(global_env->context());
// 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;
v8::Context::Scope context_scope(env->context());
// Deal with uv events.
int r = uv_run(uv_loop_, (uv_run_mode)(UV_RUN_ONCE | UV_RUN_NOWAIT));

View file

@ -38,6 +38,10 @@ class NodeBindings {
// Do message loop integration.
virtual void RunMessageLoop();
// 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_; }
protected:
explicit NodeBindings(bool is_browser);
@ -84,6 +88,9 @@ class NodeBindings {
// Semaphore to wait for main loop in the embed thread.
uv_sem_t embed_sem_;
// Environment that to wrap the uv loop.
node::Environment* uv_env_;
base::WeakPtrFactory<NodeBindings> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(NodeBindings);

View file

@ -51,10 +51,13 @@ void AtomRendererClient::DidCreateScriptContext(WebKit::WebFrame* frame,
node_bindings_->RunMessageLoop();
// Setup node environment for each window.
node_bindings_->CreateEnvironment(context);
node::Environment* env = node_bindings_->CreateEnvironment(context);
// Add atom-shell extended APIs.
atom_bindings_->BindToFrame(frame);
// Make uv loop being wrapped by window context.
node_bindings_->set_uv_env(env);
}
void AtomRendererClient::WillReleaseScriptContext(
@ -67,6 +70,9 @@ void AtomRendererClient::WillReleaseScriptContext(
return;
}
if (env == node_bindings_->get_uv_env())
node_bindings_->set_uv_env(NULL);
env->Dispose();
}