| OLD | NEW |
| (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 } |
| OLD | NEW |