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,
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) {
......
......@@ -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);
......
......@@ -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
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