1 /*
2 * Copyright (c) 2023 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 "app_domain_verify_task_mgr.h"
17 #include <deque>
18 #include <memory>
19 #include <string>
20 #include <future>
21 #include "app_domain_verify_hilog.h"
22
23 namespace OHOS {
24 namespace AppDomainVerify {
25 std::shared_ptr<AppDomainVerifyTaskMgr> AppDomainVerifyTaskMgr::instance_ = nullptr;
26 ffrt::mutex AppDomainVerifyTaskMgr::instanceMutex_;
27
28 using namespace OHOS::NetStack::HttpClient;
29
30 class AutoSeqReleaser {
31 public:
AutoSeqReleaser(SafeMap<uint32_t,std::shared_ptr<IHttpTask>> * map,uint32_t seq)32 AutoSeqReleaser(SafeMap<uint32_t, std::shared_ptr<IHttpTask>>* map, uint32_t seq) : seq_(seq), map_(map)
33 {
34 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_COMMON, "AutoSeqReleaser() seq:%{public}u.", seq_);
35 }
~AutoSeqReleaser()36 ~AutoSeqReleaser()
37 {
38 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_MODULE_COMMON, "~AutoSeqReleaser() seq:%{public}u.", seq_);
39 if (map_ != nullptr) {
40 map_->Erase(seq_);
41 }
42 }
43
44 private:
45 uint32_t seq_;
46 SafeMap<uint32_t, std::shared_ptr<IHttpTask>>* map_;
47 };
48
GetInstance()49 std::shared_ptr<AppDomainVerifyTaskMgr> AppDomainVerifyTaskMgr::GetInstance()
50 {
51 if (instance_ == nullptr) {
52 std::lock_guard<ffrt::mutex> lock(instanceMutex_);
53 if (instance_ == nullptr) {
54 instance_ = std::make_shared<AppDomainVerifyTaskMgr>();
55 }
56 }
57 return instance_;
58 }
59
DestroyInstance()60 void AppDomainVerifyTaskMgr::DestroyInstance()
61 {
62 std::lock_guard<ffrt::mutex> lock(instanceMutex_);
63 if (instance_ != nullptr) {
64 instance_.reset();
65 instance_ = nullptr;
66 }
67 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr DestroyInstance!");
68 }
69
AppDomainVerifyTaskMgr()70 AppDomainVerifyTaskMgr::AppDomainVerifyTaskMgr()
71 {
72 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr new!");
73 Init();
74 }
75
~AppDomainVerifyTaskMgr()76 AppDomainVerifyTaskMgr::~AppDomainVerifyTaskMgr()
77 {
78 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr destory!");
79 {
80 std::unique_lock<ffrt::mutex> lock(mutex_);
81 this->stop_ = true;
82 cond_.notify_all();
83 }
84 // wait all workers done;
85 ffrt::wait();
86 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "AppDomainVerifyTaskMgr destory end!");
87 }
88
Init()89 bool AppDomainVerifyTaskMgr::Init()
90 {
91 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "Init workers.");
92 for (int i = 0; i < poolSize_; i++) {
93 ffrt::submit_h([this]() {
94 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "worker run.");
95 std::unique_lock<ffrt::mutex> lock(mutex_);
96 while (!this->stop_) {
97 if (!tasks_.empty()) {
98 auto task = std::move(tasks_.front());
99 tasks_.pop();
100 lock.unlock();
101 task();
102 lock.lock();
103 } else {
104 while (tasks_.empty() && !this->stop_) {
105 cond_.wait(lock);
106 }
107 }
108 }
109 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "worker done.");
110 });
111 }
112 return true;
113 }
GetTaskWrapper(const std::shared_ptr<IHttpTask> & httpTask)114 std::function<void()> AppDomainVerifyTaskMgr::GetTaskWrapper(const std::shared_ptr<IHttpTask>& httpTask)
115 {
116 return [taskMap = &taskMap_, httpTask]() {
117 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "task in");
118 auto seq = httpTask->GetTaskId();
119 auto clientTask = httpTask->CreateHttpClientTask();
120 if (clientTask == nullptr) {
121 AutoSeqReleaser releaser(taskMap, seq);
122 HttpClientRequest request;
123 HttpClientResponse response;
124 response.SetResult("creat http client task failed");
125 HttpClientError error;
126 httpTask->OnFail(request, response, error);
127 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "clientTask null");
128 return;
129 }
130 std::promise<void> promise;
131 std::future future = promise.get_future();
132 clientTask->OnSuccess(
133 [&taskMap, &httpTask, &promise, seq](const HttpClientRequest& request, const HttpClientResponse& response) {
134 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnSuccess");
135 httpTask->OnSuccess(request, response);
136 AutoSeqReleaser releaser(taskMap, seq);
137 promise.set_value();
138 });
139 clientTask->OnFail([&taskMap, httpTask, &promise, seq](const HttpClientRequest& request,
140 const HttpClientResponse& response, const HttpClientError& error) {
141 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnFail");
142 httpTask->OnFail(request, response, error);
143 AutoSeqReleaser releaser(taskMap, seq);
144 promise.set_value();
145 });
146 clientTask->OnCancel(
147 [&taskMap, &httpTask, &promise, seq](const HttpClientRequest& request, const HttpClientResponse& response) {
148 APP_DOMAIN_VERIFY_HILOGW(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnCancel");
149 httpTask->OnCancel(request, response);
150 AutoSeqReleaser releaser(taskMap, seq);
151 promise.set_value();
152 });
153 clientTask->OnDataReceive(
154 [&clientTask, &httpTask](const HttpClientRequest& request, const uint8_t* data, size_t length) {
155 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "OnDataReceive");
156 httpTask->OnDataReceive(clientTask, request, data, length);
157 });
158 clientTask->Start();
159 future.wait();
160 APP_DOMAIN_VERIFY_HILOGD(APP_DOMAIN_VERIFY_AGENT_MODULE_SERVICE, "task out");
161 };
162 }
AddTask(const std::shared_ptr<IHttpTask> & task)163 bool AppDomainVerifyTaskMgr::AddTask(const std::shared_ptr<IHttpTask>& task)
164 {
165 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "AddTask.");
166 if (task == nullptr) {
167 APP_DOMAIN_VERIFY_HILOGE(APP_DOMAIN_VERIFY_MODULE_COMMON, "AddTask task null.");
168 return false;
169 }
170 std::function<void()> taskWrapper = GetTaskWrapper(task);
171 std::unique_lock<ffrt::mutex> lock(mutex_);
172 taskMap_.EnsureInsert(task->GetTaskId(), task);
173 tasks_.push(std::move(taskWrapper));
174 cond_.notify_one();
175 return true;
176 }
IsIdle()177 bool AppDomainVerifyTaskMgr::IsIdle()
178 {
179 APP_DOMAIN_VERIFY_HILOGI(APP_DOMAIN_VERIFY_MODULE_COMMON, "IsIdle.");
180 return taskMap_.IsEmpty();
181 }
182 }
183 }
184