| 65 | // after the wait. |
| 66 | template <typename T> |
| 67 | bool await(const process::Future<T>& future, const Duration& duration) |
| 68 | { |
| 69 | if (!process::Clock::paused()) { |
| 70 | return future.await(duration); |
| 71 | } |
| 72 | |
| 73 | // If the clock is paused, no new timers will expire. |
| 74 | // Future::await(duration) may hang forever because it depends on |
| 75 | // a timer to expire after 'duration'. We instead ensure all |
| 76 | // expired timers are flushed and check if the future is satisfied. |
| 77 | Stopwatch stopwatch; |
| 78 | stopwatch.start(); |
| 79 | |
| 80 | // Settle to make sure all expired timers are executed (not |
| 81 | // necessarily finished, see below). |
| 82 | process::Clock::settle(); |
| 83 | |
| 84 | while (future.isPending() && stopwatch.elapsed() < duration) { |
| 85 | // Synchronous operations and asynchronous process::Process |
| 86 | // operations should finish when the above 'settle()' returns. |
| 87 | // Other types of async operations such as io::write() may not. |
| 88 | // Therefore we wait the specified duration for it to complete. |
| 89 | // Note that nothing prevents the operations to schedule more |
| 90 | // timeouts for some time in the future. These timeouts will |
| 91 | // never be executed due to the paused process::Clock. In this |
| 92 | // case we return after the stopwatch (system clock) runs out. |
| 93 | os::sleep(Milliseconds(10)); |
| 94 | } |
| 95 | |
| 96 | return !future.isPending(); |
| 97 | } |
| 98 | |
| 99 | } // namespace internal { |
| 100 | } // namespace process { |
no test coverage detected