From e017e157ba849f6dcf6a61c61767444503b9496e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 7 Mar 2017 19:35:03 +0900 Subject: [PATCH] Insert node integrations into WebWorker --- atom/renderer/atom_renderer_client.cc | 11 +++++ atom/renderer/atom_renderer_client.h | 4 ++ atom/renderer/web_worker_observer.cc | 71 +++++++++++++++++++++++++++ atom/renderer/web_worker_observer.h | 37 ++++++++++++++ filenames.gypi | 2 + 5 files changed, 125 insertions(+) create mode 100644 atom/renderer/web_worker_observer.cc create mode 100644 atom/renderer/web_worker_observer.h diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index 9b3d2214b4cc..623e09015ba3 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -23,6 +23,7 @@ #include "atom/renderer/guest_view_container.h" #include "atom/renderer/node_array_buffer_bridge.h" #include "atom/renderer/preferences_manager.h" +#include "atom/renderer/web_worker_observer.h" #include "base/command_line.h" #include "chrome/renderer/media/chrome_key_systems.h" #include "chrome/renderer/pepper/pepper_helper.h" @@ -436,6 +437,16 @@ void AtomRendererClient::AddSupportedKeySystems( AddChromeKeySystems(key_systems); } +void AtomRendererClient::DidInitializeWorkerContextOnWorkerThread( + v8::Local context) { + WebWorkerObserver::GetCurrent()->ContextCreated(context); +} + +void AtomRendererClient::WillDestroyWorkerContextOnWorkerThread( + v8::Local context) { + WebWorkerObserver::GetCurrent()->ContextWillDestroy(context); +} + v8::Local AtomRendererClient::GetContext( blink::WebFrame* frame, v8::Isolate* isolate) { if (isolated_world()) diff --git a/atom/renderer/atom_renderer_client.h b/atom/renderer/atom_renderer_client.h index c1d86cddf5e3..af8397854e3e 100644 --- a/atom/renderer/atom_renderer_client.h +++ b/atom/renderer/atom_renderer_client.h @@ -65,6 +65,10 @@ class AtomRendererClient : public content::ContentRendererClient { void AddSupportedKeySystems( std::vector>* key_systems) override; + void DidInitializeWorkerContextOnWorkerThread( + v8::Local context) override; + void WillDestroyWorkerContextOnWorkerThread( + v8::Local context) override; // Whether the node integration has been initialized. bool node_integration_initialized_; diff --git a/atom/renderer/web_worker_observer.cc b/atom/renderer/web_worker_observer.cc new file mode 100644 index 000000000000..223b39322ace --- /dev/null +++ b/atom/renderer/web_worker_observer.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/renderer/web_worker_observer.h" + +#include "atom/common/api/atom_bindings.h" +#include "atom/common/api/event_emitter_caller.h" +#include "atom/common/node_bindings.h" +#include "base/lazy_instance.h" +#include "base/threading/thread_local.h" + +#include "atom/common/node_includes.h" + +namespace atom { + +namespace { + +static base::LazyInstance> + lazy_tls = LAZY_INSTANCE_INITIALIZER; + +} // namespace + +// static +WebWorkerObserver* WebWorkerObserver::GetCurrent() { + WebWorkerObserver* self = lazy_tls.Pointer()->Get(); + return self ? self : new WebWorkerObserver; +} + +WebWorkerObserver::WebWorkerObserver() + : node_bindings_(NodeBindings::Create(false)), + atom_bindings_(new AtomBindings) { + lazy_tls.Pointer()->Set(this); +} + +WebWorkerObserver::~WebWorkerObserver() { + lazy_tls.Pointer()->Set(nullptr); +} + +void WebWorkerObserver::ContextCreated(v8::Local context) { + node_bindings_->Initialize(); + node_bindings_->PrepareMessageLoop(); + + // Setup node environment for each window. + node::Environment* env = node_bindings_->CreateEnvironment(context); + + // Add Electron extended APIs. + atom_bindings_->BindTo(env->isolate(), env->process_object()); + + // Load everything. + node_bindings_->LoadEnvironment(env); + + // Make uv loop being wrapped by window context. + node_bindings_->set_uv_env(env); + + // Give the node loop a run to make sure everything is ready. + node_bindings_->RunMessageLoop(); +} + +void WebWorkerObserver::ContextWillDestroy(v8::Local context) { + node::Environment* env = node::Environment::GetCurrent(context); + if (env) + mate::EmitEvent(env->isolate(), env->process_object(), "exit"); + + // Destroy the node environment. + node::FreeEnvironment(env); + atom_bindings_.reset(); + node_bindings_.reset(); +} + +} // namespace atom diff --git a/atom/renderer/web_worker_observer.h b/atom/renderer/web_worker_observer.h new file mode 100644 index 000000000000..45ccfc3dc968 --- /dev/null +++ b/atom/renderer/web_worker_observer.h @@ -0,0 +1,37 @@ +// Copyright (c) 2017 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_RENDERER_WEB_WORKER_OBSERVER_H_ +#define ATOM_RENDERER_WEB_WORKER_OBSERVER_H_ + +#include "base/macros.h" +#include "v8/include/v8.h" + +namespace atom { + +class AtomBindings; +class NodeBindings; + +// Watches for WebWorker and insert node integration to it. +class WebWorkerObserver { + public: + // Returns the WebWorkerObserver for current worker thread. + static WebWorkerObserver* GetCurrent(); + + void ContextCreated(v8::Local context); + void ContextWillDestroy(v8::Local context); + + private: + WebWorkerObserver(); + ~WebWorkerObserver(); + + std::unique_ptr node_bindings_; + std::unique_ptr atom_bindings_; + + DISALLOW_COPY_AND_ASSIGN(WebWorkerObserver); +}; + +} // namespace atom + +#endif // ATOM_RENDERER_WEB_WORKER_OBSERVER_H_ diff --git a/filenames.gypi b/filenames.gypi index 000e08c0a305..31d4fddd65fe 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -479,6 +479,8 @@ 'atom/renderer/node_array_buffer_bridge.h', 'atom/renderer/preferences_manager.cc', 'atom/renderer/preferences_manager.h', + 'atom/renderer/web_worker_observer.cc', + 'atom/renderer/web_worker_observer.h', 'atom/utility/atom_content_utility_client.cc', 'atom/utility/atom_content_utility_client.h', 'chromium_src/chrome/browser/browser_process.cc',