• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()19 GroupImpl::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)31 bool 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()60 void 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()70 void 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)92 bool GroupImpl::AddNotification(const std::shared_ptr<Runnable> &notification)
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()119 void 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