summaryrefslogtreecommitdiffstats
path: root/gin
diff options
context:
space:
mode:
authorsammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-09 05:57:29 +0000
committersammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-09 05:57:29 +0000
commitd5ef911ed9f13cdc6b3948dd1befb2b8c7ba394c (patch)
tree703307ab56cc57042c47534614e3b90ae195deef /gin
parent5655d80f8720212cf6901fcb1e62e0d5abb79e53 (diff)
downloadchromium_src-d5ef911ed9f13cdc6b3948dd1befb2b8c7ba394c.zip
chromium_src-d5ef911ed9f13cdc6b3948dd1befb2b8c7ba394c.tar.gz
chromium_src-d5ef911ed9f13cdc6b3948dd1befb2b8c7ba394c.tar.bz2
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
Diffstat (limited to 'gin')
-rw-r--r--gin/modules/module_registry.cc26
-rw-r--r--gin/modules/module_registry.h2
-rw-r--r--gin/modules/module_registry_unittest.cc37
3 files changed, 54 insertions, 11 deletions
diff --git a/gin/modules/module_registry.cc b/gin/modules/module_registry.cc
index 3712f1a..a92a5461 100644
--- a/gin/modules/module_registry.cc
+++ b/gin/modules/module_registry.cc
@@ -167,9 +167,7 @@ void ModuleRegistry::LoadModule(Isolate* isolate,
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;
+ waiting_callbacks_.insert(std::make_pair(id, callback));
unsatisfied_dependencies_.insert(id);
}
@@ -184,13 +182,21 @@ void ModuleRegistry::RegisterModule(Isolate* isolate,
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);
+ std::pair<LoadModuleCallbackMap::iterator, LoadModuleCallbackMap::iterator>
+ range = waiting_callbacks_.equal_range(id);
+ std::vector<LoadModuleCallback> callbacks;
+ callbacks.reserve(waiting_callbacks_.count(id));
+ for (LoadModuleCallbackMap::iterator it = range.first; it != range.second;
+ ++it) {
+ 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) {
diff --git a/gin/modules/module_registry.h b/gin/modules/module_registry.h
index 5775a34..439207e 100644
--- a/gin/modules/module_registry.h
+++ b/gin/modules/module_registry.h
@@ -77,7 +77,7 @@ class GIN_EXPORT ModuleRegistry {
private:
typedef ScopedVector<PendingModule> PendingModuleVector;
- typedef std::map<std::string, LoadModuleCallback> LoadModuleCallbackMap;
+ typedef std::multimap<std::string, LoadModuleCallback> LoadModuleCallbackMap;
explicit ModuleRegistry(v8::Isolate* isolate);
diff --git a/gin/modules/module_registry_unittest.cc b/gin/modules/module_registry_unittest.cc
index 0ffdc0c..77bf9f1 100644
--- a/gin/modules/module_registry_unittest.cc
+++ b/gin/modules/module_registry_unittest.cc
@@ -4,6 +4,7 @@
#include "gin/modules/module_registry.h"
+#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "gin/modules/module_registry_observer.h"
#include "gin/modules/module_runner_delegate.h"
@@ -54,6 +55,21 @@ class ModuleRegistryObserverImpl : public ModuleRegistryObserver {
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
typedef V8Test ModuleRegistryTest;
@@ -96,4 +112,25 @@ TEST_F(ModuleRegistryTest, ModuleRegistryObserverTest) {
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