| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/keyed_service/core/dependency_manager.h" | 5 #include "components/keyed_service/core/dependency_manager.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/supports_user_data.h" | 9 #include "base/supports_user_data.h" |
| 10 #include "components/keyed_service/core/keyed_service_base_factory.h" | 10 #include "components/keyed_service/core/keyed_service_base_factory.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 void DependencyManager::RemoveComponent(KeyedServiceBaseFactory* component) { | 27 void DependencyManager::RemoveComponent(KeyedServiceBaseFactory* component) { |
| 28 dependency_graph_.RemoveNode(component); | 28 dependency_graph_.RemoveNode(component); |
| 29 } | 29 } |
| 30 | 30 |
| 31 void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended, | 31 void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended, |
| 32 KeyedServiceBaseFactory* dependee) { | 32 KeyedServiceBaseFactory* dependee) { |
| 33 dependency_graph_.AddEdge(depended, dependee); | 33 dependency_graph_.AddEdge(depended, dependee); |
| 34 } | 34 } |
| 35 | 35 |
| 36 void DependencyManager::RegisterPrefsForServices( | 36 void DependencyManager::RegisterPrefsForServices( |
| 37 const base::SupportsUserData* context, | 37 base::SupportsUserData* context, |
| 38 user_prefs::PrefRegistrySyncable* pref_registry) { | 38 user_prefs::PrefRegistrySyncable* pref_registry) { |
| 39 std::vector<DependencyNode*> construction_order; | 39 std::vector<DependencyNode*> construction_order; |
| 40 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { | 40 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { |
| 41 NOTREACHED(); | 41 NOTREACHED(); |
| 42 } | 42 } |
| 43 | 43 |
| 44 for (const auto& dependency_node : construction_order) { | 44 for (const auto& dependency_node : construction_order) { |
| 45 KeyedServiceBaseFactory* factory = | 45 KeyedServiceBaseFactory* factory = |
| 46 static_cast<KeyedServiceBaseFactory*>(dependency_node); | 46 static_cast<KeyedServiceBaseFactory*>(dependency_node); |
| 47 factory->RegisterPrefsIfNecessaryForContext(context, pref_registry); | 47 base::SupportsUserData* typed_context = factory->GetTypedContext(context); |
| 48 factory->RegisterPrefsIfNecessaryForContext(typed_context, pref_registry); |
| 48 } | 49 } |
| 49 } | 50 } |
| 50 | 51 |
| 51 void DependencyManager::CreateContextServices(base::SupportsUserData* context, | 52 void DependencyManager::CreateContextServices(base::SupportsUserData* context, |
| 52 bool is_testing_context) { | 53 bool is_testing_context) { |
| 53 #ifndef NDEBUG | 54 #ifndef NDEBUG |
| 54 MarkContextLiveForTesting(context); | 55 MarkContextLiveForTesting(context); |
| 55 #endif | 56 #endif |
| 56 | 57 |
| 57 std::vector<DependencyNode*> construction_order; | 58 std::vector<DependencyNode*> construction_order; |
| 58 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { | 59 if (!dependency_graph_.GetConstructionOrder(&construction_order)) { |
| 59 NOTREACHED(); | 60 NOTREACHED(); |
| 60 } | 61 } |
| 61 | 62 |
| 62 #ifndef NDEBUG | 63 #ifndef NDEBUG |
| 63 DumpContextDependencies(context); | 64 DumpContextDependencies(context); |
| 64 #endif | 65 #endif |
| 65 | 66 |
| 66 for (const auto& dependency_node : construction_order) { | 67 for (const auto& dependency_node : construction_order) { |
| 67 KeyedServiceBaseFactory* factory = | 68 KeyedServiceBaseFactory* factory = |
| 68 static_cast<KeyedServiceBaseFactory*>(dependency_node); | 69 static_cast<KeyedServiceBaseFactory*>(dependency_node); |
| 70 base::SupportsUserData* typed_context = factory->GetTypedContext(context); |
| 69 if (is_testing_context && factory->ServiceIsNULLWhileTesting() && | 71 if (is_testing_context && factory->ServiceIsNULLWhileTesting() && |
| 70 !factory->HasTestingFactory(context)) { | 72 !factory->HasTestingFactory(typed_context)) { |
| 71 factory->SetEmptyTestingFactory(context); | 73 factory->SetEmptyTestingFactory(typed_context); |
| 72 } else if (factory->ServiceIsCreatedWithContext()) { | 74 } else if (factory->ServiceIsCreatedWithContext()) { |
| 73 factory->CreateServiceNow(context); | 75 factory->CreateServiceNow(typed_context); |
| 74 } | 76 } |
| 75 } | 77 } |
| 76 } | 78 } |
| 77 | 79 |
| 78 void DependencyManager::DestroyContextServices( | 80 void DependencyManager::DestroyContextServices( |
| 79 base::SupportsUserData* context) { | 81 base::SupportsUserData* context) { |
| 80 std::vector<DependencyNode*> destruction_order; | 82 std::vector<DependencyNode*> destruction_order; |
| 81 if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { | 83 if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { |
| 82 NOTREACHED(); | 84 NOTREACHED(); |
| 83 } | 85 } |
| 84 | 86 |
| 85 #ifndef NDEBUG | 87 #ifndef NDEBUG |
| 86 DumpContextDependencies(context); | 88 DumpContextDependencies(context); |
| 87 #endif | 89 #endif |
| 88 | 90 |
| 89 for (const auto& dependency_node : destruction_order) { | 91 for (const auto& dependency_node : destruction_order) { |
| 90 KeyedServiceBaseFactory* factory = | 92 KeyedServiceBaseFactory* factory = |
| 91 static_cast<KeyedServiceBaseFactory*>(dependency_node); | 93 static_cast<KeyedServiceBaseFactory*>(dependency_node); |
| 92 factory->ContextShutdown(context); | 94 base::SupportsUserData* typed_context = factory->GetTypedContext(context); |
| 95 factory->ContextShutdown(typed_context); |
| 93 } | 96 } |
| 94 | 97 |
| 95 #ifndef NDEBUG | 98 #ifndef NDEBUG |
| 96 // The context is now dead to the rest of the program. | 99 // The context is now dead to the rest of the program. |
| 97 dead_context_pointers_.insert(context); | 100 dead_context_pointers_.insert(context); |
| 98 #endif | 101 #endif |
| 99 | 102 |
| 100 for (const auto& dependency_node : destruction_order) { | 103 for (const auto& dependency_node : destruction_order) { |
| 101 KeyedServiceBaseFactory* factory = | 104 KeyedServiceBaseFactory* factory = |
| 102 static_cast<KeyedServiceBaseFactory*>(dependency_node); | 105 static_cast<KeyedServiceBaseFactory*>(dependency_node); |
| 103 factory->ContextDestroyed(context); | 106 base::SupportsUserData* typed_context = factory->GetTypedContext(context); |
| 107 factory->ContextDestroyed(typed_context); |
| 104 } | 108 } |
| 105 } | 109 } |
| 106 | 110 |
| 107 #ifndef NDEBUG | 111 #ifndef NDEBUG |
| 108 void DependencyManager::AssertContextWasntDestroyed( | 112 void DependencyManager::AssertContextWasntDestroyed( |
| 109 const base::SupportsUserData* context) { | 113 base::SupportsUserData* context) { |
| 110 if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) { | 114 if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) { |
| 111 NOTREACHED() << "Attempted to access a context that was ShutDown(). " | 115 NOTREACHED() << "Attempted to access a context that was ShutDown(). " |
| 112 << "This is most likely a heap smasher in progress. After " | 116 << "This is most likely a heap smasher in progress. After " |
| 113 << "KeyedService::Shutdown() completes, your service MUST " | 117 << "KeyedService::Shutdown() completes, your service MUST " |
| 114 << "NOT refer to depended services again."; | 118 << "NOT refer to depended services again."; |
| 115 } | 119 } |
| 116 } | 120 } |
| 117 | 121 |
| 118 void DependencyManager::MarkContextLiveForTesting( | 122 void DependencyManager::MarkContextLiveForTesting( |
| 119 const base::SupportsUserData* context) { | 123 base::SupportsUserData* context) { |
| 120 dead_context_pointers_.erase(context); | 124 dead_context_pointers_.erase(context); |
| 121 } | 125 } |
| 122 | 126 |
| 123 namespace { | 127 namespace { |
| 124 | 128 |
| 125 std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) { | 129 std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) { |
| 126 return static_cast<KeyedServiceBaseFactory*>(node)->name(); | 130 return static_cast<KeyedServiceBaseFactory*>(node)->name(); |
| 127 } | 131 } |
| 128 | 132 |
| 129 } // namespace | 133 } // namespace |
| 130 | 134 |
| 131 void DependencyManager::DumpDependenciesAsGraphviz( | 135 void DependencyManager::DumpDependenciesAsGraphviz( |
| 132 const std::string& top_level_name, | 136 const std::string& top_level_name, |
| 133 const base::FilePath& dot_file) const { | 137 const base::FilePath& dot_file) const { |
| 134 DCHECK(!dot_file.empty()); | 138 DCHECK(!dot_file.empty()); |
| 135 std::string contents = dependency_graph_.DumpAsGraphviz( | 139 std::string contents = dependency_graph_.DumpAsGraphviz( |
| 136 top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName)); | 140 top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName)); |
| 137 base::WriteFile(dot_file, contents.c_str(), contents.size()); | 141 base::WriteFile(dot_file, contents.c_str(), contents.size()); |
| 138 } | 142 } |
| 139 #endif // NDEBUG | 143 #endif // NDEBUG |
| OLD | NEW |