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 OHOS_APP_DISPATCHER_TASK_DISPATCHER_H 17 #define OHOS_APP_DISPATCHER_TASK_DISPATCHER_H 18 19 #include <memory> 20 #include "task_priority.h" 21 #include "revocable.h" 22 #include "runnable.h" 23 #include "group.h" 24 #include "appexecfwk_errors.h" 25 namespace OHOS { 26 namespace AppExecFwk { 27 28 template<typename T> 29 using IteratableTask = std::function<void(T)>; 30 31 class TaskDispatcher { 32 public: 33 virtual ~TaskDispatcher() = default; 34 35 /** 36 * @brief Dispatches a task and waits until the task is complete in the current thread. 37 * 38 * @param runnable Indicates the task to be executed. This parameter includes all information required for the task 39 * execution. 40 */ 41 virtual ErrCode SyncDispatch(const std::shared_ptr<Runnable> &runnable) = 0; 42 43 /** 44 * @brief Asynchronously dispatches a task. 45 * 46 * <p>This method dispatches a task and returns a value immediately without waiting for the task to execute.</p> 47 * 48 * @param runnable Indicates the task to be executed. This parameter includes all information required for the task 49 * execution. 50 * @return Returns a {@link std::shared_ptr<OHOS::AppExecFwk::Revocable>} instance used for revoking the given task 51 * if it has not been invoked. 52 */ 53 virtual std::shared_ptr<Revocable> AsyncDispatch(const std::shared_ptr<Runnable> &runnable) = 0; 54 55 /** 56 * @brief Dispatches a task after the given delay. 57 * 58 * <p>This is an asynchronous execution and returns a value immediately without waiting. The task will be 59 * dispatched to the queue after the given delay specified by {@code delayMs}, and its actual execution time 60 * maybe later than the given time. The time when the task will be executed depends on the length of the queue 61 * and how busy the thread pool is. 62 * </p> 63 * 64 * @param runnable Indicates the task to be executed. This parameter includes all information required for the task 65 * execution. 66 * @param delayMs Indicates the time period that the given task has to wait before being dispatched. 67 * @return Returns a {@link std::shared_ptr<OHOS::AppExecFwk::Revocable>} instance used for revoking the given task 68 * if it has not been invoked. 69 */ 70 virtual std::shared_ptr<Revocable> DelayDispatch(const std::shared_ptr<Runnable> &runnable, long delayMs) = 0; 71 72 /** 73 * @brief Sets an execution barrier in a task group for the given task and waits for the task to be executed after all 74 * tasks in the task group are finished. 75 * 76 * <p>The current thread is blocked until the given task is complete. Incorrect use of this method may cause a 77 * deadlock. 78 * If too many threads are blocked, resources in the thread pool will be used up.</p> 79 * 80 * @param runnable Indicates the task to be executed. 81 */ 82 virtual ErrCode SyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable) = 0; 83 84 /** 85 * @brief Sets an execution barrier for the given task to be executed only after all tasks in the task group are 86 * finished. This method does not wait for the given task to execute. 87 * 88 * <p>Task execution barriers are unavailable on global task dispatchers. Example code for setting a task 89 * execution barrier:</p> 90 * 91 * <pre>{@code 92 * std::shared_ptr<ParallelTaskDispatcher> parallelTaskDispatcher = 93 * context.CreateParallelTaskDispatcher(dispatcherName, taskPriority); 94 * parallelTaskDispatcher->AsyncDispatch(std::make_shared<Runnable>([](){ 95 * sleep(1000); 96 * // sleep enough time 97 * std::cout << "before barrier" << std::endl; 98 * })); 99 * parallelTaskDispatcher->AsyncDispatchBarrier(std::make_shared<Runnable>([]() { 100 * std::cout << "Barrier" << std::endl; 101 * })); 102 * parallelTaskDispatcher->AsyncDispatch(std::make_shared<Runnable>([]() { 103 * std::cout << "after barrier" << std::endl; 104 * })); 105 * 106 * // Result will be: 1.before barrier; 2.Barrier; 3.after barrier. 107 * } 108 * </pre> 109 * 110 * @param runnable Indicates the task to be executed. This parameter includes all information required for the task 111 * execution. 112 */ 113 virtual ErrCode AsyncDispatchBarrier(const std::shared_ptr<Runnable> &runnable) = 0; 114 115 /** 116 * @brief Creates a task group. 117 * 118 * <p>The {@link std::shared_ptr<OHOS::AppExecFwk::Group>} object returned by this method does not contain any task. 119 * If you need to dispatch tasks asynchronously, you can use {@link #asyncGroupDispatch} to associate this object 120 * with multiple tasks for monitoring the execution progress of all these tasks.</p> 121 * <p>Example code for waiting for the completion of all download tasks in a task group:</p> 122 * <pre> {@code 123 * void groupTest(Context context) { 124 * std::shared_ptr<ParallelTaskDispatcher> parallelTaskDispatcher = 125 * context.CreateParallelTaskDispatcher(dispatcherName, taskPriority); 126 * // Creates a task group. 127 * std::shared_ptr<Group> group = context.CreateDispatchGroup(); 128 * // Adds asynchronous tasks to the task group. 129 * dispatcher->AsyncGroupDispatch(group, []() { 130 * // Downloads a 10 MB file. 131 * download(url1); 132 * std::cout << "Finished downloading URL 1" << std::endl; 133 * }); 134 * 135 * std::cout << "1" << std::endl; 136 * 137 * dispatcher->AsyncGroupDispatch(group, []() { 138 * // Downloads a 1 MB file. 139 * download(url2); 140 * std::cout << "Finished downloading URL 2" << std:endl; 141 * }); 142 * 143 * // Executes a new task until all tasks in the task group are complete. 144 * dispatcher->GroupDispatchNotify(group, []() { 145 * std::cout << "All tasks finished. Do shutdown." << std:endl; 146 * }); 147 * std::cout << "2" << std::endl; 148 * } 149 * 150 * @return Returns a {@link std::shared_ptr<Group>} object. 151 */ 152 virtual std::shared_ptr<Group> CreateDispatchGroup() = 0; 153 154 /** 155 * @brief Adds a task to a task group asynchronously. 156 * 157 * <p>This method returns a value immediately without waiting for the task to execute.</p> 158 * 159 * @param group Indicates the group to which the task is added. 160 * @param runnable Indicates the task to be executed. This parameter includes all information required for the task 161 * execution. 162 * @return Returns a {@link std::shared_ptr<Revocable>} instance used for revoking the given task 163 * if it has not been invoked. 164 */ 165 virtual std::shared_ptr<Revocable> AsyncGroupDispatch( 166 const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable) = 0; 167 168 /** 169 * @brief Waits all tasks in a task group to finish. 170 * 171 * @param group Indicates the task group containing the waiting tasks. 172 * @param timeout Indicates the maximum waiting time for a task. 173 * @return Returns {@code true} if all tasks are correctly executed; returns {@code false} if any task times out. 174 */ 175 virtual bool GroupDispatchWait(const std::shared_ptr<Group> &group, long timeout) = 0; 176 177 /** 178 * @brief Executes a task after all tasks in the task group are finished. 179 * 180 * @param group Indicates the task group containing the waiting tasks. 181 * @param runnable Indicates the task to be executed after all tasks are finished. 182 */ 183 virtual ErrCode GroupDispatchNotify( 184 const std::shared_ptr<Group> &group, const std::shared_ptr<Runnable> &runnable) = 0; 185 186 /** 187 * @brief Executes a task multiple times without waiting. 188 * 189 * @param task Indicates the task to be executed. This parameter includes all information required for the task 190 * execution. 191 * @param iterations Indicates the number of times the task is executed. The value must be a positive integer. 192 */ 193 virtual ErrCode ApplyDispatch(const std::shared_ptr<IteratableTask<long>> &task, long iterations) = 0; 194 }; 195 196 } // namespace AppExecFwk 197 } // namespace OHOS 198 199 #endif