blob: 5db831924e0d6031de5a29b69f2b937ef9095af8 [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;
Austin Schuh9fe68f72019-08-10 19:32:03 -070053 void Run();
54 void Exit();
Parker Schuhe4a70d62017-12-27 20:10:20 -080055
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
Austin Schuh0fc3b3e2019-06-29 13:56:21 -070065 void set_name(const char *name) override;
66
Parker Schuhe4a70d62017-12-27 20:10:20 -080067 private:
68 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080069 friend class internal::TimerHandlerState;
Austin Schuh52d325c2019-06-23 18:59:06 -070070 friend class internal::PhasedLoopHandler;
Parker Schuhe4a70d62017-12-27 20:10:20 -080071 // This ThreadState ensures that two watchers in the same loop cannot be
72 // triggered concurrently. Because watchers block threads indefinitely, this
73 // has to be shared_ptr in case the EventLoop is destroyed before the thread
74 // receives any new events.
75 class ThreadState {
76 public:
77 void WaitForStart();
78
79 bool is_running() { return loop_running_; }
80
Austin Schuh6b6dfa52019-06-12 20:16:20 -070081 void Start();
Parker Schuhe4a70d62017-12-27 20:10:20 -080082
83 void Exit();
84
Austin Schuh3115a202019-05-27 21:02:14 -070085 void MaybeSetCurrentThreadRealtimePriority();
86
Austin Schuh0fc3b3e2019-06-29 13:56:21 -070087 const ::std::string &name() const { return name_; }
88
Parker Schuhe4a70d62017-12-27 20:10:20 -080089 private:
90 friend class internal::WatcherThreadState;
Neil Balch229001a2018-01-07 18:22:52 -080091 friend class internal::TimerHandlerState;
Austin Schuh52d325c2019-06-23 18:59:06 -070092 friend class internal::PhasedLoopHandler;
Parker Schuhe4a70d62017-12-27 20:10:20 -080093 friend class ShmEventLoop;
94
95 // This mutex ensures that only one watch event happens at a time.
Austin Schuh6b6dfa52019-06-12 20:16:20 -070096 ::aos::Mutex mutex_;
Parker Schuhe4a70d62017-12-27 20:10:20 -080097 // Block on this until the loop starts.
Austin Schuh6b6dfa52019-06-12 20:16:20 -070098 ::aos::Condition loop_running_cond_{&mutex_};
Parker Schuhe4a70d62017-12-27 20:10:20 -080099 // Used to notify watchers that the loop is done.
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700100 ::std::atomic<bool> loop_running_{false};
Parker Schuhe4a70d62017-12-27 20:10:20 -0800101 bool loop_finished_ = false;
Austin Schuh3115a202019-05-27 21:02:14 -0700102 int priority_ = -1;
Austin Schuh0fc3b3e2019-06-29 13:56:21 -0700103
104 // Immutable after Start is called.
105 ::std::string name_;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800106 };
107
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700108 // Tracks that we can't have multiple watchers or a sender and a watcher (or
109 // multiple senders) on a single queue (path).
110 void Take(const ::std::string &path);
Parker Schuhe4a70d62017-12-27 20:10:20 -0800111
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700112 ::std::vector<::std::function<void()>> on_run_;
113 ThreadState thread_state_;
114 ::std::vector<::std::string> taken_;
115 internal::EPoll epoll_;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800116
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700117 ::std::vector<::std::unique_ptr<internal::TimerHandlerState>> timers_;
Austin Schuh52d325c2019-06-23 18:59:06 -0700118 ::std::vector<::std::unique_ptr<internal::PhasedLoopHandler>> phased_loops_;
Austin Schuh6b6dfa52019-06-12 20:16:20 -0700119 ::std::vector<::std::unique_ptr<internal::WatcherThreadState>> watchers_;
Parker Schuhe4a70d62017-12-27 20:10:20 -0800120};
121
122} // namespace aos
Austin Schuh520f33d2019-01-27 22:38:01 -0800123
124#endif // AOS_EVENTS_SHM_EVENT_LOOP_H_