service_instance_registry.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright 2019 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 "services/service_manager/service_instance_registry.h"
  5. #include <algorithm>
  6. #include "services/service_manager/public/cpp/manifest.h"
  7. #include "services/service_manager/service_instance.h"
  8. namespace service_manager {
  9. ServiceInstanceRegistry::Entry::Entry(const base::Token& guid,
  10. ServiceInstance* instance)
  11. : guid(guid), instance(instance) {
  12. DCHECK(!guid.is_zero());
  13. DCHECK(instance);
  14. }
  15. ServiceInstanceRegistry::Entry::Entry(const Entry&) = default;
  16. ServiceInstanceRegistry::Entry::~Entry() = default;
  17. ServiceInstanceRegistry::RegularInstanceKey::RegularInstanceKey(
  18. const std::string& service_name,
  19. const base::Token& instance_group,
  20. const base::Token& instance_id)
  21. : service_name(service_name),
  22. instance_group(instance_group),
  23. instance_id(instance_id) {}
  24. ServiceInstanceRegistry::RegularInstanceKey::RegularInstanceKey(
  25. const RegularInstanceKey&) = default;
  26. ServiceInstanceRegistry::RegularInstanceKey::~RegularInstanceKey() = default;
  27. bool ServiceInstanceRegistry::RegularInstanceKey::operator==(
  28. const RegularInstanceKey& other) const {
  29. return service_name == other.service_name &&
  30. instance_group == other.instance_group &&
  31. instance_id == other.instance_id;
  32. }
  33. bool ServiceInstanceRegistry::RegularInstanceKey::operator<(
  34. const RegularInstanceKey& other) const {
  35. return std::tie(service_name, instance_group, instance_id) <
  36. std::tie(other.service_name, other.instance_group, other.instance_id);
  37. }
  38. ServiceInstanceRegistry::SharedInstanceKey::SharedInstanceKey(
  39. const std::string& service_name,
  40. const base::Token& instance_id)
  41. : service_name(service_name), instance_id(instance_id) {}
  42. ServiceInstanceRegistry::SharedInstanceKey::SharedInstanceKey(
  43. const SharedInstanceKey&) = default;
  44. ServiceInstanceRegistry::SharedInstanceKey::~SharedInstanceKey() = default;
  45. bool ServiceInstanceRegistry::SharedInstanceKey::operator==(
  46. const SharedInstanceKey& other) const {
  47. return service_name == other.service_name && instance_id == other.instance_id;
  48. }
  49. bool ServiceInstanceRegistry::SharedInstanceKey::operator<(
  50. const SharedInstanceKey& other) const {
  51. if (service_name != other.service_name)
  52. return service_name < other.service_name;
  53. return instance_id < other.instance_id;
  54. }
  55. ServiceInstanceRegistry::ServiceInstanceRegistry() = default;
  56. ServiceInstanceRegistry::~ServiceInstanceRegistry() = default;
  57. void ServiceInstanceRegistry::Register(ServiceInstance* instance) {
  58. DCHECK_NE(instance, nullptr);
  59. const Identity& identity = instance->identity();
  60. DCHECK_EQ(FindMatching(identity), nullptr);
  61. switch (instance->manifest().options.instance_sharing_policy) {
  62. case Manifest::InstanceSharingPolicy::kNoSharing: {
  63. const RegularInstanceKey key{identity.name(), identity.instance_group(),
  64. identity.instance_id()};
  65. regular_instances_[key].emplace_back(identity.globally_unique_id(),
  66. instance);
  67. break;
  68. }
  69. case Manifest::InstanceSharingPolicy::kSharedAcrossGroups: {
  70. const SharedInstanceKey key{identity.name(), identity.instance_id()};
  71. shared_instances_[key].emplace_back(identity.globally_unique_id(),
  72. instance);
  73. break;
  74. }
  75. case Manifest::InstanceSharingPolicy::kSingleton:
  76. singleton_instances_[identity.name()].emplace_back(
  77. identity.globally_unique_id(), instance);
  78. break;
  79. default:
  80. NOTREACHED();
  81. }
  82. }
  83. bool ServiceInstanceRegistry::Unregister(ServiceInstance* instance) {
  84. DCHECK(instance);
  85. const Identity& identity = instance->identity();
  86. const RegularInstanceKey regular_key{
  87. identity.name(), identity.instance_group(), identity.instance_id()};
  88. auto regular_iter = regular_instances_.find(regular_key);
  89. if (regular_iter != regular_instances_.end()) {
  90. auto& entries = regular_iter->second;
  91. if (EraseEntry(identity.globally_unique_id(), &entries)) {
  92. if (entries.empty())
  93. regular_instances_.erase(regular_iter);
  94. return true;
  95. }
  96. }
  97. const SharedInstanceKey shared_key{identity.name(), identity.instance_id()};
  98. auto shared_iter = shared_instances_.find(shared_key);
  99. if (shared_iter != shared_instances_.end()) {
  100. auto& entries = shared_iter->second;
  101. if (EraseEntry(identity.globally_unique_id(), &entries)) {
  102. if (entries.empty())
  103. shared_instances_.erase(shared_iter);
  104. return true;
  105. }
  106. }
  107. auto singleton_iter = singleton_instances_.find(identity.name());
  108. if (singleton_iter != singleton_instances_.end()) {
  109. auto& entries = singleton_iter->second;
  110. if (EraseEntry(identity.globally_unique_id(), &entries)) {
  111. if (entries.empty())
  112. singleton_instances_.erase(singleton_iter);
  113. return true;
  114. }
  115. }
  116. return false;
  117. }
  118. ServiceInstance* ServiceInstanceRegistry::FindMatching(
  119. const ServiceFilter& filter) const {
  120. DCHECK(filter.instance_group());
  121. DCHECK(filter.instance_id());
  122. DCHECK(!filter.globally_unique_id() ||
  123. !filter.globally_unique_id()->is_zero());
  124. const RegularInstanceKey regular_key{
  125. filter.service_name(), *filter.instance_group(), *filter.instance_id()};
  126. auto regular_iter = regular_instances_.find(regular_key);
  127. if (regular_iter != regular_instances_.end()) {
  128. return FindMatchInEntries(regular_iter->second,
  129. filter.globally_unique_id());
  130. }
  131. const SharedInstanceKey shared_key{filter.service_name(),
  132. *filter.instance_id()};
  133. auto shared_iter = shared_instances_.find(
  134. SharedInstanceKey(filter.service_name(), *filter.instance_id()));
  135. if (shared_iter != shared_instances_.end()) {
  136. return FindMatchInEntries(shared_iter->second, filter.globally_unique_id());
  137. }
  138. auto singleton_iter = singleton_instances_.find(filter.service_name());
  139. if (singleton_iter != singleton_instances_.end()) {
  140. return FindMatchInEntries(singleton_iter->second,
  141. filter.globally_unique_id());
  142. }
  143. return nullptr;
  144. }
  145. ServiceInstance* ServiceInstanceRegistry::FindMatchInEntries(
  146. const std::vector<Entry>& entries,
  147. const absl::optional<base::Token>& guid) const {
  148. DCHECK(!entries.empty());
  149. if (!guid.has_value())
  150. return entries.front().instance;
  151. for (const auto& entry : entries) {
  152. if (entry.guid == *guid)
  153. return entry.instance;
  154. }
  155. return nullptr;
  156. }
  157. bool ServiceInstanceRegistry::EraseEntry(const base::Token& guid,
  158. std::vector<Entry>* entries) {
  159. auto it =
  160. std::find_if(entries->begin(), entries->end(),
  161. [&guid](const Entry& entry) { return entry.guid == guid; });
  162. if (it == entries->end())
  163. return false;
  164. entries->erase(it);
  165. return true;
  166. }
  167. } // namespace service_manager