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;
23 time_val current_time {0, 0};
26 void get_time(time_val &tv, dasynq::clock_type clock) noexcept
31 // Advance the simulated current time by the given amount, and call timer callbacks.
32 void advance_time(time_val amount)
34 current_time += amount;
35 auto active_copy = active_timers;
36 for (timer * t : active_copy) {
37 if (t->expiry_time >= current_time) {
39 rearm r = t->expired(*this, 1);
40 assert(r == rearm::NOOP); // others not handled
45 class child_proc_watcher
48 pid_t fork(eventloop_t &loop, bool reserved_child_watcher, int priority = dasynq::DEFAULT_PRIORITY)
50 bp_sys::last_forked_pid++;
51 return bp_sys::last_forked_pid;
54 void add_reserved(eventloop_t &eloop, pid_t child, int prio = dasynq::DEFAULT_PRIORITY) noexcept
59 void stop_watch(eventloop_t &eloop) noexcept
64 void deregister(eventloop_t &loop, pid_t pid) noexcept
69 void unreserve(eventloop_t &loop) noexcept
75 template <typename Derived> class child_proc_watcher_impl : public child_proc_watcher
85 void add_watch(eventloop_t &loop, int fd, int events, bool enable = true)
87 if (loop.regd_fd_watchers.find(fd) != loop.regd_fd_watchers.end()
88 || loop.regd_bidi_watchers.find(fd) != loop.regd_bidi_watchers.end()) {
89 throw std::string("must not add_watch when already active");
92 loop.regd_fd_watchers[fd] = this;
95 int get_watched_fd() noexcept
100 void set_enabled(eventloop_t &loop, bool enable) noexcept
105 void deregister(eventloop_t &loop) noexcept
107 loop.regd_fd_watchers.erase(watched_fd);
111 virtual rearm fd_event(eventloop_t & loop, int fd, int flags) = 0;
114 template <typename Derived> class fd_watcher_impl : public fd_watcher
119 class bidi_fd_watcher
124 void set_watches(eventloop_t &eloop, int newFlags) noexcept
129 void add_watch(eventloop_t &eloop, int fd, int flags, int inprio = dasynq::DEFAULT_PRIORITY,
130 int outprio = dasynq::DEFAULT_PRIORITY)
132 if (eloop.regd_bidi_watchers.find(fd) != eloop.regd_bidi_watchers.end()) {
133 throw std::string("must not add_watch when already active");
135 eloop.regd_bidi_watchers[fd] = this;
139 int get_watched_fd() noexcept
144 void deregister(eventloop_t &eloop) noexcept
146 eloop.regd_bidi_watchers.erase(watched_fd);
150 // In the real implementation these are not virtual, but it is easier for testing if they are:
151 virtual rearm read_ready(eventloop_t &loop, int fd) noexcept = 0;
152 virtual rearm write_ready(eventloop_t &loop, int fd) noexcept = 0;
155 template <typename Derived> class bidi_fd_watcher_impl : public bidi_fd_watcher
162 friend class eventloop_t;
165 time_val expiry_time;
168 virtual rearm expired(eventloop_t &loop, int expiry_count)
174 void add_timer(eventloop_t &loop)
179 void arm_timer_rel(eventloop_t &loop, time_val timeout) noexcept
181 expiry_time = loop.current_time + timeout;
182 loop.active_timers.insert(this);
185 void stop_timer(eventloop_t &loop) noexcept
187 loop.active_timers.erase(this);
190 void deregister(eventloop_t &loop) noexcept
196 template <typename Derived> class timer_impl : public timer
199 virtual rearm expired(eventloop_t &loop, int expiry_count) override
201 return static_cast<Derived *>(this)->timer_expiry(loop, expiry_count);
205 std::unordered_set<timer *> active_timers;
206 std::map<int, bidi_fd_watcher *> regd_bidi_watchers;
207 std::map<int, fd_watcher *> regd_fd_watchers;
210 inline void rootfs_is_rw() noexcept
214 inline void setup_external_log() noexcept
218 inline void read_env_file(const char *env_file_path)
222 extern eventloop_t event_loop;