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

Side by Side 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, 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/profiles/profile_dependency_manager.h"
6
7 #include <algorithm>
8 #include <deque>
9
10 #include "chrome/browser/profiles/profile_keyed_service.h"
11 #include "chrome/browser/profiles/profile_keyed_service_factory.h"
12 #include "content/common/notification_service.h"
13
14 class Profile;
15
16 void ProfileDependencyManager::AddComponent(
17 ProfileKeyedServiceFactory* component) {
18 all_components_.push_back(component);
19 destruction_order_.clear();
20 }
21
22 void ProfileDependencyManager::RemoveComponent(
23 ProfileKeyedServiceFactory* component) {
24 all_components_.erase(std::remove(all_components_.begin(),
25 all_components_.end(),
26 component),
27 all_components_.end());
28
29 // Remove all dependency edges that contain this component.
30 EdgeMap::iterator it = edges_.begin();
31 while (it != edges_.end()) {
32 EdgeMap::iterator temp = it;
33 ++it;
34
35 if (temp->first == component || temp->second == component)
36 edges_.erase(temp);
37 }
38
39 destruction_order_.clear();
40 }
41
42 void ProfileDependencyManager::AddEdge(ProfileKeyedServiceFactory* depended,
43 ProfileKeyedServiceFactory* dependee) {
44 edges_.insert(std::make_pair(depended, dependee));
45 destruction_order_.clear();
46 }
47
48 void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
49 if (destruction_order_.empty())
50 BuildDestructionOrder();
51
52 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
53 destruction_order_.begin(); it != destruction_order_.end(); ++it) {
54 (*it)->ProfileShutdown(profile);
55 }
56
57 for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
58 destruction_order_.begin(); it != destruction_order_.end(); ++it) {
59 (*it)->ProfileDestroyed(profile);
60 }
61 }
62
63 // static
64 ProfileDependencyManager* ProfileDependencyManager::GetInstance() {
65 return Singleton<ProfileDependencyManager>::get();
66 }
67
68 ProfileDependencyManager::ProfileDependencyManager() {}
69
70 ProfileDependencyManager::~ProfileDependencyManager() {}
71
72 void ProfileDependencyManager::BuildDestructionOrder() {
73 // Step 1: Build a set of nodes with no incoming edges.
74 std::deque<ProfileKeyedServiceFactory*> queue;
75 std::copy(all_components_.begin(),
76 all_components_.end(),
77 std::back_inserter(queue));
78
79 std::deque<ProfileKeyedServiceFactory*>::iterator queue_end = queue.end();
80 for (EdgeMap::const_iterator it = edges_.begin();
81 it != edges_.end(); ++it) {
82 queue_end = std::remove(queue.begin(), queue_end, it->second);
83 }
84 queue.erase(queue_end, queue.end());
85
86 // Step 2: Do the Kahn topological sort.
87 std::vector<ProfileKeyedServiceFactory*> output;
88 EdgeMap edges(edges_);
89 while (!queue.empty()) {
90 ProfileKeyedServiceFactory* node = queue.front();
91 queue.pop_front();
92 output.push_back(node);
93
94 std::pair<EdgeMap::iterator, EdgeMap::iterator> range =
95 edges.equal_range(node);
96 EdgeMap::iterator it = range.first;
97 while (it != range.second) {
98 ProfileKeyedServiceFactory* dest = it->second;
99 EdgeMap::iterator temp = it;
100 it++;
101 edges.erase(temp);
102
103 bool has_incoming_edges = false;
104 for (EdgeMap::iterator jt = edges.begin(); jt != edges.end(); ++jt) {
105 if (jt->second == dest) {
106 has_incoming_edges = true;
107 break;
108 }
109 }
110
111 if (!has_incoming_edges)
112 queue.push_back(dest);
113 }
114 }
115
116 if (edges.size()) {
117 NOTREACHED() << "Dependency graph has a cycle. We are doomed.";
118 }
119
120 std::reverse(output.begin(), output.end());
121 destruction_order_ = output;
122 }
OLDNEW
« 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