summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gin/modules/module_registry.cc38
-rw-r--r--gin/modules/module_registry.h13
-rw-r--r--gin/modules/module_runner_delegate.cc12
-rw-r--r--gin/modules/module_runner_delegate.h3
-rw-r--r--mojo/apps/js/main.cc19
-rw-r--r--mojo/apps/js/main.js18
-rw-r--r--mojo/apps/js/mojo_runner_delegate.cc27
-rw-r--r--mojo/apps/js/mojo_runner_delegate.h3
-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.gyp4
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',
],
},
{