1 #ifndef DINIT_H_INCLUDED
2 #define DINIT_H_INCLUDED 1
6 #include <unordered_set>
13 using clock_type = dasynq::clock_type;
14 using rearm = dasynq::rearm;
15 using time_val = dasynq::time_val;
18 extern pid_t last_forked_pid;
21 // This is a mock for a Dasynq-based event loop
24 time_val current_time {0, 0};
27 void get_time(time_val &tv, dasynq::clock_type clock) noexcept
32 // Advance the simulated current time by the given amount, and call timer callbacks.
33 void advance_time(time_val amount)
35 current_time += amount;
36 auto active_copy = active_timers;
37 for (timer * t : active_copy) {
38 if (t->expiry_time >= current_time) {
40 rearm r = t->expired(*this, 1);
41 assert(r == rearm::NOOP); // others not handled
46 void send_fd_event(int fd, int events)
48 auto i = regd_fd_watchers.find(fd);
49 if (i != regd_fd_watchers.end()) {
50 fd_watcher *watcher = i->second;
51 dasynq::rearm r = watcher->fd_event(*this, fd, events);
52 if (r == dasynq::rearm::REMOVE) {
53 watcher->deregister(*this);
58 class child_proc_watcher
61 pid_t fork(eventloop_t &loop, bool reserved_child_watcher, int priority = dasynq::DEFAULT_PRIORITY)
63 bp_sys::last_forked_pid++;
64 return bp_sys::last_forked_pid;
67 void add_reserved(eventloop_t &eloop, pid_t child, int prio = dasynq::DEFAULT_PRIORITY) noexcept
72 void stop_watch(eventloop_t &eloop) noexcept
77 void deregister(eventloop_t &loop, pid_t pid) noexcept
82 void unreserve(eventloop_t &loop) noexcept
88 template <typename Derived> class child_proc_watcher_impl : public child_proc_watcher
98 void add_watch(eventloop_t &loop, int fd, int events, bool enable = true)
100 if (loop.regd_fd_watchers.find(fd) != loop.regd_fd_watchers.end()
101 || loop.regd_bidi_watchers.find(fd) != loop.regd_bidi_watchers.end()) {
102 throw std::string("must not add_watch when already active");
105 loop.regd_fd_watchers[fd] = this;
108 int get_watched_fd() noexcept
113 void set_enabled(eventloop_t &loop, bool enable) noexcept
118 void deregister(eventloop_t &loop) noexcept
120 loop.regd_fd_watchers.erase(watched_fd);
125 virtual rearm fd_event(eventloop_t & loop, int fd, int flags) = 0;
127 virtual void watch_removed() noexcept { }
130 template <typename Derived> class fd_watcher_impl : public fd_watcher
135 class bidi_fd_watcher
140 void set_watches(eventloop_t &eloop, int newFlags) noexcept
145 void add_watch(eventloop_t &eloop, int fd, int flags, int inprio = dasynq::DEFAULT_PRIORITY,
146 int outprio = dasynq::DEFAULT_PRIORITY)
148 if (eloop.regd_bidi_watchers.find(fd) != eloop.regd_bidi_watchers.end()) {
149 throw std::string("must not add_watch when already active");
151 eloop.regd_bidi_watchers[fd] = this;
155 int get_watched_fd() noexcept
160 void deregister(eventloop_t &eloop) noexcept
162 eloop.regd_bidi_watchers.erase(watched_fd);
166 // In the real implementation these are not virtual, but it is easier for testing if they are:
167 virtual rearm read_ready(eventloop_t &loop, int fd) noexcept = 0;
168 virtual rearm write_ready(eventloop_t &loop, int fd) noexcept = 0;
171 template <typename Derived> class bidi_fd_watcher_impl : public bidi_fd_watcher
178 friend class eventloop_t;
181 time_val expiry_time;
184 virtual rearm expired(eventloop_t &loop, int expiry_count)
190 void add_timer(eventloop_t &loop)
195 void arm_timer_rel(eventloop_t &loop, time_val timeout) noexcept
197 expiry_time = loop.current_time + timeout;
198 loop.active_timers.insert(this);
201 void stop_timer(eventloop_t &loop) noexcept
203 loop.active_timers.erase(this);
206 void deregister(eventloop_t &loop) noexcept
212 template <typename Derived> class timer_impl : public timer
215 virtual rearm expired(eventloop_t &loop, int expiry_count) override
217 return static_cast<Derived *>(this)->timer_expiry(loop, expiry_count);
221 std::unordered_set<timer *> active_timers;
222 std::map<int, bidi_fd_watcher *> regd_bidi_watchers;
223 std::map<int, fd_watcher *> regd_fd_watchers;
226 inline void rootfs_is_rw() noexcept
230 inline void setup_external_log() noexcept
234 inline void read_env_file(const char *env_file_path)
238 extern eventloop_t event_loop;