|
30 | 30 |
|
31 | 31 | namespace base {
|
32 | 32 |
|
| 33 | +namespace { |
| 34 | + |
| 35 | +const size_t kReservedSizeForTimersMap = 100; |
| 36 | +const float kLoadFactorForTimersMap = 0.5; |
| 37 | + |
| 38 | +} // namespace |
| 39 | + |
33 | 40 | //--------------------------------------------------------------------------------------------------
|
34 | 41 | AsioEventDispatcher::AsioEventDispatcher(QObject* parent)
|
35 | 42 | : QAbstractEventDispatcher(parent),
|
36 | 43 | work_guard_(asio::make_work_guard(io_context_)),
|
37 |
| - timer_(io_context_) |
| 44 | + high_resolution_timer_(io_context_) |
38 | 45 | {
|
39 | 46 | LOG(LS_INFO) << "Ctor";
|
| 47 | + |
| 48 | + timers_.reserve(kReservedSizeForTimersMap); |
| 49 | + timers_.max_load_factor(kLoadFactorForTimersMap); |
40 | 50 | }
|
41 | 51 |
|
42 | 52 | //--------------------------------------------------------------------------------------------------
|
@@ -107,8 +117,8 @@ void AsioEventDispatcher::unregisterSocketNotifier(QSocketNotifier* /* notifier
|
107 | 117 | void AsioEventDispatcher::registerTimer(
|
108 | 118 | int id, int interval, Qt::TimerType type, QObject* object)
|
109 | 119 | {
|
110 |
| - TimePoint start_time = Clock::now(); |
111 |
| - TimePoint expire_time = start_time + Milliseconds(interval); |
| 120 | + const TimePoint start_time = Clock::now(); |
| 121 | + const TimePoint expire_time = start_time + Milliseconds(interval); |
112 | 122 |
|
113 | 123 | timers_.emplace(
|
114 | 124 | std::make_pair(id, TimerData(id, interval, type, object, start_time, expire_time)));
|
@@ -161,7 +171,7 @@ QList<QAbstractEventDispatcher::TimerInfo> AsioEventDispatcher::registeredTimers
|
161 | 171 | for (auto it = timers_.cbegin(), it_end = timers_.cend(); it != it_end; ++it)
|
162 | 172 | {
|
163 | 173 | if (it->second.object == object)
|
164 |
| - list.append({ it->second.id, it->second.interval, it->second.type }); |
| 174 | + list.append({ it->second.timer_id, it->second.interval, it->second.type }); |
165 | 175 | }
|
166 | 176 |
|
167 | 177 | return list;
|
@@ -233,8 +243,8 @@ void AsioEventDispatcher::unregisterEventNotifier(QWinEventNotifier* notifier)
|
233 | 243 | //--------------------------------------------------------------------------------------------------
|
234 | 244 | void AsioEventDispatcher::wakeUp()
|
235 | 245 | {
|
236 |
| - // Send an empty lambda so that call run_one inside method processEvents completes. |
237 |
| - asio::post(io_context_, []{}); |
| 246 | + // To stop run_one inside method processEvents completes. |
| 247 | + io_context_.stop(); |
238 | 248 | }
|
239 | 249 |
|
240 | 250 | //--------------------------------------------------------------------------------------------------
|
@@ -296,34 +306,32 @@ void AsioEventDispatcher::asyncWaitForNextTimer()
|
296 | 306 | return lhs.second.expire_time < rhs.second.expire_time;
|
297 | 307 | });
|
298 | 308 |
|
299 |
| - // Start waiting for the timer. |
300 |
| - timer_.expires_at(next_expire_timer->second.expire_time); |
301 |
| - timer_.async_wait(std::bind( |
302 |
| - &AsioEventDispatcher::onTimerEvent, this, std::placeholders::_1, next_expire_timer->second.id)); |
303 |
| -} |
| 309 | + const int next_timer_id = next_expire_timer->second.timer_id; |
304 | 310 |
|
305 |
| -//-------------------------------------------------------------------------------------------------- |
306 |
| -void AsioEventDispatcher::onTimerEvent(const std::error_code& error_code, int id) |
307 |
| -{ |
308 |
| - if (error_code || interrupted_.load(std::memory_order_relaxed)) |
309 |
| - return; |
| 311 | + // Start waiting for the timer. |
| 312 | + high_resolution_timer_.expires_at(next_expire_timer->second.expire_time); |
| 313 | + high_resolution_timer_.async_wait([this, next_timer_id](const std::error_code& error_code) |
| 314 | + { |
| 315 | + if (error_code || interrupted_.load(std::memory_order_relaxed)) |
| 316 | + return; |
310 | 317 |
|
311 |
| - auto it = timers_.find(id); |
312 |
| - if (it == timers_.end()) |
313 |
| - return; |
| 318 | + auto it = timers_.find(next_timer_id); |
| 319 | + if (it == timers_.end()) |
| 320 | + return; |
314 | 321 |
|
315 |
| - QCoreApplication::sendEvent(it->second.object, new QTimerEvent(id)); |
| 322 | + QCoreApplication::sendEvent(it->second.object, new QTimerEvent(next_timer_id)); |
316 | 323 |
|
317 |
| - // When calling method sendEvent the timer may have been deleted, so we look for it again. |
318 |
| - it = timers_.find(id); |
319 |
| - if (it == timers_.end()) |
320 |
| - return; |
| 324 | + // When calling method sendEvent the timer may have been deleted, so we look for it again. |
| 325 | + it = timers_.find(next_timer_id); |
| 326 | + if (it == timers_.end()) |
| 327 | + return; |
321 | 328 |
|
322 |
| - TimerData& timer = it->second; |
323 |
| - timer.start_time = Clock::now(); |
324 |
| - timer.expire_time = timer.start_time + Milliseconds(timer.interval); |
| 329 | + TimerData& timer = it->second; |
| 330 | + timer.start_time = Clock::now(); |
| 331 | + timer.expire_time = timer.start_time + Milliseconds(timer.interval); |
325 | 332 |
|
326 |
| - asyncWaitForNextTimer(); |
| 333 | + asyncWaitForNextTimer(); |
| 334 | + }); |
327 | 335 | }
|
328 | 336 |
|
329 | 337 | } // namespace base
|
0 commit comments