1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "resource_node_pool.h"
17
18 #include <mutex>
19 #include <set>
20 #include <unordered_map>
21
22 #include <singleton.h>
23
24 #include "iam_check.h"
25 #include "iam_logger.h"
26
27 #define LOG_TAG "USER_AUTH_SA"
28
29 namespace OHOS {
30 namespace UserIam {
31 namespace UserAuth {
32 class ResourceNodePoolImpl final : public ResourceNodePool, public Singleton<ResourceNodePoolImpl> {
33 public:
34 bool Insert(const std::shared_ptr<ResourceNode> &resource) override;
35 bool Delete(uint64_t executorIndex) override;
36 void DeleteAll() override;
37 std::weak_ptr<ResourceNode> Select(uint64_t executorIndex) const override;
38 uint32_t GetPoolSize() const override;
39 void Enumerate(std::function<void(const std::weak_ptr<ResourceNode> &)> action) const override;
40 bool RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener) override;
41 bool DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener) override;
42
43 private:
44 struct ResourceNodeParam {
45 uint32_t count = 0;
46 std::shared_ptr<ResourceNode> node = nullptr;
47 };
48 mutable std::recursive_mutex poolMutex_;
49 std::unordered_map<uint64_t, ResourceNodeParam> resourceNodeMap_;
50 std::set<std::shared_ptr<ResourceNodePoolListener>> listenerSet_;
51 };
52
Insert(const std::shared_ptr<ResourceNode> & resource)53 bool ResourceNodePoolImpl::Insert(const std::shared_ptr<ResourceNode> &resource)
54 {
55 if (resource == nullptr) {
56 IAM_LOGE("resource is nullptr");
57 return false;
58 }
59 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
60 uint64_t executorIndex = resource->GetExecutorIndex();
61
62 ResourceNodeParam nodeParam = {1, resource};
63 auto iter = resourceNodeMap_.find(executorIndex);
64 if (iter != resourceNodeMap_.end()) {
65 if (nodeParam.count < UINT32_MAX) {
66 nodeParam.count = iter->second.count + 1;
67 }
68 if (iter->second.node != nullptr) {
69 iter->second.node->DetachFromDriver();
70 }
71 }
72
73 auto result = resourceNodeMap_.insert_or_assign(executorIndex, nodeParam);
74 if (result.second) {
75 IAM_LOGI("insert resource node success");
76 for (const auto &listener : listenerSet_) {
77 if (listener != nullptr) {
78 listener->OnResourceNodePoolInsert(nodeParam.node);
79 }
80 }
81 } else {
82 IAM_LOGI("update resource node success, count: %{public}u", resourceNodeMap_[executorIndex].count);
83 for (const auto &listener : listenerSet_) {
84 if (listener != nullptr) {
85 listener->OnResourceNodePoolUpdate(nodeParam.node);
86 }
87 }
88 }
89 return true;
90 }
91
Delete(uint64_t executorIndex)92 bool ResourceNodePoolImpl::Delete(uint64_t executorIndex)
93 {
94 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
95 auto iter = resourceNodeMap_.find(executorIndex);
96 if (iter == resourceNodeMap_.end()) {
97 IAM_LOGE("executor not found");
98 return false;
99 }
100
101 if (iter->second.count > 1) {
102 iter->second.count--;
103 IAM_LOGI("resource node count %{public}u, no delete", iter->second.count);
104 return true;
105 }
106 IAM_LOGI("delete resource node");
107
108 auto tempResource = iter->second.node;
109 IF_FALSE_LOGE_AND_RETURN_VAL(tempResource != nullptr, false);
110 tempResource->DeleteFromDriver();
111
112 resourceNodeMap_.erase(iter);
113 for (const auto &listener : listenerSet_) {
114 if (listener != nullptr) {
115 listener->OnResourceNodePoolDelete(tempResource);
116 }
117 }
118 return true;
119 }
120
DeleteAll()121 void ResourceNodePoolImpl::DeleteAll()
122 {
123 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
124 IAM_LOGI("delete all resource node begin, node num %{public}zu", resourceNodeMap_.size());
125 for (const auto &pair : resourceNodeMap_) {
126 auto node = pair.second.node;
127 if (node != nullptr) {
128 node->DeleteFromDriver();
129 }
130 }
131 auto tempMap = resourceNodeMap_;
132 resourceNodeMap_.clear();
133 for (auto &node : tempMap) {
134 for (const auto &listener : listenerSet_) {
135 if (listener != nullptr) {
136 listener->OnResourceNodePoolDelete(node.second.node);
137 }
138 }
139 }
140 IAM_LOGI("delete all resource node success");
141 }
142
Select(uint64_t executorIndex) const143 std::weak_ptr<ResourceNode> ResourceNodePoolImpl::Select(uint64_t executorIndex) const
144 {
145 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
146 std::weak_ptr<ResourceNode> result;
147 auto iter = resourceNodeMap_.find(executorIndex);
148 if (iter != resourceNodeMap_.end()) {
149 result = iter->second.node;
150 }
151 return result;
152 }
153
Enumerate(std::function<void (const std::weak_ptr<ResourceNode> &)> action) const154 void ResourceNodePoolImpl::Enumerate(std::function<void(const std::weak_ptr<ResourceNode> &)> action) const
155 {
156 if (action == nullptr) {
157 IAM_LOGE("action is nullptr");
158 return;
159 }
160 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
161 for (auto &node : resourceNodeMap_) {
162 action(node.second.node);
163 }
164 }
165
GetPoolSize() const166 uint32_t ResourceNodePoolImpl::GetPoolSize() const
167 {
168 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
169 return resourceNodeMap_.size();
170 }
171
RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> & listener)172 bool ResourceNodePoolImpl::RegisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener)
173 {
174 if (listener == nullptr) {
175 IAM_LOGE("listener is nullptr");
176 return false;
177 }
178 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
179 listenerSet_.insert(listener);
180 return true;
181 }
182
DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> & listener)183 bool ResourceNodePoolImpl::DeregisterResourceNodePoolListener(const std::shared_ptr<ResourceNodePoolListener> &listener)
184 {
185 std::lock_guard<std::recursive_mutex> lock(poolMutex_);
186 return listenerSet_.erase(listener) == 1;
187 }
188
Instance()189 ResourceNodePool &ResourceNodePool::Instance()
190 {
191 return ResourceNodePoolImpl::GetInstance();
192 }
193 } // namespace UserAuth
194 } // namespace UserIam
195 } // namespace OHOS
196