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 <atomic>
19 #include <chrono>
20 #include <condition_variable>
21 #include <deque>
22 #include <functional>
23 #include <mutex>
24 #include <thread>
25 
26 namespace cuttlefish {
27 
28 template <typename T>
makeSafeCallback(T * me,std::function<void (T *)> f)29 std::function<void()> makeSafeCallback(T *me, std::function<void(T *)> f) {
30   return [f, me] {
31     if (me) {
32       f(me);
33     }
34   };
35 }
36 
37 template<typename T, typename... Params>
makeSafeCallback(T * obj,void (T::* f)(const Params &...),const Params &...params)38 std::function<void()> makeSafeCallback(
39     T *obj, void (T::*f)(const Params&...), const Params&... params) {
40   return makeSafeCallback<T>(obj,
41                              [f, params...](T *me) { (me->*f)(params...); });
42 }
43 
44 template<typename T, typename... Params>
makeSafeCallback(T * obj,void (T::* f)(Params...),const Params &...params)45 std::function<void()> makeSafeCallback(
46       T *obj, void (T::*f)(Params...), const Params&... params) {
47   return makeSafeCallback<T>(obj,
48                              [f, params...](T *me) { (me->*f)(params...); });
49 }
50 
51 class ThreadLooper {
52  public:
53   ThreadLooper();
54   ~ThreadLooper();
55 
56   ThreadLooper(const ThreadLooper &) = delete;
57   ThreadLooper &operator=(const ThreadLooper &) = delete;
58 
59   typedef std::function<void()> Callback;
60   typedef int32_t Serial;
61 
62   Serial Post(Callback cb);
63   Serial PostWithDelay(std::chrono::steady_clock::duration delay, Callback cb);
64 
65   void Stop();
66 
67   // Returns true if matching event was canceled.
68   bool CancelSerial(Serial serial);
69 
70  private:
71   struct Event {
72       std::chrono::steady_clock::time_point when;
73       Callback cb;
74       Serial serial;
75 
76       bool operator<=(const Event &other) const;
77   };
78 
79   bool stopped_;
80   std::thread looper_thread_;
81 
82   std::mutex lock_;
83   std::condition_variable cond_;
84   std::deque<Event> queue_;
85   std::atomic<Serial> next_serial_;
86 
87   void ThreadLoop();
88 
89   void Insert(const Event &event);
90 };
91 
92 };  // namespace cuttlefish
93