dependency_manager.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #ifndef COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
  5. #define COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_
  6. #include <set>
  7. #include <string>
  8. #include "base/dcheck_is_on.h"
  9. #include "components/keyed_service/core/dependency_graph.h"
  10. #include "components/keyed_service/core/keyed_service_export.h"
  11. class KeyedServiceBaseFactory;
  12. namespace base {
  13. class FilePath;
  14. }
  15. namespace user_prefs {
  16. class PrefRegistrySyncable;
  17. }
  18. // DependencyManager manages dependency between KeyedServiceBaseFactory
  19. // broadcasting the context creation and destruction to each factory in
  20. // a safe order based on the stated dependencies.
  21. class KEYED_SERVICE_EXPORT DependencyManager {
  22. public:
  23. DependencyManager(const DependencyManager&) = delete;
  24. DependencyManager& operator=(const DependencyManager&) = delete;
  25. // Shuts down all keyed services managed by two
  26. // DependencyManagers (DMs), then destroys them. The order of execution is:
  27. // - Shutdown services in DM1
  28. // - Shutdown services in DM2
  29. // - Destroy services in DM1
  30. // - Destroy services in DM2
  31. static void PerformInterlockedTwoPhaseShutdown(
  32. DependencyManager* dependency_manager1,
  33. void* context1,
  34. DependencyManager* dependency_manager2,
  35. void* context2);
  36. // Returns the dependency graph for Keyed Services Factory testing purposes.
  37. DependencyGraph& GetDependencyGraphForTesting();
  38. protected:
  39. DependencyManager();
  40. virtual ~DependencyManager();
  41. // Adds/Removes a component from our list of live components. Removing will
  42. // also remove live dependency links.
  43. void AddComponent(KeyedServiceBaseFactory* component);
  44. void RemoveComponent(KeyedServiceBaseFactory* component);
  45. // Adds a dependency between two factories.
  46. void AddEdge(KeyedServiceBaseFactory* depended,
  47. KeyedServiceBaseFactory* dependee);
  48. // Registers preferences for all services via |registry|.
  49. void RegisterPrefsForServices(user_prefs::PrefRegistrySyncable* registry);
  50. // Called upon creation of |context| to create services that want to be
  51. // started at the creation of a context and register service-related
  52. // preferences.
  53. //
  54. // To have a KeyedService started when a context is created the method
  55. // KeyedServiceBaseFactory::ServiceIsCreatedWithContext() must be overridden
  56. // to return true.
  57. //
  58. // If |is_testing_context| then the service will not be started unless the
  59. // method KeyedServiceBaseFactory::ServiceIsNULLWhileTesting() return false.
  60. void CreateContextServices(void* context, bool is_testing_context);
  61. // Called upon destruction of |context| to destroy all services associated
  62. // with it.
  63. void DestroyContextServices(void* context);
  64. // Runtime assertion called as a part of GetServiceForContext() to check if
  65. // |context| is considered stale. This will CHECK(false) to avoid a potential
  66. // use-after-free from services created after context destruction.
  67. void AssertContextWasntDestroyed(void* context) const;
  68. // Marks |context| as live (i.e., not stale). This method can be called as a
  69. // safeguard against |AssertContextWasntDestroyed()| checks going off due to
  70. // |context| aliasing an instance from a prior construction (i.e., 0xWhatever
  71. // might be created, be destroyed, and then a new object might be created at
  72. // 0xWhatever).
  73. void MarkContextLive(void* context);
  74. // Marks |context| as dead (i.e., stale). Calls passing |context| to
  75. //|AssertContextWasntDestroyed()| will flag an error until that context is
  76. // marked as live again with MarkContextLive().
  77. void MarkContextDead(void* context);
  78. #ifndef NDEBUG
  79. // Dumps service dependency graph as a Graphviz dot file |dot_file| with a
  80. // title |top_level_name|. Helper for |DumpContextDependencies|.
  81. void DumpDependenciesAsGraphviz(const std::string& top_level_name,
  82. const base::FilePath& dot_file) const;
  83. #endif // NDEBUG
  84. private:
  85. friend class KeyedServiceBaseFactory;
  86. #ifndef NDEBUG
  87. // Hook for subclass to dump the dependency graph of service for |context|.
  88. virtual void DumpContextDependencies(void* context) const = 0;
  89. #endif // NDEBUG
  90. std::vector<DependencyNode*> GetDestructionOrder();
  91. static void ShutdownFactoriesInOrder(void* context,
  92. std::vector<DependencyNode*>& order);
  93. static void DestroyFactoriesInOrder(void* context,
  94. std::vector<DependencyNode*>& order);
  95. DependencyGraph dependency_graph_;
  96. // A list of context objects that have gone through the Shutdown() phase.
  97. // These pointers are most likely invalid, but we keep track of their
  98. // locations in memory so we can nicely assert if we're asked to do anything
  99. // with them.
  100. std::set<void*> dead_context_pointers_;
  101. #if DCHECK_IS_ON()
  102. bool context_services_created_ = false;
  103. #endif
  104. };
  105. #endif // COMPONENTS_KEYED_SERVICE_CORE_DEPENDENCY_MANAGER_H_