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