/components/keyed_service/core/dependency_manager.cc

https://gitlab.com/jonnialva90/iridium-browser · C++ · 143 lines · 114 code · 25 blank · 4 comment · 13 complexity · 871cccddde5b07148c01a359e3b2686c MD5 · raw file

  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
  3. // found in the LICENSE file.
  4. #include "components/keyed_service/core/dependency_manager.h"
  5. #include "base/bind.h"
  6. #include "base/logging.h"
  7. #include "base/supports_user_data.h"
  8. #include "components/keyed_service/core/keyed_service_base_factory.h"
  9. #ifndef NDEBUG
  10. #include "base/files/file_path.h"
  11. #include "base/files/file_util.h"
  12. #endif // NDEBUG
  13. DependencyManager::DependencyManager() {
  14. }
  15. DependencyManager::~DependencyManager() {
  16. }
  17. void DependencyManager::AddComponent(KeyedServiceBaseFactory* component) {
  18. dependency_graph_.AddNode(component);
  19. }
  20. void DependencyManager::RemoveComponent(KeyedServiceBaseFactory* component) {
  21. dependency_graph_.RemoveNode(component);
  22. }
  23. void DependencyManager::AddEdge(KeyedServiceBaseFactory* depended,
  24. KeyedServiceBaseFactory* dependee) {
  25. dependency_graph_.AddEdge(depended, dependee);
  26. }
  27. void DependencyManager::RegisterPrefsForServices(
  28. base::SupportsUserData* context,
  29. user_prefs::PrefRegistrySyncable* pref_registry) {
  30. std::vector<DependencyNode*> construction_order;
  31. if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
  32. NOTREACHED();
  33. }
  34. for (const auto& dependency_node : construction_order) {
  35. KeyedServiceBaseFactory* factory =
  36. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  37. base::SupportsUserData* typed_context = factory->GetTypedContext(context);
  38. factory->RegisterPrefsIfNecessaryForContext(typed_context, pref_registry);
  39. }
  40. }
  41. void DependencyManager::CreateContextServices(base::SupportsUserData* context,
  42. bool is_testing_context) {
  43. #ifndef NDEBUG
  44. MarkContextLiveForTesting(context);
  45. #endif
  46. std::vector<DependencyNode*> construction_order;
  47. if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
  48. NOTREACHED();
  49. }
  50. #ifndef NDEBUG
  51. DumpContextDependencies(context);
  52. #endif
  53. for (const auto& dependency_node : construction_order) {
  54. KeyedServiceBaseFactory* factory =
  55. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  56. base::SupportsUserData* typed_context = factory->GetTypedContext(context);
  57. if (is_testing_context && factory->ServiceIsNULLWhileTesting() &&
  58. !factory->HasTestingFactory(typed_context)) {
  59. factory->SetEmptyTestingFactory(typed_context);
  60. } else if (factory->ServiceIsCreatedWithContext()) {
  61. factory->CreateServiceNow(typed_context);
  62. }
  63. }
  64. }
  65. void DependencyManager::DestroyContextServices(
  66. base::SupportsUserData* context) {
  67. std::vector<DependencyNode*> destruction_order;
  68. if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
  69. NOTREACHED();
  70. }
  71. #ifndef NDEBUG
  72. DumpContextDependencies(context);
  73. #endif
  74. for (const auto& dependency_node : destruction_order) {
  75. KeyedServiceBaseFactory* factory =
  76. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  77. base::SupportsUserData* typed_context = factory->GetTypedContext(context);
  78. factory->ContextShutdown(typed_context);
  79. }
  80. #ifndef NDEBUG
  81. // The context is now dead to the rest of the program.
  82. dead_context_pointers_.insert(context);
  83. #endif
  84. for (const auto& dependency_node : destruction_order) {
  85. KeyedServiceBaseFactory* factory =
  86. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  87. base::SupportsUserData* typed_context = factory->GetTypedContext(context);
  88. factory->ContextDestroyed(typed_context);
  89. }
  90. }
  91. #ifndef NDEBUG
  92. void DependencyManager::AssertContextWasntDestroyed(
  93. base::SupportsUserData* context) {
  94. if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
  95. NOTREACHED() << "Attempted to access a context that was ShutDown(). "
  96. << "This is most likely a heap smasher in progress. After "
  97. << "KeyedService::Shutdown() completes, your service MUST "
  98. << "NOT refer to depended services again.";
  99. }
  100. }
  101. void DependencyManager::MarkContextLiveForTesting(
  102. base::SupportsUserData* context) {
  103. dead_context_pointers_.erase(context);
  104. }
  105. namespace {
  106. std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) {
  107. return static_cast<KeyedServiceBaseFactory*>(node)->name();
  108. }
  109. } // namespace
  110. void DependencyManager::DumpDependenciesAsGraphviz(
  111. const std::string& top_level_name,
  112. const base::FilePath& dot_file) const {
  113. DCHECK(!dot_file.empty());
  114. std::string contents = dependency_graph_.DumpAsGraphviz(
  115. top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName));
  116. base::WriteFile(dot_file, contents.c_str(), contents.size());
  117. }
  118. #endif // NDEBUG