Index: chrome/browser/profiles/profile_dependency_manager.cc |
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc |
index 0a3aea510d7a0e2e7ca8b4efe8b89ec533958790..abd1ffe4b5a6e60b87eed940b50a82a71a601846 100644 |
--- a/chrome/browser/profiles/profile_dependency_manager.cc |
+++ b/chrome/browser/profiles/profile_dependency_manager.cc |
@@ -130,34 +130,17 @@ class Profile; |
void ProfileDependencyManager::AddComponent( |
ProfileKeyedBaseFactory* component) { |
- all_components_.push_back(component); |
- destruction_order_.clear(); |
+ dependency_graph_.AddNode(component); |
} |
void ProfileDependencyManager::RemoveComponent( |
ProfileKeyedBaseFactory* component) { |
- all_components_.erase(std::remove(all_components_.begin(), |
- all_components_.end(), |
- component), |
- all_components_.end()); |
- |
- // Remove all dependency edges that contain this component. |
- EdgeMap::iterator it = edges_.begin(); |
- while (it != edges_.end()) { |
- EdgeMap::iterator temp = it; |
- ++it; |
- |
- if (temp->first == component || temp->second == component) |
- edges_.erase(temp); |
- } |
- |
- destruction_order_.clear(); |
+ dependency_graph_.RemoveNode(component); |
} |
void ProfileDependencyManager::AddEdge(ProfileKeyedBaseFactory* depended, |
ProfileKeyedBaseFactory* dependee) { |
- edges_.insert(std::make_pair(depended, dependee)); |
- destruction_order_.clear(); |
+ dependency_graph_.AddEdge(depended, dependee); |
} |
void ProfileDependencyManager::CreateProfileServices(Profile* profile, |
@@ -171,35 +154,48 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile, |
AssertFactoriesBuilt(); |
- if (destruction_order_.empty()) |
- BuildDestructionOrder(profile); |
+ std::vector<DependencyNode*> construction_order; |
+ if (!dependency_graph_.GetConstructionOrder(&construction_order)) { |
+ NOTREACHED(); |
+ } |
+ |
+#ifndef NDEBUG |
+ DumpProfileDependencies(profile); |
+#endif |
+ |
+ for (size_t i = 0; i < construction_order.size(); i++) { |
+ ProfileKeyedBaseFactory* factory = |
+ static_cast<ProfileKeyedBaseFactory*>(construction_order[i]); |
- // Iterate in reverse destruction order for creation. |
- for (std::vector<ProfileKeyedBaseFactory*>::reverse_iterator rit = |
- destruction_order_.rbegin(); rit != destruction_order_.rend(); |
- ++rit) { |
if (!profile->IsOffTheRecord()) { |
// We only register preferences on normal profiles because the incognito |
// profile shares the pref service with the normal one. |
- (*rit)->RegisterUserPrefsOnProfile(profile); |
+ factory->RegisterUserPrefsOnProfile(profile); |
} |
- if (is_testing_profile && (*rit)->ServiceIsNULLWhileTesting()) { |
- (*rit)->SetEmptyTestingFactory(profile); |
- } else if ((*rit)->ServiceIsCreatedWithProfile()) { |
+ if (is_testing_profile && factory->ServiceIsNULLWhileTesting()) { |
+ factory->SetEmptyTestingFactory(profile); |
+ } else if (factory->ServiceIsCreatedWithProfile()) { |
// Create the service. |
- (*rit)->CreateServiceNow(profile); |
+ factory->CreateServiceNow(profile); |
} |
} |
} |
void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { |
- if (destruction_order_.empty()) |
- BuildDestructionOrder(profile); |
+ std::vector<DependencyNode*> destruction_order; |
+ if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { |
+ NOTREACHED(); |
+ } |
- for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it = |
- destruction_order_.begin(); it != destruction_order_.end(); ++it) { |
- (*it)->ProfileShutdown(profile); |
+#ifndef NDEBUG |
+ DumpProfileDependencies(profile); |
+#endif |
+ |
+ for (size_t i = 0; i < destruction_order.size(); i++) { |
+ ProfileKeyedBaseFactory* factory = |
+ static_cast<ProfileKeyedBaseFactory*>(destruction_order[i]); |
+ factory->ProfileShutdown(profile); |
} |
#ifndef NDEBUG |
@@ -207,9 +203,10 @@ void ProfileDependencyManager::DestroyProfileServices(Profile* profile) { |
dead_profile_pointers_.insert(profile); |
#endif |
- for (std::vector<ProfileKeyedBaseFactory*>::const_iterator it = |
- destruction_order_.begin(); it != destruction_order_.end(); ++it) { |
- (*it)->ProfileDestroyed(profile); |
+ for (size_t i = 0; i < destruction_order.size(); i++) { |
+ ProfileKeyedBaseFactory* factory = |
+ static_cast<ProfileKeyedBaseFactory*>(destruction_order[i]); |
+ factory->ProfileDestroyed(profile); |
} |
} |
@@ -229,8 +226,7 @@ ProfileDependencyManager* ProfileDependencyManager::GetInstance() { |
return Singleton<ProfileDependencyManager>::get(); |
} |
-ProfileDependencyManager::ProfileDependencyManager() |
- : built_factories_(false) { |
+ProfileDependencyManager::ProfileDependencyManager() : built_factories_(false) { |
} |
ProfileDependencyManager::~ProfileDependencyManager() {} |
@@ -384,113 +380,25 @@ void ProfileDependencyManager::AssertFactoriesBuilt() { |
built_factories_ = true; |
} |
-void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) { |
-#if !defined(NDEBUG) |
+#ifndef NDEBUG |
+namespace { |
+ |
+std::string ProfileKeyedBaseFactoryGetNodeName(DependencyNode* node) { |
+ return static_cast<ProfileKeyedBaseFactory*>(node)->name(); |
+} |
+ |
+} // namespace |
+ |
+void ProfileDependencyManager::DumpProfileDependencies(Profile* profile) { |
// Whenever we try to build a destruction ordering, we should also dump a |
// dependency graph to "/path/to/profile/profile-dependencies.dot". |
if (CommandLine::ForCurrentProcess()->HasSwitch( |
switches::kDumpProfileDependencyGraph)) { |
base::FilePath dot_file = |
profile->GetPath().AppendASCII("profile-dependencies.dot"); |
- std::string contents = DumpGraphvizDependency(); |
+ std::string contents = dependency_graph_.DumpAsGraphviz( |
+ "Profile", base::Bind(&ProfileKeyedBaseFactoryGetNodeName)); |
file_util::WriteFile(dot_file, contents.c_str(), contents.size()); |
} |
-#endif |
- |
- // Step 1: Build a set of nodes with no incoming edges. |
- std::deque<ProfileKeyedBaseFactory*> queue; |
- std::copy(all_components_.begin(), |
- all_components_.end(), |
- std::back_inserter(queue)); |
- |
- std::deque<ProfileKeyedBaseFactory*>::iterator queue_end = queue.end(); |
- for (EdgeMap::const_iterator it = edges_.begin(); |
- it != edges_.end(); ++it) { |
- queue_end = std::remove(queue.begin(), queue_end, it->second); |
- } |
- queue.erase(queue_end, queue.end()); |
- |
- // Step 2: Do the Kahn topological sort. |
- std::vector<ProfileKeyedBaseFactory*> output; |
- EdgeMap edges(edges_); |
- while (!queue.empty()) { |
- ProfileKeyedBaseFactory* node = queue.front(); |
- queue.pop_front(); |
- output.push_back(node); |
- |
- std::pair<EdgeMap::iterator, EdgeMap::iterator> range = |
- edges.equal_range(node); |
- EdgeMap::iterator it = range.first; |
- while (it != range.second) { |
- ProfileKeyedBaseFactory* dest = it->second; |
- EdgeMap::iterator temp = it; |
- it++; |
- edges.erase(temp); |
- |
- bool has_incoming_edges = false; |
- for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) { |
- if (jt->second == dest) { |
- has_incoming_edges = true; |
- break; |
- } |
- } |
- |
- if (!has_incoming_edges) |
- queue.push_back(dest); |
- } |
- } |
- |
- if (edges.size()) { |
- NOTREACHED() << "Dependency graph has a cycle. We are doomed."; |
- } |
- |
- std::reverse(output.begin(), output.end()); |
- destruction_order_ = output; |
} |
- |
-#if !defined(NDEBUG) |
- |
-std::string ProfileDependencyManager::DumpGraphvizDependency() { |
- std::string result("digraph {\n"); |
- |
- // Make a copy of all components. |
- std::deque<ProfileKeyedBaseFactory*> components; |
- std::copy(all_components_.begin(), |
- all_components_.end(), |
- std::back_inserter(components)); |
- |
- // State all dependencies and remove |second| so we don't generate an |
- // implicit dependency on the Profile hard coded node. |
- std::deque<ProfileKeyedBaseFactory*>::iterator components_end = |
- components.end(); |
- result.append(" /* Dependencies */\n"); |
- for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) { |
- result.append(" "); |
- result.append(it->second->name()); |
- result.append(" -> "); |
- result.append(it->first->name()); |
- result.append(";\n"); |
- |
- components_end = std::remove(components.begin(), components_end, |
- it->second); |
- } |
- components.erase(components_end, components.end()); |
- |
- // Every node that doesn't depend on anything else will implicitly depend on |
- // the Profile. |
- result.append("\n /* Toplevel attachments */\n"); |
- for (std::deque<ProfileKeyedBaseFactory*>::const_iterator it = |
- components.begin(); it != components.end(); ++it) { |
- result.append(" "); |
- result.append((*it)->name()); |
- result.append(" -> Profile;\n"); |
- } |
- |
- result.append("\n /* Toplevel profile */\n"); |
- result.append(" Profile [shape=box];\n"); |
- |
- result.append("}\n"); |
- return result; |
-} |
- |
-#endif |
+#endif // NDEBUG |