1 /*
2 * Copyright (c) 2025 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 #include "base/log/ace_trace.h"
16 #include "base/log/log_wrapper.h"
17 #include "base/memory/ace_type.h"
18 #include "base/thread/background_task_executor.h"
19 #include "base/thread/task_dependency_manager.h"
20 #include "base/utils/utils.h"
21
22 #include "base/utils/system_properties.h"
23
24 namespace OHOS::Ace {
25 std::mutex g_mutexTaskDependencyManager;
26 RefPtr<TaskDependencyManager> TaskDependencyManager::instance_ = nullptr;
27
PostTaskToBg(std::function<void ()> && task,const std::string & taskName,std::function<void (TaskDependencyManager::ErrorCode,std::function<void ()> &&,const std::string &)> && errorHandler)28 void TaskDependencyManager::PostTaskToBg(std::function<void()>&& task, const std::string& taskName,
29 std::function<void(TaskDependencyManager::ErrorCode, std::function<void()>&&,
30 const std::string&)>&& errorHandler)
31 {
32 if (!SystemProperties::GetAsyncInitializeEnabled()) {
33 task();
34 return;
35 }
36 std::shared_ptr<std::packaged_task<void()>> package = std::make_shared<std::packaged_task<void()>>(task);
37 if (taskName == "") {
38 errorHandler(TaskDependencyManager::ErrorCode::TASK_ERROR_KEY_ILLEGAL,
39 [package] () { (*package)(); },
40 taskName);
41 return;
42 }
43 auto wrappedTask = [package, taskName, weak = WeakClaim(this)] () {
44 (*package)();
45 auto manager = weak.Upgrade();
46 CHECK_NULL_VOID(manager);
47 manager->Delete(taskName);
48 };
49 bool result;
50 lock_.lock();
51 if (futures_.find(taskName) != futures_.end()) {
52 result = false;
53 } else {
54 result = true;
55 futures_.emplace(taskName, std::make_shared<std::future<void>>(package->get_future()));
56 }
57 lock_.unlock();
58 if (result) {
59 BackgroundTaskExecutor::GetInstance().PostTask(std::move(wrappedTask));
60 } else {
61 errorHandler(TaskDependencyManager::ErrorCode::TASK_ERROR_KEY_CONFLICT,
62 [package] () { (*package)(); },
63 taskName);
64 }
65 }
66
Wait(const std::string & dependencyName,std::function<void (TaskDependencyManager::ErrorCode,const std::string &)> && errorHandler)67 void TaskDependencyManager::Wait(const std::string& dependencyName,
68 std::function<void(TaskDependencyManager::ErrorCode, const std::string&)>&& errorHandler)
69 {
70 if (!SystemProperties::GetAsyncInitializeEnabled()) {
71 return;
72 }
73 bool result;
74 std::shared_ptr<std::future<void>> future;
75 lock_.lock();
76 if (futures_.find(dependencyName) != futures_.end()) {
77 result = true;
78 future = futures_[dependencyName];
79 } else {
80 result = false;
81 }
82 lock_.unlock();
83 if (result) {
84 future->wait();
85 } else {
86 errorHandler(
87 TaskDependencyManager::ErrorCode::TASK_ERROR_UNRECORDED_DEPENDENCY,
88 dependencyName);
89 }
90 }
91
Sync()92 void TaskDependencyManager::Sync()
93 {
94 if (!SystemProperties::GetAsyncInitializeEnabled()) {
95 return;
96 }
97 std::shared_ptr<std::future<void>> future;
98 bool breakFlag = false;
99 while (!breakFlag) {
100 lock_.lock();
101 if (futures_.size() > 0) {
102 future = std::shared_ptr<std::future<void>>(futures_.begin()->second);
103 } else {
104 breakFlag = true;
105 }
106 lock_.unlock();
107 if (breakFlag) {
108 break;
109 }
110 future->wait();
111 }
112 }
113
GetInstance()114 RefPtr<TaskDependencyManager> TaskDependencyManager::GetInstance()
115 {
116 if (!instance_) {
117 std::lock_guard<std::mutex> lock(g_mutexTaskDependencyManager);
118 if (!instance_) {
119 instance_ = MakeRefPtr<TaskDependencyManager>();
120 }
121 }
122 return instance_;
123 }
124
Delete(const std::string & taskName)125 void TaskDependencyManager::Delete(const std::string& taskName)
126 {
127 if (!SystemProperties::GetAsyncInitializeEnabled()) {
128 return;
129 }
130 lock_.lock();
131 if (futures_.find(taskName) != futures_.end()) {
132 futures_.erase(taskName);
133 }
134 lock_.unlock();
135 }
136 } //OHOS::Ace
137