| 2502 | if (async.sequence and async.type != AsyncRequest::Type::LoopTimeout) |
| 2503 | { |
| 2504 | // Sequenced non-timeout requests complete through sequence/manual-completion paths and are not |
| 2505 | // tracked in typed active lists. LoopTimeout is the exception: invokeExpiredTimers() scans |
| 2506 | // activeLoopTimeouts, so sequenced timers must still be tracked there. |
| 2507 | return; |
| 2508 | } |
| 2509 | switch (async.type) |
| 2510 | { |
| 2511 | case AsyncRequest::Type::LoopTimeout: { |
| 2512 | // Timeouts needs to be ordered |
| 2513 | AsyncLoopTimeout& timeout = *static_cast<AsyncLoopTimeout*>(&async); |
| 2514 | |
| 2515 | AsyncLoopTimeout* iterator = activeLoopTimeouts.front; |
| 2516 | // TODO: Replace code below with a heap or some sorted data structure... |
| 2517 | while (iterator) |
| 2518 | { |
| 2519 | // It's important to compare with '>' and not '>=' to allow timers with same expiration time to be |
| 2520 | // sub-ordered by their scheduling order |
| 2521 | if (iterator->expirationTime.milliseconds > timeout.expirationTime.milliseconds) |
| 2522 | { |
| 2523 | // middle |
| 2524 | timeout.prev = iterator->prev; |
| 2525 | timeout.next = iterator; |
| 2526 | if (timeout.prev) |
| 2527 | { |
| 2528 | timeout.prev->next = &timeout; |
| 2529 | } |
| 2530 | else |
| 2531 | { |
| 2532 | activeLoopTimeouts.front = &timeout; |