• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_THREAD_TASK_EXECUTOR_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_THREAD_TASK_EXECUTOR_H
18 
19 #include <functional>
20 
21 #include "base/memory/ace_type.h"
22 #include "base/thread/cancelable_callback.h"
23 #include "base/utils/noncopyable.h"
24 
25 namespace OHOS::Ace {
26 
27 class TaskExecutor : public AceType {
28     DECLARE_ACE_TYPE(TaskExecutor, AceType);
29     ACE_DISALLOW_COPY_AND_MOVE(TaskExecutor);
30 
31 public:
32     using Task = std::function<void()>;
33     using CancelableTask = CancelableCallback<void()>;
34 
35     enum class TaskType : uint32_t {
36         PLATFORM = 0,
37         UI,
38         IO,
39         GPU,
40         JS,
41         BACKGROUND,
42         UNKNOWN,
43     };
44 
45     ~TaskExecutor() override = default;
46 
47     /**
48      * Post a task to the specified thread.
49      *
50      * @param task Task which need execution.
51      * @param type FrontendType of task, used to specify the thread.
52      * @return Returns 'true' whether task has been post successfully.
53      */
PostTask(Task && task,TaskType type)54     bool PostTask(Task&& task, TaskType type) const
55     {
56         return PostDelayedTask(std::move(task), type, 0);
57     }
58 
59     /**
60      * Post a task to the specified thread.
61      *
62      * @param task Task which need execution.
63      * @param type FrontendType of task, used to specify the thread.
64      * @return Returns 'true' if task has been posted successfully.
65      */
PostTask(const Task & task,TaskType type)66     bool PostTask(const Task& task, TaskType type) const
67     {
68         return PostDelayedTask(task, type, 0);
69     }
70 
71     /**
72      * Post a task to the specified thread with a trace id.
73      *
74      * @param task Task which need execution.
75      * @param type FrontendType of task, used to specify the thread.
76      * @param id The id to trace the task.
77      * @return Returns 'true' whether task has been post successfully.
78      */
PostTaskWithTraceId(Task && task,TaskType type,int32_t id)79     bool PostTaskWithTraceId(Task&& task, TaskType type, int32_t id) const
80     {
81         Task wrappedTask = WrapTaskWithTraceId(std::move(task), id);
82         return PostDelayedTask(std::move(wrappedTask), type, 0);
83     }
84 
85     /**
86      * Post a task to the specified thread.
87      *
88      * @param task Task which need execution.
89      * @param type FrontendType of task, used to specify the thread.
90      * @param id The id to trace the task.
91      * @return Returns 'true' if task has been posted successfully.
92      */
PostTaskWithTraceId(const Task & task,TaskType type,int32_t id)93     bool PostTaskWithTraceId(const Task& task, TaskType type, int32_t id) const
94     {
95         Task wrappedTask = WrapTaskWithTraceId(Task(task), id);
96         return PostDelayedTask(std::move(wrappedTask), type, 0);
97     }
98 
99     /**
100      * Post a delayed task to the specified thread.
101      * Never allow to post a background delayed task.
102      *
103      * @param task Task which need execution.
104      * @param type FrontendType of task, used to specify the thread.
105      * @param delayTime Wait a period of time in milliseconds before execution.
106      * @return Returns 'true' if task has been posted successfully.
107      */
PostDelayedTask(Task && task,TaskType type,uint32_t delayTime)108     bool PostDelayedTask(Task&& task, TaskType type, uint32_t delayTime) const
109     {
110         if (delayTime > 0 && type == TaskType::BACKGROUND) {
111             return false;
112         }
113         return OnPostTask(std::move(task), type, delayTime);
114     }
115 
116     /**
117      * Post a delayed task to the specified thread.
118      * Never allow to post a background delayed task.
119      *
120      * @param task Task which need execution.
121      * @param type FrontendType of task, used to specify the thread.
122      * @param delayTime Wait a period of time in milliseconds before execution.
123      * @return Returns 'true' if task has been posted successfully.
124      */
PostDelayedTask(const Task & task,TaskType type,uint32_t delayTime)125     bool PostDelayedTask(const Task& task, TaskType type, uint32_t delayTime) const
126     {
127         return PostDelayedTask(Task(task), type, delayTime);
128     }
129 
130     /**
131      * Post a task to the specified thread and wait until finished executing.
132      * Never allow to post a background synchronous task.
133      *
134      * @param task Task which need execution.
135      * @param type FrontendType of task, used to specify the thread.
136      * @return Returns 'true' whether task has been executed.
137      */
PostSyncTask(Task && task,TaskType type)138     bool PostSyncTask(Task&& task, TaskType type) const
139     {
140         if (!task || type == TaskType::BACKGROUND) {
141             return false;
142         } else if (WillRunOnCurrentThread(type)) {
143             task();
144             return true;
145         }
146         return PostTaskAndWait(CancelableTask(std::move(task)), type);
147     }
148 
149     /**
150      * Post a task to the specified thread and wait until finished executing.
151      * Never allow to post a background synchronous task.
152      *
153      * @param task Task which need execution.
154      * @param type FrontendType of task, used to specify the thread.
155      * @return Returns 'true' whether task has been executed.
156      */
PostSyncTask(const Task & task,TaskType type)157     bool PostSyncTask(const Task& task, TaskType type) const
158     {
159         return PostSyncTask(Task(task), type);
160     }
161 
162     /**
163      * Post a cancelable task to the specified thread and wait until finished executing.
164      * Never allow to post a background synchronous task.
165      *
166      * @param task Task which need execution.
167      * @param type FrontendType of task, used to specify the thread.
168      * @return Returns 'true' whether task has been executed.
169      */
PostSyncTask(CancelableTask && task,TaskType type)170     bool PostSyncTask(CancelableTask&& task, TaskType type) const
171     {
172         if (!task || type == TaskType::BACKGROUND) {
173             return false;
174         } else if (WillRunOnCurrentThread(type)) {
175             CancelableTask avatar(task);
176             task();
177             return avatar.WaitUntilComplete();
178         }
179         return PostTaskAndWait(std::move(task), type);
180     }
181 
182     /**
183      * Post a cancelable task to the specified thread and wait until finished executing.
184      * Never allow to post a background synchronous task.
185      *
186      * @param task Task which need execution.
187      * @param type FrontendType of task, used to specify the thread.
188      * @return Returns 'true' whether task has been executed.
189      */
PostSyncTask(const CancelableTask & task,TaskType type)190     bool PostSyncTask(const CancelableTask& task, TaskType type) const
191     {
192         return PostSyncTask(CancelableTask(task), type);
193     }
194 
195     virtual void AddTaskObserver(Task&& callback) = 0;
196     virtual void RemoveTaskObserver() = 0;
197     virtual bool WillRunOnCurrentThread(TaskType type) const = 0;
198 
GetTid(TaskType type)199     virtual int32_t GetTid(TaskType type)
200     {
201         return 0;
202     }
203 
204 protected:
205     TaskExecutor() = default;
206 
207     virtual bool OnPostTask(Task&& task, TaskType type, uint32_t delayTime) const = 0;
208     virtual Task WrapTaskWithTraceId(Task&& task, int32_t id) const = 0;
209 
210 #ifdef ACE_DEBUG
OnPreSyncTask(TaskType type)211     virtual bool OnPreSyncTask(TaskType type) const
212     {
213         return true;
214     }
OnPostSyncTask()215     virtual void OnPostSyncTask() const {}
216 #endif
217 
218 private:
PostTaskAndWait(CancelableTask && task,TaskType type)219     bool PostTaskAndWait(CancelableTask&& task, TaskType type) const
220     {
221 #ifdef ACE_DEBUG
222         bool result = false;
223         if (OnPreSyncTask(type)) {
224             result = OnPostTask(Task(task), type, 0) && task.WaitUntilComplete();
225             OnPostSyncTask();
226         }
227         return result;
228 #else
229         return OnPostTask(Task(task), type, 0) && task.WaitUntilComplete();
230 #endif
231     }
232 };
233 
234 class SingleTaskExecutor final {
235 public:
236     using Task = TaskExecutor::Task;
237     using CancelableTask = TaskExecutor::CancelableTask;
238     using TaskType = TaskExecutor::TaskType;
239 
SingleTaskExecutor(RefPtr<TaskExecutor> && taskExecutor,TaskType type)240     SingleTaskExecutor(RefPtr<TaskExecutor>&& taskExecutor, TaskType type)
241         : taskExecutor_(std::move(taskExecutor)), type_(type)
242     {}
SingleTaskExecutor(const RefPtr<TaskExecutor> & taskExecutor,TaskType type)243     SingleTaskExecutor(const RefPtr<TaskExecutor>& taskExecutor, TaskType type)
244         : taskExecutor_(taskExecutor), type_(type)
245     {}
246     ~SingleTaskExecutor() = default;
247 
Make(RefPtr<TaskExecutor> && taskExecutor,TaskType type)248     static SingleTaskExecutor Make(RefPtr<TaskExecutor>&& taskExecutor, TaskType type)
249     {
250         return SingleTaskExecutor(std::move(taskExecutor), type);
251     }
252 
Make(const RefPtr<TaskExecutor> & taskExecutor,TaskType type)253     static SingleTaskExecutor Make(const RefPtr<TaskExecutor>& taskExecutor, TaskType type)
254     {
255         return SingleTaskExecutor(taskExecutor, type);
256     }
257 
258     /**
259      * Post a task to the specified thread.
260      *
261      * @param task Task which need execution.
262      * @return Returns 'true' whether task has been post successfully.
263      */
PostTask(Task && task)264     bool PostTask(Task&& task) const
265     {
266         return taskExecutor_ ? taskExecutor_->PostTask(std::move(task), type_) : false;
267     }
268 
269     /**
270      * Post a task to the specified thread.
271      *
272      * @param task Task which need execution.
273      * @return Returns 'true' whether task has been post successfully.
274      */
PostTask(const Task & task)275     bool PostTask(const Task& task) const
276     {
277         return taskExecutor_ ? taskExecutor_->PostTask(task, type_) : false;
278     }
279 
280     /**
281      * Post a delayed task to the specified thread.
282      * Never allow to post a background delayed task.
283      *
284      * @param task Task which need execution.
285      * @param delayTime Wait a period of time in milliseconds before execution.
286      * @return Returns 'true' if task has been posted successfully.
287      */
PostDelayedTask(Task && task,uint32_t delayTime)288     bool PostDelayedTask(Task&& task, uint32_t delayTime) const
289     {
290         return taskExecutor_ ? taskExecutor_->PostDelayedTask(std::move(task), type_, delayTime) : false;
291     }
292 
293     /**
294      * Post a delayed task to the specified thread.
295      * Never allow to post a background delayed task.
296      *
297      * @param task Task which need execution.
298      * @param delayTime Wait a period of time in milliseconds before execution.
299      * @return Returns 'true' if task has been posted successfully.
300      */
PostDelayedTask(const Task & task,uint32_t delayTime)301     bool PostDelayedTask(const Task& task, uint32_t delayTime) const
302     {
303         return taskExecutor_ ? taskExecutor_->PostDelayedTask(task, type_, delayTime) : false;
304     }
305 
306     /**
307      * Post a task to the specified thread and wait until finished executing.
308      * Never allow to post a background synchronous task.
309      *
310      * @param task Task which need execution.
311      * @return Returns 'true' whether task has been executed.
312      */
PostSyncTask(Task && task)313     bool PostSyncTask(Task&& task) const
314     {
315         return taskExecutor_ ? taskExecutor_->PostSyncTask(std::move(task), type_) : false;
316     }
317 
318     /**
319      * Post a task to the specified thread and wait until finished executing.
320      * Never allow to post a background synchronous task.
321      *
322      * @param task Task which need execution.
323      * @return Returns 'true' whether task has been executed.
324      */
PostSyncTask(const Task & task)325     bool PostSyncTask(const Task& task) const
326     {
327         return taskExecutor_ ? taskExecutor_->PostSyncTask(task, type_) : false;
328     }
329 
330     /**
331      * Post a cancelable task to the specified thread and wait until finished executing.
332      * Never allow to post a background synchronous task.
333      *
334      * @param task Task which need execution.
335      * @return Returns 'true' whether task has been executed.
336      */
PostSyncTask(CancelableTask && task)337     bool PostSyncTask(CancelableTask&& task) const
338     {
339         return taskExecutor_ ? taskExecutor_->PostSyncTask(std::move(task), type_) : false;
340     }
341 
342     /**
343      * Post a cancelable task to the specified thread and wait until finished executing.
344      * Never allow to post a background synchronous task.
345      *
346      * @param task Task which need execution.
347      * @return Returns 'true' whether task has been executed.
348      */
PostSyncTask(const CancelableTask & task)349     bool PostSyncTask(const CancelableTask& task) const
350     {
351         return taskExecutor_ ? taskExecutor_->PostSyncTask(task, type_) : false;
352     }
353 
GetTaskExecutor()354     RefPtr<TaskExecutor> GetTaskExecutor() const
355     {
356         return taskExecutor_;
357     }
358 
IsRunOnCurrentThread()359     bool IsRunOnCurrentThread() const
360     {
361         return taskExecutor_ ? taskExecutor_->WillRunOnCurrentThread(type_) : false;
362     }
363 
364 private:
365     RefPtr<TaskExecutor> taskExecutor_;
366     TaskExecutor::TaskType type_;
367 };
368 
369 } // namespace OHOS::Ace
370 
371 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_THREAD_TASK_EXECUTOR_H
372