1 /*
2 * Copyright (c) 2021-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 #include "base_task_dispatcher.h"
16 #include "hilog_wrapper.h"
17
18 namespace OHOS {
19 namespace AppExecFwk {
20 std::atomic<int> BaseTaskDispatcher::SEQUENCE_(0);
BaseTaskDispatcher(const std::string & dispatcherName,const TaskPriority priority)21 BaseTaskDispatcher::BaseTaskDispatcher(const std::string &dispatcherName, const TaskPriority priority)
22 {
23 std::string name = dispatcherName;
24 if (name.size() == 0) {
25 name = "Dispatcher-" + std::to_string(SEQUENCE_.fetch_add(1, std::memory_order_relaxed));
26 }
27
28 dispatcherName_ = name;
29 taskPriority_ = priority;
30 }
31
SyncDispatchBarrier(const std::shared_ptr<Runnable> & task)32 ErrCode BaseTaskDispatcher::SyncDispatchBarrier(const std::shared_ptr<Runnable> &task)
33 {
34 HILOG_INFO("BaseTaskDispatcher::SyncDispatchBarrier called");
35 return SyncDispatch(task);
36 }
37
AsyncDispatchBarrier(const std::shared_ptr<Runnable> & task)38 ErrCode BaseTaskDispatcher::AsyncDispatchBarrier(const std::shared_ptr<Runnable> &task)
39 {
40 HILOG_INFO("BaseTaskDispatcher::AsyncDispatchBarrier start");
41 std::shared_ptr<Revocable> revocable = AsyncDispatch(task);
42 if (revocable != nullptr) {
43 HILOG_INFO("BaseTaskDispatcher::AsyncDispatchBarrier end");
44 return ERR_OK;
45 }
46 HILOG_ERROR("BaseTaskDispatcher::AsyncDispatchBarrier revocable is nullptr");
47 return ERR_APPEXECFWK_CHECK_FAILED;
48 }
49
CreateDispatchGroup()50 std::shared_ptr<Group> BaseTaskDispatcher::CreateDispatchGroup()
51 {
52 HILOG_INFO("BaseTaskDispatcher::CreateDispatchGroup called.");
53 return std::make_shared<GroupImpl>();
54 }
55
AsyncGroupDispatch(const std::shared_ptr<Group> & group,const std::shared_ptr<Runnable> & task)56 std::shared_ptr<Revocable> BaseTaskDispatcher::AsyncGroupDispatch(
57 const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &task)
58 {
59 HILOG_INFO("BaseTaskDispatcher::AsyncGroupDispatch called.");
60 return AsyncDispatch(task);
61 }
62
GroupDispatchWait(const std::shared_ptr<Group> & group,long timeout)63 bool BaseTaskDispatcher::GroupDispatchWait(const std::shared_ptr<Group> &group, long timeout)
64 {
65 HILOG_INFO("BaseTaskDispatcher::GroupDispatchWait start");
66 if (group == nullptr) {
67 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchWait group is nullptr");
68 return false;
69 }
70 std::shared_ptr<GroupImpl> groupImpl = CastToGroupImpl(group);
71 if (groupImpl == nullptr) {
72 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchWait groupImpl is nullptr");
73 return false;
74 }
75 bool result = groupImpl->AwaitAllTasks(timeout);
76 HILOG_INFO("BaseTaskDispatcher::GroupDispatchWait start");
77 return result;
78 }
79
GroupDispatchNotify(const std::shared_ptr<Group> & group,const std::shared_ptr<Runnable> & task)80 ErrCode BaseTaskDispatcher::GroupDispatchNotify(
81 const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &task)
82 {
83 HILOG_INFO("BaseTaskDispatcher::GroupDispatchNotify start");
84 if (group == nullptr) {
85 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify group cannot be null.");
86 return ERR_APPEXECFWK_CHECK_FAILED;
87 }
88 if (task == nullptr) {
89 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify task cannot be null");
90 return ERR_APPEXECFWK_CHECK_FAILED;
91 }
92 const std::function<void()> asyncDispatch = std::bind(&BaseTaskDispatcher::AsyncDispatch, this, task);
93 if (asyncDispatch == nullptr) {
94 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify asyncDispatch is nullptr");
95 return ERR_APPEXECFWK_CHECK_FAILED;
96 }
97 std::shared_ptr<Runnable> ptrCallback = std::make_shared<Runnable>(asyncDispatch);
98 if (ptrCallback == nullptr) {
99 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify runnable is nullptr");
100 return ERR_APPEXECFWK_CHECK_FAILED;
101 }
102 if (group == nullptr) {
103 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify group is nullptr");
104 return ERR_APPEXECFWK_CHECK_FAILED;
105 }
106 std::shared_ptr<GroupImpl> groupImpl = CastToGroupImpl(group);
107 if (groupImpl == nullptr) {
108 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify groupImpl is nullptr");
109 return ERR_APPEXECFWK_CHECK_FAILED;
110 }
111 if (groupImpl->AddNotification(ptrCallback)) {
112 HILOG_INFO("BaseTaskDispatcher::GroupDispatchNotify end");
113 return ERR_OK;
114 }
115 HILOG_ERROR("BaseTaskDispatcher::GroupDispatchNotify addNotification failed");
116 return ERR_APPEXECFWK_CHECK_FAILED;
117 }
118
ApplyDispatch(const std::shared_ptr<IteratableTask<long>> & task,long iterations)119 ErrCode BaseTaskDispatcher::ApplyDispatch(const std::shared_ptr<IteratableTask<long>> &task, long iterations)
120 {
121 HILOG_INFO("BaseTaskDispatcher::ApplyDispatch start");
122 if (task == nullptr) {
123 HILOG_ERROR("BaseTaskDispatcher::ApplyDispatch task object is not set");
124 return ERR_APPEXECFWK_CHECK_FAILED;
125 }
126
127 if (iterations <= 0) {
128 HILOG_ERROR("BaseTaskDispatcher::ApplyDispatch iterations must giant than 0");
129 return ERR_APPEXECFWK_CHECK_FAILED;
130 }
131
132 bool flag = true;
133 for (long i = 0L; i < iterations; ++i) {
134 std::shared_ptr<Runnable> ptrCallback = std::make_shared<Runnable>([task, i]() { (*task)(i); });
135 if (ptrCallback == nullptr) {
136 HILOG_ERROR("BaseTaskDispatcher::ApplyDispatch runnable is nullptr");
137 return ERR_APPEXECFWK_CHECK_FAILED;
138 }
139 std::shared_ptr<Revocable> revocable = AsyncDispatch(ptrCallback);
140 if (revocable == nullptr) {
141 HILOG_ERROR("BaseTaskDispatcher::ApplyDispatch revocable is nullptr, index:%{public}ld", i);
142 flag = false;
143 }
144 }
145 if (flag) {
146 HILOG_INFO("BaseTaskDispatcher::ApplyDispatch end");
147 return ERR_OK;
148 }
149 HILOG_INFO("BaseTaskDispatcher::ApplyDispatch failed");
150 return ERR_APPEXECFWK_CHECK_FAILED;
151 }
152
Check(const std::shared_ptr<Runnable> & task) const153 ErrCode BaseTaskDispatcher::Check(const std::shared_ptr<Runnable> &task) const
154 {
155 HILOG_INFO("BaseTaskDispatcher::Check called");
156 if (task == nullptr) {
157 HILOG_ERROR("dispatch task cannot be null.");
158 return ERR_APPEXECFWK_CHECK_FAILED;
159 }
160 return ERR_OK;
161 }
162
CastToGroupImpl(const std::shared_ptr<Group> & group)163 std::shared_ptr<GroupImpl> BaseTaskDispatcher::CastToGroupImpl(const std::shared_ptr<Group> &group)
164 {
165 HILOG_INFO("BaseTaskDispatcher::CastToGroupImpl called");
166 std::shared_ptr<GroupImpl> groupImpl_ptr = std::static_pointer_cast<GroupImpl>(group);
167 if (groupImpl_ptr != nullptr) {
168 return groupImpl_ptr;
169 }
170 HILOG_ERROR("group cannot instance of groupImpl ");
171 return nullptr;
172 }
173
GetInterceptor()174 std::shared_ptr<TaskExecuteInterceptor> BaseTaskDispatcher::GetInterceptor()
175 {
176 return nullptr;
177 }
178
GetPriority() const179 TaskPriority BaseTaskDispatcher::GetPriority() const
180 {
181 return taskPriority_;
182 }
183
TracePointBeforePost(std::shared_ptr<Task> & task,bool isAsyncTask,const std::string & dispatcherName) const184 void BaseTaskDispatcher::TracePointBeforePost(
185 std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const
186 {
187 HILOG_INFO("BaseTaskDispatcher::TracePointBeforePost called");
188 if (task == nullptr) {
189 HILOG_ERROR("BaseTaskDispatcher::TracePointBeforePost the task is nullptr");
190 return;
191 }
192 std::string taskType = isAsyncTask ? "ASYNC_TASK_STRING" : "SYNC_TASK_STRING";
193 long seq = task->GetSequence();
194 HILOG_INFO("BaseTaskDispatcher::TracePointBeforePost "
195 "log---TaskType:%{public}s,TaskSeq:%{public}ld,DispatcherName::%{public}s",
196 taskType.c_str(),
197 seq,
198 dispatcherName.c_str());
199 }
200
TracePointAfterPost(std::shared_ptr<Task> & task,bool isAsyncTask,const std::string & dispatcherName) const201 void BaseTaskDispatcher::TracePointAfterPost(
202 std::shared_ptr<Task> &task, bool isAsyncTask, const std::string &dispatcherName) const
203 {
204 HILOG_INFO("BaseTaskDispatcher::TracePointAfterPost called");
205 if (task == nullptr) {
206 HILOG_ERROR("BaseTaskDispatcher::TracePointAfterPost the task is nullptr");
207 return;
208 }
209 std::string taskType = isAsyncTask ? "ASYNC_TASK_STRING" : "SYNC_TASK_STRING";
210 long seq = task->GetSequence();
211 HILOG_INFO("BaseTaskDispatcher::TracePointAfterPost "
212 "log---TaskType:%{public}s,TaskSeq:%{public}ld,DispatcherName::%{public}s",
213 taskType.c_str(),
214 seq,
215 dispatcherName.c_str());
216 }
217 } // namespace AppExecFwk
218 } // namespace OHOS
219