1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define STATSD_DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "MultiConditionTrigger.h"
20 
21 namespace android {
22 namespace os {
23 namespace statsd {
24 
25 using std::function;
26 using std::set;
27 using std::string;
28 
MultiConditionTrigger(const set<string> & conditionNames,function<void ()> trigger)29 MultiConditionTrigger::MultiConditionTrigger(const set<string>& conditionNames,
30                                              function<void()> trigger)
31     : mRemainingConditionNames(conditionNames),
32       mTrigger(std::move(trigger)),
33       mCompleted(mRemainingConditionNames.empty()) {
34     if (mCompleted) {
35         startExecutorThread();
36     }
37 }
38 
markComplete(const string & conditionName)39 void MultiConditionTrigger::markComplete(const string& conditionName) {
40     bool doTrigger = false;
41     {
42         std::lock_guard<std::mutex> lg(mMutex);
43         if (mCompleted) {
44             return;
45         }
46         mRemainingConditionNames.erase(conditionName);
47         mCompleted = mRemainingConditionNames.empty();
48         doTrigger = mCompleted;
49     }
50     if (doTrigger) {
51         startExecutorThread();
52     }
53 }
54 
startExecutorThread()55 void MultiConditionTrigger::startExecutorThread() {
56     mExecutorThread = std::make_unique<std::thread>([this] { mTrigger(); });
57 }
58 
~MultiConditionTrigger()59 MultiConditionTrigger::~MultiConditionTrigger() {
60     if (mExecutorThread != nullptr && mExecutorThread->joinable()) {
61         VLOG("MultiConditionTrigger waiting on execution thread termination");
62         mExecutorThread->join();
63     }
64 }
65 
66 }  // namespace statsd
67 }  // namespace os
68 }  // namespace android
69