blob: e8ff267e547d45f3aad48bb9cf7b1ba3c2558150 [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
Austin Schuh81fc9cc2019-02-02 23:25:47 -080020//
21// This object must be interacted with from one thread, but the Senders and
22// Fetchers may be used from multiple threads afterwords (as long as their
23// destructors are called back in one thread again)
Parker Schuhe4a70d62017-12-27 20:10:20 -080024class ShmEventLoop : public EventLoop {
25 public:
26 ShmEventLoop();
27 ~ShmEventLoop() override;
28
29 ::aos::monotonic_clock::time_point monotonic_now() override {
30 return ::aos::monotonic_clock::now();
31 }
32
33 std::unique_ptr<RawSender> MakeRawSender(const std::string &path,
34 const QueueTypeInfo &type) override;
35 std::unique_ptr<RawFetcher> MakeRawFetcher(
36 const std::string &path, const QueueTypeInfo &type) override;
37
38 void MakeRawWatcher(
39 const std::string &path, const QueueTypeInfo &type,
40 std::function<void(const aos::Message *message)> watcher) override;
41
Neil Balch229001a2018-01-07 18:22:52 -080042 TimerHandler *AddTimer(::std::function<void()> callback) override;
43
Parker Schuhe4a70d62017-12-27 20:10:20 -080044 void OnRun(std::function<void()> on_run) override;
45 void Run() override;
46 void Exit() override;
47
48 private:
49 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080050 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080051 // This ThreadState ensures that two watchers in the same loop cannot be
52 // triggered concurrently. Because watchers block threads indefinitely, this
53 // has to be shared_ptr in case the EventLoop is destroyed before the thread
54 // receives any new events.
55 class ThreadState {
56 public:
57 void WaitForStart();
58
59 bool is_running() { return loop_running_; }
60
61 void Run();
62
63 void Exit();
64
65 private:
66 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080067 friend class internal::TimerHandlerState;
Parker Schuhe4a70d62017-12-27 20:10:20 -080068 friend class ShmEventLoop;
69
70 // This mutex ensures that only one watch event happens at a time.
71 aos::Mutex mutex_;
72 // Block on this until the loop starts.
73 aos::Condition loop_running_cond_{&mutex_};
74 // Used to notify watchers that the loop is done.
75 std::atomic<bool> loop_running_{false};
76 bool loop_finished_ = false;
77 };
78
79 // Exclude multiple of the same type for path.
Parker Schuhe4a70d62017-12-27 20:10:20 -080080
81 std::vector<std::function<void()>> on_run_;
82 std::shared_ptr<ThreadState> thread_state_;
83
Austin Schuh81fc9cc2019-02-02 23:25:47 -080084 void Take(const std::string &path);
85
86 std::vector<::std::string> taken_;
Parker Schuhe4a70d62017-12-27 20:10:20 -080087};
88
89} // namespace aos
Austin Schuh520f33d2019-01-27 22:38:01 -080090
91#endif // AOS_EVENTS_SHM_EVENT_LOOP_H_