diff options
-rw-r--r-- | gin/modules/module_registry.cc | 38 | ||||
-rw-r--r-- | gin/modules/module_registry.h | 13 | ||||
-rw-r--r-- | gin/modules/module_runner_delegate.cc | 12 | ||||
-rw-r--r-- | gin/modules/module_runner_delegate.h | 3 | ||||
-rw-r--r-- | mojo/apps/js/main.cc | 19 | ||||
-rw-r--r-- | mojo/apps/js/main.js | 18 | ||||
-rw-r--r-- | mojo/apps/js/mojo_runner_delegate.cc | 27 | ||||
-rw-r--r-- | mojo/apps/js/mojo_runner_delegate.h | 3 | ||||
-rw-r--r-- | mojo/apps/js/threading.cc (renamed from mojo/apps/js/bootstrap.cc) | 18 | ||||
-rw-r--r-- | mojo/apps/js/threading.h (renamed from mojo/apps/js/bootstrap.h) | 11 | ||||
-rw-r--r-- | mojo/mojo.gyp | 4 |
11 files changed, 111 insertions, 55 deletions
diff --git a/gin/modules/module_registry.cc b/gin/modules/module_registry.cc index 6eba6f5..e9340db 100644 --- a/gin/modules/module_registry.cc +++ b/gin/modules/module_registry.cc @@ -135,6 +135,20 @@ void ModuleRegistry::AddPendingModule(Isolate* isolate, AttemptToLoad(isolate, pending.Pass()); } +void ModuleRegistry::LoadModule(Isolate* isolate, + const std::string& id, + LoadModuleCallback callback) { + if (available_modules_.find(id) != available_modules_.end()) { + // Should we call the callback asynchronously? + callback.Run(GetModule(isolate, id)); + return; + } + // Should we support multiple callers waiting on the same module? + DCHECK(waiting_callbacks_.find(id) == waiting_callbacks_.end()); + waiting_callbacks_[id] = callback; + unsatisfied_dependencies_.insert(id); +} + void ModuleRegistry::RegisterModule(Isolate* isolate, const std::string& id, v8::Handle<Value> module) { @@ -145,6 +159,14 @@ void ModuleRegistry::RegisterModule(Isolate* isolate, available_modules_.insert(id); v8::Handle<Object> modules = Local<Object>::New(isolate, modules_); modules->Set(StringToSymbol(isolate, id), module); + + LoadModuleCallbackMap::iterator it = waiting_callbacks_.find(id); + if (it == waiting_callbacks_.end()) + return; + LoadModuleCallback callback = it->second; + waiting_callbacks_.erase(it); + // Should we call the callback asynchronously? + callback.Run(module); } void ModuleRegistry::Detach(v8::Handle<Context> context) { @@ -169,14 +191,10 @@ void ModuleRegistry::Load(Isolate* isolate, scoped_ptr<PendingModule> pending) { if (!pending->id.empty() && available_modules_.count(pending->id)) return; // We've already loaded this module. - v8::Handle<Object> modules = Local<Object>::New(isolate, modules_); uint32_t argc = static_cast<uint32_t>(pending->dependencies.size()); std::vector<v8::Handle<Value> > argv(argc); - for (uint32_t i = 0; i < argc; ++i) { - v8::Handle<String> key = StringToSymbol(isolate, pending->dependencies[i]); - DCHECK(modules->HasOwnProperty(key)); - argv[i] = modules->Get(key); - } + for (uint32_t i = 0; i < argc; ++i) + argv[i] = GetModule(isolate, pending->dependencies[i]); v8::Handle<Value> module = Local<Value>::New(isolate, pending->factory); @@ -203,6 +221,14 @@ bool ModuleRegistry::AttemptToLoad(Isolate* isolate, return true; } +v8::Handle<v8::Value> ModuleRegistry::GetModule(v8::Isolate* isolate, + const std::string& id) { + v8::Handle<Object> modules = Local<Object>::New(isolate, modules_); + v8::Handle<String> key = StringToSymbol(isolate, id); + DCHECK(modules->HasOwnProperty(key)); + return modules->Get(key); +} + void ModuleRegistry::AttemptToLoadMoreModules(Isolate* isolate) { bool keep_trying = true; while (keep_trying) { diff --git a/gin/modules/module_registry.h b/gin/modules/module_registry.h index a7732c8..d3bed32 100644 --- a/gin/modules/module_registry.h +++ b/gin/modules/module_registry.h @@ -6,9 +6,11 @@ #define GIN_MODULES_MODULE_REGISTRY_H_ #include <list> +#include <map> #include <set> #include <string> +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/memory/scoped_ptr.h" #include "gin/per_context_data.h" @@ -30,6 +32,8 @@ struct PendingModule; // class ModuleRegistry : public ContextSupplement { public: + typedef base::Callback<void (v8::Handle<v8::Value>)> LoadModuleCallback; + virtual ~ModuleRegistry(); static ModuleRegistry* From(v8::Handle<v8::Context> context); @@ -46,6 +50,10 @@ class ModuleRegistry : public ContextSupplement { void AddPendingModule(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); + void LoadModule(v8::Isolate* isolate, + const std::string& id, + LoadModuleCallback callback); + // The caller must have already entered our context. void AttemptToLoadMoreModules(v8::Isolate* isolate); @@ -59,6 +67,7 @@ class ModuleRegistry : public ContextSupplement { private: typedef ScopedVector<PendingModule> PendingModuleVector; + typedef std::map<std::string, LoadModuleCallback> LoadModuleCallbackMap; explicit ModuleRegistry(v8::Isolate* isolate); @@ -73,9 +82,13 @@ class ModuleRegistry : public ContextSupplement { bool CheckDependencies(PendingModule* pending); bool AttemptToLoad(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); + v8::Handle<v8::Value> GetModule(v8::Isolate* isolate, const std::string& id); + std::set<std::string> available_modules_; std::set<std::string> unsatisfied_dependencies_; + LoadModuleCallbackMap waiting_callbacks_; + PendingModuleVector pending_modules_; v8::Persistent<v8::Object> modules_; diff --git a/gin/modules/module_runner_delegate.cc b/gin/modules/module_runner_delegate.cc index 9e0b762..9bf2863 100644 --- a/gin/modules/module_runner_delegate.cc +++ b/gin/modules/module_runner_delegate.cc @@ -21,6 +21,13 @@ void ModuleRunnerDelegate::AddBuiltinModule(const std::string& id, builtin_modules_[id] = templ; } +void ModuleRunnerDelegate::AttemptToLoadMoreModules(Runner* runner) { + ModuleRegistry* registry = ModuleRegistry::From(runner->context()); + registry->AttemptToLoadMoreModules(runner->isolate()); + module_provider_.AttempToLoadModules( + runner, registry->unsatisfied_dependencies()); +} + v8::Handle<v8::ObjectTemplate> ModuleRunnerDelegate::GetGlobalTemplate( Runner* runner) { v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(); @@ -42,10 +49,7 @@ void ModuleRunnerDelegate::DidCreateContext(Runner* runner) { } void ModuleRunnerDelegate::DidRunScript(Runner* runner) { - ModuleRegistry* registry = ModuleRegistry::From(runner->context()); - registry->AttemptToLoadMoreModules(runner->isolate()); - module_provider_.AttempToLoadModules( - runner, registry->unsatisfied_dependencies()); + AttemptToLoadMoreModules(runner); } } // namespace gin diff --git a/gin/modules/module_runner_delegate.h b/gin/modules/module_runner_delegate.h index d5523b8..1873d5a 100644 --- a/gin/modules/module_runner_delegate.h +++ b/gin/modules/module_runner_delegate.h @@ -32,6 +32,9 @@ class ModuleRunnerDelegate : public RunnerDelegate { // lazily. void AddBuiltinModule(const std::string& id, ModuleTemplateGetter templ); + protected: + void AttemptToLoadMoreModules(Runner* runner); + private: typedef std::map<std::string, ModuleTemplateGetter> BuiltinModuleMap; diff --git a/mojo/apps/js/main.cc b/mojo/apps/js/main.cc index 5a6842a..12ec34e 100644 --- a/mojo/apps/js/main.cc +++ b/mojo/apps/js/main.cc @@ -4,7 +4,6 @@ #include "base/message_loop/message_loop.h" #include "gin/public/isolate_holder.h" -#include "mojo/apps/js/bootstrap.h" #include "mojo/apps/js/mojo_runner_delegate.h" #include "mojo/common/bindings_support_impl.h" #include "mojo/public/system/core_cpp.h" @@ -23,18 +22,13 @@ namespace mojo { namespace apps { -void RunMojoJS(MojoHandle pipe) { - gin::IsolateHolder instance; - Bootstrap::SetInitialHandle(pipe); +void Start(MojoHandle pipe, const std::string& module) { + base::MessageLoop loop; + gin::IsolateHolder instance; MojoRunnerDelegate delegate; gin::Runner runner(&delegate, instance.isolate()); - - { - gin::Runner::Scope scope(&runner); - runner.Run("define(['mojo/apps/js/main'], function(main) {});", - "mojo.js"); - } + delegate.Start(&runner, pipe, module); base::MessageLoop::current()->Run(); } @@ -43,10 +37,11 @@ void RunMojoJS(MojoHandle pipe) { } // namespace mojo extern "C" MOJO_APPS_JS_EXPORT MojoResult CDECL MojoMain(MojoHandle pipe) { - base::MessageLoop loop; mojo::common::BindingsSupportImpl bindings_support; mojo::BindingsSupport::Set(&bindings_support); - mojo::apps::RunMojoJS(pipe); + + mojo::apps::Start(pipe, "mojo/apps/js/main"); + mojo::BindingsSupport::Set(NULL); return MOJO_RESULT_OK; } diff --git a/mojo/apps/js/main.js b/mojo/apps/js/main.js index a04048a..2592422 100644 --- a/mojo/apps/js/main.js +++ b/mojo/apps/js/main.js @@ -4,10 +4,10 @@ define([ "console", - "mojo/apps/js/bootstrap", + "mojo/apps/js/threading", "mojo/public/bindings/js/connector", "mojom/hello_world_service", -], function(console, bootstrap, connector, hello) { +], function(console, threading, connector, hello) { function HelloWorldClientImpl() { } @@ -18,12 +18,16 @@ define([ HelloWorldClientImpl.prototype.didReceiveGreeting = function(result) { console.log("DidReceiveGreeting from pipe: " + result); connection.close(); - bootstrap.quit(); + threading.quit(); }; - var connection = new connector.Connection(bootstrap.initialHandle, - HelloWorldClientImpl, - hello.HelloWorldServiceProxy); + var connection = null; - connection.remote.greeting("hello, world!"); + return function(handle) { + connection = new connector.Connection(handle, + HelloWorldClientImpl, + hello.HelloWorldServiceProxy); + + connection.remote.greeting("hello, world!"); + }; }); diff --git a/mojo/apps/js/mojo_runner_delegate.cc b/mojo/apps/js/mojo_runner_delegate.cc index 610ede4..c74bf50 100644 --- a/mojo/apps/js/mojo_runner_delegate.cc +++ b/mojo/apps/js/mojo_runner_delegate.cc @@ -4,11 +4,13 @@ #include "mojo/apps/js/mojo_runner_delegate.h" +#include "base/bind.h" #include "base/path_service.h" +#include "gin/converter.h" #include "gin/modules/console.h" #include "gin/modules/module_registry.h" #include "gin/try_catch.h" -#include "mojo/apps/js/bootstrap.h" +#include "mojo/apps/js/threading.h" #include "mojo/public/bindings/js/core.h" #include "mojo/public/bindings/js/support.h" @@ -27,11 +29,22 @@ std::vector<base::FilePath> GetModuleSearchPaths() { return search_paths; } +void StartCallback(base::WeakPtr<gin::Runner> runner, + MojoHandle pipe, + v8::Handle<v8::Value> module) { + v8::Isolate* isolate = runner->isolate(); + v8::Handle<v8::Function> start; + CHECK(gin::ConvertFromV8(isolate, module, &start)); + + v8::Handle<v8::Value> args[] = { gin::ConvertToV8(isolate, pipe) }; + runner->Call(start, runner->global(), 1, args); +} + } // namespace MojoRunnerDelegate::MojoRunnerDelegate() : ModuleRunnerDelegate(GetModuleSearchPaths()) { - AddBuiltinModule(Bootstrap::kModuleName, Bootstrap::GetTemplate); + AddBuiltinModule(Threading::kModuleName, Threading::GetTemplate); AddBuiltinModule(gin::Console::kModuleName, gin::Console::GetTemplate); AddBuiltinModule(js::Core::kModuleName, js::Core::GetTemplate); AddBuiltinModule(js::Support::kModuleName, js::Support::GetTemplate); @@ -40,6 +53,16 @@ MojoRunnerDelegate::MojoRunnerDelegate() MojoRunnerDelegate::~MojoRunnerDelegate() { } +void MojoRunnerDelegate::Start(gin::Runner* runner, + MojoHandle pipe, + const std::string& module) { + gin::Runner::Scope scope(runner); + gin::ModuleRegistry* registry = gin::ModuleRegistry::From(runner->context()); + registry->LoadModule(runner->isolate(), module, + base::Bind(StartCallback, runner->GetWeakPtr(), pipe)); + AttemptToLoadMoreModules(runner); +} + void MojoRunnerDelegate::UnhandledException(gin::Runner* runner, gin::TryCatch& try_catch) { gin::ModuleRunnerDelegate::UnhandledException(runner, try_catch); diff --git a/mojo/apps/js/mojo_runner_delegate.h b/mojo/apps/js/mojo_runner_delegate.h index 899ef01..aa1393f 100644 --- a/mojo/apps/js/mojo_runner_delegate.h +++ b/mojo/apps/js/mojo_runner_delegate.h @@ -7,6 +7,7 @@ #include "base/compiler_specific.h" #include "gin/modules/module_runner_delegate.h" +#include "mojo/public/system/core.h" namespace mojo { namespace apps { @@ -16,6 +17,8 @@ class MojoRunnerDelegate : public gin::ModuleRunnerDelegate { MojoRunnerDelegate(); virtual ~MojoRunnerDelegate(); + void Start(gin::Runner* runner, MojoHandle pipe, const std::string& module); + private: // From ModuleRunnerDelegate: virtual void UnhandledException(gin::Runner* runner, diff --git a/mojo/apps/js/bootstrap.cc b/mojo/apps/js/threading.cc index 540309f..09536cd 100644 --- a/mojo/apps/js/bootstrap.cc +++ b/mojo/apps/js/threading.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "mojo/apps/js/bootstrap.h" +#include "mojo/apps/js/threading.h" #include "base/bind.h" #include "base/message_loop/message_loop.h" @@ -19,15 +19,13 @@ void Quit() { base::MessageLoop::current()->QuitNow(); } -MojoHandle g_initial_handle = MOJO_HANDLE_INVALID; - gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin }; } // namespace -const char Bootstrap::kModuleName[] = "mojo/apps/js/bootstrap"; +const char Threading::kModuleName[] = "mojo/apps/js/threading"; -v8::Local<v8::ObjectTemplate> Bootstrap::GetTemplate(v8::Isolate* isolate) { +v8::Local<v8::ObjectTemplate> Threading::GetTemplate(v8::Isolate* isolate) { gin::PerIsolateData* data = gin::PerIsolateData::From(isolate); v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate( &g_wrapper_info); @@ -36,21 +34,11 @@ v8::Local<v8::ObjectTemplate> Bootstrap::GetTemplate(v8::Isolate* isolate) { templ = v8::ObjectTemplate::New(); templ->Set(gin::StringToSymbol(isolate, "quit"), gin::CreateFunctionTemplate(isolate, base::Bind(Quit))); - - // Don't forget to call SetInitialHandle before getting the template. - DCHECK(g_initial_handle != MOJO_HANDLE_INVALID); - templ->Set(gin::StringToSymbol(isolate, "initialHandle"), - gin::ConvertToV8(isolate, g_initial_handle)); - data->SetObjectTemplate(&g_wrapper_info, templ); } return templ; } -void Bootstrap::SetInitialHandle(MojoHandle pipe) { - g_initial_handle = pipe; -} - } // namespace apps } // namespace mojo diff --git a/mojo/apps/js/bootstrap.h b/mojo/apps/js/threading.h index 4355760a..356d1e7 100644 --- a/mojo/apps/js/bootstrap.h +++ b/mojo/apps/js/threading.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef MOJO_APPS_JS_BOOTSTRAP_H_ -#define MOJO_APPS_JS_BOOTSTRAP_H_ +#ifndef MOJO_APPS_JS_THREADING_H_ +#define MOJO_APPS_JS_THREADING_H_ #include "mojo/public/system/core.h" #include "v8/include/v8.h" @@ -11,16 +11,13 @@ namespace mojo { namespace apps { -class Bootstrap { +class Threading { public: static const char kModuleName[]; static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate); - - // Must be called before the first call to GetTemplate. - static void SetInitialHandle(MojoHandle handle); }; } // namespace apps } // namespace mojo -#endif // MOJO_APPS_JS_BOOTSTRAP_H_ +#endif // MOJO_APPS_JS_THREADING_H_ diff --git a/mojo/mojo.gyp b/mojo/mojo.gyp index 9fb5389..32604a3 100644 --- a/mojo/mojo.gyp +++ b/mojo/mojo.gyp @@ -306,11 +306,11 @@ 'mojo_system', ], 'sources': [ - 'apps/js/bootstrap.cc', - 'apps/js/bootstrap.h', 'apps/js/main.cc', 'apps/js/mojo_runner_delegate.cc', 'apps/js/mojo_runner_delegate.h', + 'apps/js/threading.cc', + 'apps/js/threading.h', ], }, { |