Helper for scheduling the next clock tick, if applicable. Note that we don't manipulate 'timers' or 'ticks' directly so that it's clear from the callsite that this needs to be called within a 'synchronized' block. TODO(bmahler): Consider taking an optional 'now' to avoid excessive syscalls via Clock::now(nullptr).
| 117 | // TODO(bmahler): Consider taking an optional 'now' to avoid |
| 118 | // excessive syscalls via Clock::now(nullptr). |
| 119 | void scheduleTick(const map<Time, list<Timer>>& timers, set<Time>* ticks) |
| 120 | { |
| 121 | // Determine when the next 'tick' should fire. |
| 122 | const Option<Time> next = clock::next(timers); |
| 123 | |
| 124 | if (next.isSome()) { |
| 125 | // Don't schedule a 'tick' if there is a 'tick' scheduled for |
| 126 | // an earlier time, to avoid excessive pending timers. |
| 127 | if (ticks->empty() || next.get() < (*ticks->begin())) { |
| 128 | ticks->insert(next.get()); |
| 129 | |
| 130 | // The delay can be negative if the timer is expired, this |
| 131 | // is expected will result in a 'tick' firing immediately. |
| 132 | const Duration delay = next.get() - Clock::now(nullptr); |
| 133 | EventLoop::delay(delay, lambda::bind(tick, next.get())); |
| 134 | } |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | |
| 139 | // NOTE: This method must remain robust to arbitrary invocations. |