/components/keyed_service/core/dependency_manager.cc

https://gitlab.com/0072016/Facebook-SDK- · C++ · 139 lines · 110 code · 25 blank · 4 comment · 13 complexity · 0168b07c9f1ca6c8d7b2942ac2924bde 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. factory->RegisterPrefsIfNecessaryForContext(context, pref_registry);
  38. }
  39. }
  40. void DependencyManager::CreateContextServices(base::SupportsUserData* context,
  41. bool is_testing_context) {
  42. #ifndef NDEBUG
  43. MarkContextLiveForTesting(context);
  44. #endif
  45. std::vector<DependencyNode*> construction_order;
  46. if (!dependency_graph_.GetConstructionOrder(&construction_order)) {
  47. NOTREACHED();
  48. }
  49. #ifndef NDEBUG
  50. DumpContextDependencies(context);
  51. #endif
  52. for (const auto& dependency_node : construction_order) {
  53. KeyedServiceBaseFactory* factory =
  54. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  55. if (is_testing_context && factory->ServiceIsNULLWhileTesting() &&
  56. !factory->HasTestingFactory(context)) {
  57. factory->SetEmptyTestingFactory(context);
  58. } else if (factory->ServiceIsCreatedWithContext()) {
  59. factory->CreateServiceNow(context);
  60. }
  61. }
  62. }
  63. void DependencyManager::DestroyContextServices(
  64. base::SupportsUserData* context) {
  65. std::vector<DependencyNode*> destruction_order;
  66. if (!dependency_graph_.GetDestructionOrder(&destruction_order)) {
  67. NOTREACHED();
  68. }
  69. #ifndef NDEBUG
  70. DumpContextDependencies(context);
  71. #endif
  72. for (const auto& dependency_node : destruction_order) {
  73. KeyedServiceBaseFactory* factory =
  74. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  75. factory->ContextShutdown(context);
  76. }
  77. #ifndef NDEBUG
  78. // The context is now dead to the rest of the program.
  79. dead_context_pointers_.insert(context);
  80. #endif
  81. for (const auto& dependency_node : destruction_order) {
  82. KeyedServiceBaseFactory* factory =
  83. static_cast<KeyedServiceBaseFactory*>(dependency_node);
  84. factory->ContextDestroyed(context);
  85. }
  86. }
  87. #ifndef NDEBUG
  88. void DependencyManager::AssertContextWasntDestroyed(
  89. base::SupportsUserData* context) {
  90. if (dead_context_pointers_.find(context) != dead_context_pointers_.end()) {
  91. NOTREACHED() << "Attempted to access a context that was ShutDown(). "
  92. << "This is most likely a heap smasher in progress. After "
  93. << "KeyedService::Shutdown() completes, your service MUST "
  94. << "NOT refer to depended services again.";
  95. }
  96. }
  97. void DependencyManager::MarkContextLiveForTesting(
  98. base::SupportsUserData* context) {
  99. dead_context_pointers_.erase(context);
  100. }
  101. namespace {
  102. std::string KeyedServiceBaseFactoryGetNodeName(DependencyNode* node) {
  103. return static_cast<KeyedServiceBaseFactory*>(node)->name();
  104. }
  105. } // namespace
  106. void DependencyManager::DumpDependenciesAsGraphviz(
  107. const std::string& top_level_name,
  108. const base::FilePath& dot_file) const {
  109. DCHECK(!dot_file.empty());
  110. std::string contents = dependency_graph_.DumpAsGraphviz(
  111. top_level_name, base::Bind(&KeyedServiceBaseFactoryGetNodeName));
  112. base::WriteFile(dot_file, contents.c_str(), contents.size());
  113. }
  114. #endif // NDEBUG