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

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

Issue 6766004: Create a ProfileDependencyManager to order ProfileKeyedService destruction. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix improper usage of static_cast<> in existing mac code. Created 9 years, 9 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
new file mode 100644
index 0000000000000000000000000000000000000000..4d21e5cfca178400993b76eeee9be0a45a53fcf4
--- /dev/null
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -0,0 +1,122 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/profiles/profile_dependency_manager.h"
+
+#include <algorithm>
+#include <deque>
+
+#include "chrome/browser/profiles/profile_keyed_service.h"
+#include "chrome/browser/profiles/profile_keyed_service_factory.h"
+#include "content/common/notification_service.h"
+
+class Profile;
+
+void ProfileDependencyManager::AddComponent(
+ ProfileKeyedServiceFactory* component) {
+ all_components_.push_back(component);
+ destruction_order_.clear();
+}
+
+void ProfileDependencyManager::RemoveComponent(
+ ProfileKeyedServiceFactory* 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();
+}
+
+void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended,
+ ProfileKeyedServiceFactory* dependee) {
+ edges_.insert(std::make_pair(depended, dependee));
+ destruction_order_.clear();
+}
+
+void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
+ if (destruction_order_.empty())
+ BuildDestructionOrder();
+
+ for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
+ destruction_order_.begin(); it != destruction_order_.end(); ++it) {
+ (*it)->ProfileShutdown(profile);
+ }
+
+ for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
+ destruction_order_.begin(); it != destruction_order_.end(); ++it) {
+ (*it)->ProfileDestroyed(profile);
+ }
+}
+
+// static
+ProfileDependencyManager* ProfileDependencyManager::GetInstance() {
+ return Singleton<ProfileDependencyManager>::get();
+}
+
+ProfileDependencyManager::ProfileDependencyManager() {}
+
+ProfileDependencyManager::~ProfileDependencyManager() {}
+
+void ProfileDependencyManager::BuildDestructionOrder() {
+ // Step 1: Build a set of nodes with no incoming edges.
+ std::deque<ProfileKeyedServiceFactory*> queue;
+ std::copy(all_components_.begin(),
+ all_components_.end(),
+ std::back_inserter(queue));
+
+ std::deque<ProfileKeyedServiceFactory*>::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<ProfileKeyedServiceFactory*> output;
+ EdgeMap edges(edges_);
+ while (!queue.empty()) {
+ ProfileKeyedServiceFactory* 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) {
+ ProfileKeyedServiceFactory* 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;
+}
« no previous file with comments | « chrome/browser/profiles/profile_dependency_manager.h ('k') | chrome/browser/profiles/profile_dependency_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698