blob: 91ca3420ac00811af926882133551a5c7f31c113 [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>
Austin Schuh6b6dfa52019-06-12 20:16:20 -07006
John Park33858a32018-09-28 23:05:48 -07007#include "aos/condition.h"
Austin Schuh6b6dfa52019-06-12 20:16:20 -07008#include "aos/events/epoll.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -08009#include "aos/events/event-loop.h"
Austin Schuh6b6dfa52019-06-12 20:16:20 -070010#include "aos/mutex/mutex.h"
Parker Schuhe4a70d62017-12-27 20:10:20 -080011
12namespace aos {
13namespace internal {
14
15class WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080016class TimerHandlerState;
Austin Schuh52d325c2019-06-23 18:59:06 -070017class PhasedLoopHandler;
Parker Schuhe4a70d62017-12-27 20:10:20 -080018
19} // namespace internal
20
Neil Balchc8f41ed2018-01-20 22:06:53 -080021// Specialization of EventLoop that is built from queues running out of shared
John Park33858a32018-09-28 23:05:48 -070022// memory. See more details at aos/queue.h
Austin Schuh81fc9cc2019-02-02 23:25:47 -080023//
24// This object must be interacted with from one thread, but the Senders and
25// Fetchers may be used from multiple threads afterwords (as long as their
26// destructors are called back in one thread again)
Parker Schuhe4a70d62017-12-27 20:10:20 -080027class ShmEventLoop : public EventLoop {
28 public:
29 ShmEventLoop();
30 ~ShmEventLoop() override;
31
32 ::aos::monotonic_clock::time_point monotonic_now() override {
33 return ::aos::monotonic_clock::now();
34 }
35
Austin Schuh6b6dfa52019-06-12 20:16:20 -070036 ::std::unique_ptr<RawSender> MakeRawSender(
37 const ::std::string &path, const QueueTypeInfo &type) override;
38 ::std::unique_ptr<RawFetcher> MakeRawFetcher(
39 const ::std::string &path, const QueueTypeInfo &type) override;
Parker Schuhe4a70d62017-12-27 20:10:20 -080040
41 void MakeRawWatcher(
Austin Schuh6b6dfa52019-06-12 20:16:20 -070042 const ::std::string &path, const QueueTypeInfo &type,
43 ::std::function<void(const aos::Message *message)> watcher) override;
Parker Schuhe4a70d62017-12-27 20:10:20 -080044
Neil Balch229001a2018-01-07 18:22:52 -080045 TimerHandler *AddTimer(::std::function<void()> callback) override;
Austin Schuh52d325c2019-06-23 18:59:06 -070046 ::aos::PhasedLoopHandler *AddPhasedLoop(
47 ::std::function<void(int)> callback,
48 const monotonic_clock::duration interval,
49 const monotonic_clock::duration offset =
50 ::std::chrono::seconds(0)) override;
Neil Balch229001a2018-01-07 18:22:52 -080051
Austin Schuh6b6dfa52019-06-12 20:16:20 -070052 void OnRun(::std::function<void()> on_run) override;
Parker Schuhe4a70d62017-12-27 20:10:20 -080053 void Run() override;
54 void Exit() override;
55
Austin Schuh6b6dfa52019-06-12 20:16:20 -070056 // TODO(austin): Add a function to register control-C call.
57
Austin Schuh3115a202019-05-27 21:02:14 -070058 void SetRuntimeRealtimePriority(int priority) override {
59 if (is_running()) {
60 ::aos::Die("Cannot set realtime priority while running.");
61 }
Austin Schuh6b6dfa52019-06-12 20:16:20 -070062 thread_state_.priority_ = priority;
Austin Schuh3115a202019-05-27 21:02:14 -070063 }
64
Parker Schuhe4a70d62017-12-27 20:10:20 -080065 private:
66 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080067 friend class internal::TimerHandlerState;
Austin Schuh52d325c2019-06-23 18:59:06 -070068 friend class internal::PhasedLoopHandler;
Parker Schuhe4a70d62017-12-27 20:10:20 -080069 // This ThreadState ensures that two watchers in the same loop cannot be
70 // triggered concurrently. Because watchers block threads indefinitely, this
71 // has to be shared_ptr in case the EventLoop is destroyed before the thread
72 // receives any new events.
73 class ThreadState {
74 public:
75 void WaitForStart();
76
77 bool is_running() { return loop_running_; }
78
Austin Schuh6b6dfa52019-06-12 20:16:20 -070079 void Start();
Parker Schuhe4a70d62017-12-27 20:10:20 -080080
81 void Exit();
82
Austin Schuh3115a202019-05-27 21:02:14 -070083 void MaybeSetCurrentThreadRealtimePriority();
84
Parker Schuhe4a70d62017-12-27 20:10:20 -080085 private:
86 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080087 friend class internal::TimerHandlerState;
Austin Schuh52d325c2019-06-23 18:59:06 -070088 friend class internal::PhasedLoopHandler;
Parker Schuhe4a70d62017-12-27 20:10:20 -080089 friend class ShmEventLoop;
90
91 // This mutex ensures that only one watch event happens at a time.
Austin Schuh6b6dfa52019-06-12 20:16:20 -070092 ::aos::Mutex mutex_;
Parker Schuhe4a70d62017-12-27 20:10:20 -080093 // Block on this until the loop starts.
Austin Schuh6b6dfa52019-06-12 20:16:20 -070094 ::aos::Condition loop_running_cond_{&mutex_};
Parker Schuhe4a70d62017-12-27 20:10:20 -080095 // Used to notify watchers that the loop is done.
Austin Schuh6b6dfa52019-06-12 20:16:20 -070096 ::std::atomic<bool> loop_running_{false};
Parker Schuhe4a70d62017-12-27 20:10:20 -080097 bool loop_finished_ = false;
Austin Schuh3115a202019-05-27 21:02:14 -070098 int priority_ = -1;
Parker Schuhe4a70d62017-12-27 20:10:20 -080099 };
100
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700101 // Tracks that we can't have multiple watchers or a sender and a watcher (or
102 // multiple senders) on a single queue (path).
103 void Take(const ::std::string &path);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800104
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700105 ::std::vector<::std::function<void()>> on_run_;
106 ThreadState thread_state_;
107 ::std::vector<::std::string> taken_;
108 internal::EPoll epoll_;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800109
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700110 ::std::vector<::std::unique_ptr<internal::TimerHandlerState>> timers_;
Austin Schuh52d325c2019-06-23 18:59:06 -0700111 ::std::vector<::std::unique_ptr<internal::PhasedLoopHandler>> phased_loops_;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700112 ::std::vector<::std::unique_ptr<internal::WatcherThreadState>> watchers_;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800113};
114
115} // namespace aos
Austin Schuh520f33d2019-01-27 22:38:01 -0800116
117#endif // AOS_EVENTS_SHM_EVENT_LOOP_H_