blob: 3b36f40134dc2f97f46b1b6ff3936ee3404bc2c8 [file] [log] [blame]
Parker Schuhe4a70d62017-12-27 20:10:20 -08001#include <unordered_set>
2#include <vector>
3#include "aos/common/condition.h"
4#include "aos/common/mutex.h"
5#include "aos/events/event-loop.h"
6
7namespace aos {
8namespace internal {
9
10class WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080011class TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080012
13} // namespace internal
14
Neil Balchc8f41ed2018-01-20 22:06:53 -080015// Specialization of EventLoop that is built from queues running out of shared
Parker Schuhe4a70d62017-12-27 20:10:20 -080016// memory. See more details at aos/common/queue.h
17class ShmEventLoop : public EventLoop {
18 public:
19 ShmEventLoop();
20 ~ShmEventLoop() override;
21
22 ::aos::monotonic_clock::time_point monotonic_now() override {
23 return ::aos::monotonic_clock::now();
24 }
25
26 std::unique_ptr<RawSender> MakeRawSender(const std::string &path,
27 const QueueTypeInfo &type) override;
28 std::unique_ptr<RawFetcher> MakeRawFetcher(
29 const std::string &path, const QueueTypeInfo &type) override;
30
31 void MakeRawWatcher(
32 const std::string &path, const QueueTypeInfo &type,
33 std::function<void(const aos::Message *message)> watcher) override;
34
Neil Balch229001a2018-01-07 18:22:52 -080035 TimerHandler *AddTimer(::std::function<void()> callback) override;
36
Parker Schuhe4a70d62017-12-27 20:10:20 -080037 void OnRun(std::function<void()> on_run) override;
38 void Run() override;
39 void Exit() override;
40
41 private:
42 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080043 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080044 // This ThreadState ensures that two watchers in the same loop cannot be
45 // triggered concurrently. Because watchers block threads indefinitely, this
46 // has to be shared_ptr in case the EventLoop is destroyed before the thread
47 // receives any new events.
48 class ThreadState {
49 public:
50 void WaitForStart();
51
52 bool is_running() { return loop_running_; }
53
54 void Run();
55
56 void Exit();
57
58 private:
59 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080060 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080061 friend class ShmEventLoop;
62
63 // This mutex ensures that only one watch event happens at a time.
64 aos::Mutex mutex_;
65 // Block on this until the loop starts.
66 aos::Condition loop_running_cond_{&mutex_};
67 // Used to notify watchers that the loop is done.
68 std::atomic<bool> loop_running_{false};
69 bool loop_finished_ = false;
70 };
71
72 // Exclude multiple of the same type for path.
73 void Take(const std::string &path);
74
75 std::vector<std::function<void()>> on_run_;
76 std::shared_ptr<ThreadState> thread_state_;
77
78 std::unordered_set<std::string> taken_;
79};
80
81} // namespace aos