Commit d5ef911e authored by sammc@chromium.org's avatar sammc@chromium.org

Gin: Allow multiple callers to wait for the same module in ModuleRegistry.

BUG=391888

Review URL: https://codereview.chromium.org/373973003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281966 0039d316-1c4b-4281-b951-d872f2087c98
parent 5655d80f
...@@ -167,9 +167,7 @@ void ModuleRegistry::LoadModule(Isolate* isolate, ...@@ -167,9 +167,7 @@ void ModuleRegistry::LoadModule(Isolate* isolate,
callback.Run(GetModule(isolate, id)); callback.Run(GetModule(isolate, id));
return; return;
} }
// Should we support multiple callers waiting on the same module? waiting_callbacks_.insert(std::make_pair(id, callback));
DCHECK(waiting_callbacks_.find(id) == waiting_callbacks_.end());
waiting_callbacks_[id] = callback;
unsatisfied_dependencies_.insert(id); unsatisfied_dependencies_.insert(id);
} }
...@@ -184,13 +182,21 @@ void ModuleRegistry::RegisterModule(Isolate* isolate, ...@@ -184,13 +182,21 @@ void ModuleRegistry::RegisterModule(Isolate* isolate,
v8::Handle<Object> modules = Local<Object>::New(isolate, modules_); v8::Handle<Object> modules = Local<Object>::New(isolate, modules_);
modules->Set(StringToSymbol(isolate, id), module); modules->Set(StringToSymbol(isolate, id), module);
LoadModuleCallbackMap::iterator it = waiting_callbacks_.find(id); std::pair<LoadModuleCallbackMap::iterator, LoadModuleCallbackMap::iterator>
if (it == waiting_callbacks_.end()) range = waiting_callbacks_.equal_range(id);
return; std::vector<LoadModuleCallback> callbacks;
LoadModuleCallback callback = it->second; callbacks.reserve(waiting_callbacks_.count(id));
waiting_callbacks_.erase(it); for (LoadModuleCallbackMap::iterator it = range.first; it != range.second;
// Should we call the callback asynchronously? ++it) {
callback.Run(module); callbacks.push_back(it->second);
}
waiting_callbacks_.erase(range.first, range.second);
for (std::vector<LoadModuleCallback>::iterator it = callbacks.begin();
it != callbacks.end();
++it) {
// Should we call the callback asynchronously?
it->Run(module);
}
} }
bool ModuleRegistry::CheckDependencies(PendingModule* pending) { bool ModuleRegistry::CheckDependencies(PendingModule* pending) {
......
...@@ -77,7 +77,7 @@ class GIN_EXPORT ModuleRegistry { ...@@ -77,7 +77,7 @@ class GIN_EXPORT ModuleRegistry {
private: private:
typedef ScopedVector<PendingModule> PendingModuleVector; typedef ScopedVector<PendingModule> PendingModuleVector;
typedef std::map<std::string, LoadModuleCallback> LoadModuleCallbackMap; typedef std::multimap<std::string, LoadModuleCallback> LoadModuleCallbackMap;
explicit ModuleRegistry(v8::Isolate* isolate); explicit ModuleRegistry(v8::Isolate* isolate);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "gin/modules/module_registry.h" #include "gin/modules/module_registry.h"
#include "base/bind.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "gin/modules/module_registry_observer.h" #include "gin/modules/module_registry_observer.h"
#include "gin/modules/module_runner_delegate.h" #include "gin/modules/module_runner_delegate.h"
...@@ -54,6 +55,21 @@ class ModuleRegistryObserverImpl : public ModuleRegistryObserver { ...@@ -54,6 +55,21 @@ class ModuleRegistryObserverImpl : public ModuleRegistryObserver {
DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl); DISALLOW_COPY_AND_ASSIGN(ModuleRegistryObserverImpl);
}; };
void NestedCallback(v8::Handle<v8::Value> value) {
FAIL() << "Should not be called";
}
void OnModuleLoaded(TestHelper* helper,
v8::Isolate* isolate,
int64_t* counter,
v8::Handle<v8::Value> value) {
ASSERT_TRUE(value->IsNumber());
v8::Handle<v8::Integer> int_value = v8::Handle<v8::Integer>::Cast(value);
*counter += int_value->Value();
ModuleRegistry::From(helper->runner->GetContextHolder()->context())
->LoadModule(isolate, "two", base::Bind(NestedCallback));
}
} // namespace } // namespace
typedef V8Test ModuleRegistryTest; typedef V8Test ModuleRegistryTest;
...@@ -96,4 +112,25 @@ TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) { ...@@ -96,4 +112,25 @@ TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) {
EXPECT_EQ("dep2", observer.dependencies()[1]); EXPECT_EQ("dep2", observer.dependencies()[1]);
} }
// Verifies that multiple LoadModule calls for the same module are handled
// correctly.
TEST_F(ModuleRegistryTest, LoadModuleTest) {
TestHelper helper(instance_->isolate());
int64_t counter = 0;
std::string source =
"define('one', [], function() {"
" return 1;"
"});";
ModuleRegistry::LoadModuleCallback callback =
base::Bind(OnModuleLoaded, &helper, instance_->isolate(), &counter);
for (int i = 0; i < 3; i++) {
ModuleRegistry::From(helper.runner->GetContextHolder()->context())
->LoadModule(instance_->isolate(), "one", callback);
}
EXPECT_EQ(0, counter);
helper.runner->Run(source, "script");
EXPECT_EQ(3, counter);
}
} // namespace gin } // namespace gin
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment