blob: 49d65f766594b6b583ad31b5172c3c4e97116e15 [file] [log] [blame]
Austin Schuh520f33d2019-01-27 22:38:01 -08001#ifndef AOS_EVENTS_SHM_EVENT_LOOP_H_
2#define AOS_EVENTS_SHM_EVENT_LOOP_H_
3
Parker Schuhe4a70d62017-12-27 20:10:20 -08004#include <unordered_set>
5#include <vector>
John Park33858a32018-09-28 23:05:48 -07006#include "aos/condition.h"
7#include "aos/mutex/mutex.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08008#include "aos/events/event-loop.h"
9
10namespace aos {
11namespace internal {
12
13class WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080014class TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080015
16} // namespace internal
17
Neil Balchc8f41ed2018-01-20 22:06:53 -080018// Specialization of EventLoop that is built from queues running out of shared
John Park33858a32018-09-28 23:05:48 -070019// memory. See more details at aos/queue.h
Parker Schuhe4a70d62017-12-27 20:10:20 -080020class ShmEventLoop : public EventLoop {
21 public:
22 ShmEventLoop();
23 ~ShmEventLoop() override;
24
25 ::aos::monotonic_clock::time_point monotonic_now() override {
26 return ::aos::monotonic_clock::now();
27 }
28
29 std::unique_ptr<RawSender> MakeRawSender(const std::string &path,
30 const QueueTypeInfo &type) override;
31 std::unique_ptr<RawFetcher> MakeRawFetcher(
32 const std::string &path, const QueueTypeInfo &type) override;
33
34 void MakeRawWatcher(
35 const std::string &path, const QueueTypeInfo &type,
36 std::function<void(const aos::Message *message)> watcher) override;
37
Neil Balch229001a2018-01-07 18:22:52 -080038 TimerHandler *AddTimer(::std::function<void()> callback) override;
39
Parker Schuhe4a70d62017-12-27 20:10:20 -080040 void OnRun(std::function<void()> on_run) override;
41 void Run() override;
42 void Exit() override;
43
44 private:
45 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080046 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080047 // This ThreadState ensures that two watchers in the same loop cannot be
48 // triggered concurrently. Because watchers block threads indefinitely, this
49 // has to be shared_ptr in case the EventLoop is destroyed before the thread
50 // receives any new events.
51 class ThreadState {
52 public:
53 void WaitForStart();
54
55 bool is_running() { return loop_running_; }
56
57 void Run();
58
59 void Exit();
60
61 private:
62 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080063 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080064 friend class ShmEventLoop;
65
66 // This mutex ensures that only one watch event happens at a time.
67 aos::Mutex mutex_;
68 // Block on this until the loop starts.
69 aos::Condition loop_running_cond_{&mutex_};
70 // Used to notify watchers that the loop is done.
71 std::atomic<bool> loop_running_{false};
72 bool loop_finished_ = false;
73 };
74
75 // Exclude multiple of the same type for path.
76 void Take(const std::string &path);
77
78 std::vector<std::function<void()>> on_run_;
79 std::shared_ptr<ThreadState> thread_state_;
80
81 std::unordered_set<std::string> taken_;
82};
83
84} // namespace aos
Austin Schuh520f33d2019-01-27 22:38:01 -080085
86#endif // AOS_EVENTS_SHM_EVENT_LOOP_H_