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