| 85 | } |
| 86 | |
| 87 | ::time_point process_timers(request_queue& queue) { |
| 88 | process_request_queue(queue); |
| 89 | |
| 90 | const auto now = high_resolution_clock::now(); |
| 91 | |
| 92 | while (true) { |
| 93 | if (m_timers.empty()) { |
| 94 | break; |
| 95 | } |
| 96 | |
| 97 | timer_set temp_set; |
| 98 | |
| 99 | auto first_timer_it = m_timers.begin(); // closest deadline |
| 100 | auto timer_ptr = *first_timer_it; |
| 101 | const auto is_oneshot = timer_ptr->is_oneshot(); |
| 102 | |
| 103 | if (!timer_ptr->expired(now)) { |
| 104 | // if this timer is not expired, the next ones are guaranteed not to, as |
| 105 | // the set is ordered by deadlines. |
| 106 | break; |
| 107 | } |
| 108 | |
| 109 | // we are going to modify the timer, so first we extract it |
| 110 | auto timer_node = m_timers.extract(first_timer_it); |
| 111 | |
| 112 | // we cannot use the naked node_handle according to the standard. it must |
| 113 | // be contained somewhere. |
| 114 | auto temp_it = temp_set.insert(std::move(timer_node)); |
| 115 | |
| 116 | // we fire it only if it's not cancelled |
| 117 | const auto cancelled = timer_ptr->cancelled(); |
| 118 | if (!cancelled) { |
| 119 | (*temp_it)->fire(); |
| 120 | } |
| 121 | |
| 122 | if (is_oneshot || cancelled) { |
| 123 | m_iterator_mapper.erase(timer_ptr); |
| 124 | continue; // let the timer die inside temp_set |
| 125 | } |
| 126 | |
| 127 | // regular timer, re-insert into the right position |
| 128 | timer_node = temp_set.extract(temp_it); |
| 129 | auto new_it = m_timers.insert(std::move(timer_node)); |
| 130 | // AppleClang doesn't have std::unordered_map::contains yet |
| 131 | assert(m_iterator_mapper.find(timer_ptr) != m_iterator_mapper.end()); |
| 132 | m_iterator_mapper[timer_ptr] = new_it; // update the iterator map, multiset::extract invalidates the |
| 133 | // timer |
| 134 | } |
| 135 | |
| 136 | if (m_timers.empty()) { |
| 137 | reset_containers_memory(); |
| 138 | return now + std::chrono::hours(24); |
| 139 | } |
| 140 | |
| 141 | // get the closest deadline. |
| 142 | return (**m_timers.begin()).get_deadline(); |
| 143 | } |
| 144 | }; |