diff options
author | sammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-09 05:57:29 +0000 |
---|---|---|
committer | sammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-09 05:57:29 +0000 |
commit | d5ef911ed9f13cdc6b3948dd1befb2b8c7ba394c (patch) | |
tree | 703307ab56cc57042c47534614e3b90ae195deef /gin | |
parent | 5655d80f8720212cf6901fcb1e62e0d5abb79e53 (diff) | |
download | chromium_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.cc | 26 | ||||
-rw-r--r-- | gin/modules/module_registry.h | 2 | ||||
-rw-r--r-- | gin/modules/module_registry_unittest.cc | 37 |
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 |