Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(443)

Unified Diff: chrome/browser/profiles/profile_dependency_manager.cc

Issue 13454032: Extract DependencyGraph from ProfileDependencyManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: added tests Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698