• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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