| 78 | |
| 79 | template <class Mutex> |
| 80 | void CommonSafeTimer<Mutex>::timer_thread() |
| 81 | { |
| 82 | std::unique_lock l{lock}; |
| 83 | ldout(cct,10) << "timer_thread starting" << dendl; |
| 84 | while (!stopping) { |
| 85 | auto now = clock_t::now(); |
| 86 | |
| 87 | while (!schedule.empty()) { |
| 88 | auto p = schedule.begin(); |
| 89 | |
| 90 | // is the future now? |
| 91 | #if defined(_WIN32) |
| 92 | if (p->first - now > std::chrono::milliseconds(1)) { |
| 93 | // std::condition_variable::wait_for uses SleepConditionVariableSRW |
| 94 | // on Windows, which has millisecond precision. Deltas <1ms will |
| 95 | // lead to busy loops, which should be avoided. This situation is |
| 96 | // quite common since "wait_for" often returns ~1ms earlier than |
| 97 | // requested. |
| 98 | break; |
| 99 | } |
| 100 | #else // !_WIN32 |
| 101 | if (p->first > now) { |
| 102 | break; |
| 103 | } |
| 104 | #endif |
| 105 | |
| 106 | ldout(cct, 20) << "timer_thread going to execute and remove the top of a schedule sized " << schedule.size() << dendl; |
| 107 | Context *callback = p->second; |
| 108 | events.erase(callback); |
| 109 | schedule.erase(p); |
| 110 | ldout(cct,10) << "timer_thread executing " << callback << dendl; |
| 111 | |
| 112 | if (!safe_callbacks) { |
| 113 | l.unlock(); |
| 114 | callback->complete(0); |
| 115 | l.lock(); |
| 116 | } else { |
| 117 | callback->complete(0); |
| 118 | } |
| 119 | } |
| 120 | |
| 121 | // recheck stopping if we dropped the lock |
| 122 | if (!safe_callbacks && stopping) |
| 123 | break; |
| 124 | |
| 125 | if (schedule.empty()) { |
| 126 | ldout(cct, 20) << "timer_thread going to sleep with an empty schedule" << dendl; |
| 127 | cond.wait(l); |
| 128 | } else { |
| 129 | ldout(cct, 20) << "timer_thread going to sleep with a schedule size " << schedule.size() << dendl; |
| 130 | auto when = schedule.begin()->first; |
| 131 | cond.wait_until(l, when); |
| 132 | } |
| 133 | ldout(cct,20) << "timer_thread awake" << dendl; |
| 134 | } |
| 135 | ldout(cct,10) << "timer_thread exiting" << dendl; |
| 136 | } |
| 137 | |