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 "group_impl.h" 16 #include "app_log_wrapper.h" 17 namespace OHOS { 18 namespace AppExecFwk { GroupImpl()19GroupImpl::GroupImpl() 20 { 21 count_.store(0); 22 } 23 24 /** 25 * Wait all tasks associated to this group to be done. 26 * 27 * @param timeout is the max waiting time for jobs in group execute, in ms. 28 * 29 * @return true if successfully wait. 30 */ AwaitAllTasks(long timeout)31bool GroupImpl::AwaitAllTasks(long timeout) 32 { 33 APP_LOGI("GroupImpl::AwaitAllTasks start"); 34 if (count_.load() == 0) { 35 APP_LOGI("GroupImpl::AwaitAllTasks number of count_ is zero"); 36 return true; 37 } 38 if (timeout <= 0L) { 39 APP_LOGW("GroupImpl::AwaitAllTasks timeout<=0"); 40 return false; 41 } 42 bool success = true; 43 std::unique_lock<std::mutex> lock(dataMutex_); 44 while (count_.load() > 0) { 45 if (condition_.wait_for(lock, std::chrono::milliseconds(timeout)) == std::cv_status::timeout) { 46 success = false; 47 APP_LOGI("GroupImpl::awaitAllTasks timeout"); 48 break; 49 } 50 APP_LOGI("GroupImpl::awaitAllTasks success"); 51 } 52 APP_LOGI("GroupImpl::AwaitAllTasks end"); 53 return success; 54 } 55 56 /** 57 * @brief Associates a task to this group. 58 * 59 */ Associate()60void GroupImpl::Associate() 61 { 62 APP_LOGI("GroupImpl::Associate called add a task"); 63 count_.fetch_add(1); 64 } 65 /** 66 * @brief Notify group that a task is done or canceled. 67 * 68 */ NotifyTaskDone()69void GroupImpl::NotifyTaskDone() 70 { 71 APP_LOGI("GroupImpl::NotifyTaskDone start. Called notify a task to complete"); 72 count_.fetch_sub(1); 73 int newValue = count_.load(); 74 if (newValue > 0) { 75 return; 76 } 77 std::unique_lock<std::mutex> lock(dataMutex_); 78 condition_.notify_all(); 79 DrainNotifications(); 80 81 APP_LOGI("GroupImpl::NotifyTaskDone end"); 82 } 83 /** 84 * @brief Adds the |notification| to notification list. 85 * If all tasks are already done, |notification| will immediately be called on current thread. 86 * Attention: If tasks are added just this time, it may not be considered. 87 * 88 * @param notification Called when all tasks done. 89 * 90 */ AddNotification(const std::shared_ptr<Runnable> & notification)91bool GroupImpl::AddNotification(const std::shared_ptr<Runnable> ¬ification) 92 { 93 APP_LOGI("GroupImpl::AddNotification start"); 94 if (count_.load() != 0) { 95 std::unique_lock<std::mutex> lock(dataMutex_); 96 if (notifications_.size() == MAX_TASK) { 97 APP_LOGW("GroupImpl::AddNotification called maximun number of tasks exceeded"); 98 return false; 99 } 100 if (count_.load() != 0) { 101 APP_LOGI("GroupImpl::AddNotification called add task"); 102 notifications_.push_back(notification); 103 return true; 104 } 105 } 106 if (notification) { 107 APP_LOGI("GroupImpl::AddNotification notification execute"); 108 (*notification)(); 109 } 110 APP_LOGI("GroupImpl::AddNotification end"); 111 return true; 112 } 113 /** 114 * @brief Notify all tasks and remove from queue. 115 * Attention: Notifications added after all tasks done is not guaranteed. 116 */ DrainNotifications()117void GroupImpl::DrainNotifications() 118 { 119 APP_LOGI("GroupImpl::DrainNotifications start"); 120 while (notifications_.size() > 0) { 121 std::shared_ptr<Runnable> notification = notifications_.front(); 122 notifications_.pop_front(); 123 APP_LOGI("GroupImpl::DrainNotifications execute notification"); 124 (*notification)(); 125 } 126 APP_LOGI("GroupImpl::DrainNotifications end"); 127 } 128 129 } // namespace AppExecFwk 130 } // namespace OHOS 131