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 #pragma once
17 
18 #include <gtest/gtest_prod.h>
19 
20 #include <mutex>
21 #include <set>
22 #include <thread>
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 /**
29  * This class provides a utility to wait for a set of named conditions to occur.
30  *
31  * It will execute the trigger runnable in a separate thread (which will be joined at instance
32  * destructor time) once all conditions have been marked true.
33  */
34 class MultiConditionTrigger {
35 public:
36     explicit MultiConditionTrigger(const std::set<std::string>& conditionNames,
37                                    std::function<void()> trigger);
38 
39     MultiConditionTrigger(const MultiConditionTrigger&) = delete;
40     MultiConditionTrigger& operator=(const MultiConditionTrigger&) = delete;
41     ~MultiConditionTrigger();
42 
43     // Mark a specific condition as true. If this condition has called markComplete already or if
44     // the event was not specified in the constructor, the function is a no-op.
45     void markComplete(const std::string& conditionName);
46 
47 private:
48     void startExecutorThread();
49 
50     mutable std::mutex mMutex;
51     std::set<std::string> mRemainingConditionNames;
52     std::function<void()> mTrigger;
53     bool mCompleted;
54     std::unique_ptr<std::thread> mExecutorThread;
55 
56     FRIEND_TEST(MultiConditionTriggerTest, TestCountDownCalledBySameEventName);
57 };
58 
59 }  // namespace statsd
60 }  // namespace os
61 }  // namespace android
62