| 219 | } |
| 220 | |
| 221 | void |
| 222 | EThread::execute_regular() |
| 223 | { |
| 224 | Event *e; |
| 225 | Que(Event, link) NegativeQueue; |
| 226 | ink_hrtime next_time; |
| 227 | ink_hrtime delta; // time spent in the event loop |
| 228 | ink_hrtime loop_start_time; // Time the loop started. |
| 229 | ink_hrtime loop_finish_time; // Time at the end of the loop. |
| 230 | |
| 231 | // Track this so we can update on boundary crossing. |
| 232 | auto prev_slice = this->metrics.prev_slice(metrics._slice.data() + (ink_get_hrtime() / HRTIME_SECOND) % Metrics::N_SLICES); |
| 233 | |
| 234 | int nq_count; |
| 235 | int ev_count; |
| 236 | |
| 237 | // A statically initialized instance we can use as a prototype for initializing other instances. |
| 238 | static const Metrics::Slice SLICE_INIT; |
| 239 | |
| 240 | Metrics::Slice *current_slice{nullptr}; |
| 241 | |
| 242 | // give priority to immediate events |
| 243 | while (!TSSystemState::is_event_system_shut_down()) { |
| 244 | loop_start_time = ink_get_hrtime(); |
| 245 | nq_count = 0; // count # of elements put on negative queue. |
| 246 | ev_count = 0; // # of events handled. |
| 247 | |
| 248 | current_slice = metrics._slice.data() + (loop_start_time / HRTIME_SECOND) % Metrics::N_SLICES; |
| 249 | metrics.current_slice.store(current_slice, std::memory_order_release); |
| 250 | if (current_slice != prev_slice) { |
| 251 | // I have observed multi-second event loops in production, making this necessary. [amc] |
| 252 | do { |
| 253 | memcpy(prev_slice = this->metrics.next_slice(prev_slice), &SLICE_INIT, sizeof(SLICE_INIT)); |
| 254 | } while (current_slice != prev_slice); |
| 255 | current_slice->record_loop_start(loop_start_time); |
| 256 | } |
| 257 | ++(current_slice->_count); // loop started, bump count. |
| 258 | |
| 259 | process_queue(&NegativeQueue, &ev_count, &nq_count); |
| 260 | |
| 261 | bool done_one; |
| 262 | do { |
| 263 | done_one = false; |
| 264 | // execute all the eligible internal events |
| 265 | EventQueue.check_ready(loop_start_time, this); |
| 266 | while ((e = EventQueue.dequeue_ready(ink_get_hrtime()))) { |
| 267 | ink_assert(e); |
| 268 | ink_assert(e->timeout_at > 0); |
| 269 | if (e->cancelled) { |
| 270 | free_event(e); |
| 271 | } else { |
| 272 | done_one = true; |
| 273 | process_event(e, e->callback_event); |
| 274 | } |
| 275 | } |
| 276 | } while (done_one); |
| 277 | |
| 278 | // execute any negative (poll) events |
no test coverage detected