1 /* 2 * Copyright (c) 2021-2022 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 "hilog_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 HILOG_INFO("GroupImpl::AwaitAllTasks start"); 34 if (count_.load() == 0) { 35 HILOG_INFO("GroupImpl::AwaitAllTasks number of count_ is zero"); 36 return true; 37 } 38 if (timeout <= 0L) { 39 HILOG_WARN("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 HILOG_INFO("GroupImpl::awaitAllTasks timeout"); 48 break; 49 } 50 HILOG_INFO("GroupImpl::awaitAllTasks success"); 51 } 52 HILOG_INFO("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 HILOG_INFO("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 */ 69 NotifyTaskDone()70void GroupImpl::NotifyTaskDone() 71 { 72 HILOG_INFO("GroupImpl::NotifyTaskDone start. Called notify a task to complete"); 73 count_.fetch_sub(1); 74 int newValue = count_.load(); 75 if (newValue > 0) { 76 return; 77 } 78 std::unique_lock<std::mutex> lock(dataMutex_); 79 condition_.notify_all(); 80 DrainNotifications(); 81 82 HILOG_INFO("GroupImpl::NotifyTaskDone end"); 83 } 84 /** 85 * @brief Adds the |notification| to notification list. 86 * If all tasks are already done, |notification| will immediately be called on current thread. 87 * Attention: If tasks are added just this time, it may not be considered. 88 * 89 * @param notification Called when all tasks done. 90 * 91 */ AddNotification(const std::shared_ptr<Runnable> & notification)92bool GroupImpl::AddNotification(const std::shared_ptr<Runnable> ¬ification) 93 { 94 HILOG_INFO("GroupImpl::AddNotification start"); 95 if (count_.load() != 0) { 96 std::unique_lock<std::mutex> lock(dataMutex_); 97 if (notifications_.size() == MAX_TASK) { 98 HILOG_WARN("GroupImpl::AddNotification called maximum number of tasks exceeded"); 99 return false; 100 } 101 if (count_.load() != 0) { 102 HILOG_INFO("GroupImpl::AddNotification called add task"); 103 notifications_.push_back(notification); 104 return true; 105 } 106 } 107 if (notification) { 108 HILOG_INFO("GroupImpl::AddNotification notification execute"); 109 (*notification)(); 110 } 111 HILOG_INFO("GroupImpl::AddNotification end"); 112 return true; 113 } 114 /** 115 * 116 * @brief Notify all tasks and remove from queue. 117 * Attention: Notifications added after all tasks done is not guaranteed. 118 */ DrainNotifications()119void GroupImpl::DrainNotifications() 120 { 121 HILOG_INFO("GroupImpl::DrainNotifications start"); 122 while (notifications_.size() > 0) { 123 std::shared_ptr<Runnable> notification = notifications_.front(); 124 notifications_.pop_front(); 125 HILOG_INFO("GroupImpl::DrainNotifications execute notification"); 126 (*notification)(); 127 } 128 HILOG_INFO("GroupImpl::DrainNotifications end"); 129 } 130 } // namespace AppExecFwk 131 } // namespace OHOS 132