bool CEventLoop::ProcessTimers(scoped_lock & l, CMonotonicClock const& now) { if (!deadline_ || now < deadline_) { // There's no deadline or deadline has not yet expired return false; } // Update deadline_, stop at first expired timer deadline_ = CMonotonicClock(); auto it = timers_.begin(); for (; it != timers_.end(); ++it) { if (!deadline_ || it->deadline_ < deadline_) { if (it->deadline_ <= now) { break; } deadline_ = it->deadline_; } } if (it != timers_.end()) { // 'it' is now expired // deadline_ has been updated with prior timers // go through remaining elements to update deadline_ for (auto it2 = std::next(it); it2 != timers_.end(); ++it2) { if (!deadline_ || it2->deadline_ < deadline_) { deadline_ = it2->deadline_; } } CEventHandler *const handler = it->handler_; auto const id = it->id_; // Update the expired timer if (!it->interval_) { timers_.erase(it); } else { it->deadline_ = std::move(now + it->interval_); if (!deadline_ || it->deadline_ < deadline_) { deadline_ = it->deadline_; } } // Call event handler wxASSERT(!handler->removing_); active_handler_ = handler; l.unlock(); (*handler)(CTimerEvent(id)); l.lock(); active_handler_ = 0; return true; } return false; }
//------------------------------------------------------------ CTimerEvent::CTimerEvent( CTimerd::CTimerEventTypes evtype, int mon, int day, int hour, int min, CTimerd::CTimerEventRepeat evrepeat, uint32_t repeatcount) { time_t mtime = time(NULL); struct tm *tmtime = localtime(&mtime); if(mon > 0) tmtime->tm_mon = mon -1; if(day > 0) tmtime->tm_mday = day; tmtime->tm_hour = hour; tmtime->tm_min = min; CTimerEvent(evtype, (time_t) 0, mktime(tmtime), (time_t)0, evrepeat, repeatcount); }
bool CEventLoop::ProcessTimers(scoped_lock & l) { CDateTime const now(CDateTime::Now()); for (auto it = timers_.begin(); it != timers_.end(); ++it) { int diff = static_cast<int>((it->deadline_ - now).GetMilliseconds().GetValue()); if (diff <= -60000) { // Did the system time change? Update deadline it->deadline_ = now + it->ms_interval_; continue; } else if (diff <= 0) { CEventHandler *const handler = it->handler_; auto const id = it->id_; if (it->one_shot_) { timers_.erase(it); } else { it->deadline_ = now + wxTimeSpan::Milliseconds(it->ms_interval_); } bool const requestMore = !pending_events_.empty() || quit_; if (!handler->removing_) { active_handler_ = handler; l.unlock(); (*handler)(CTimerEvent(id)); l.lock(); active_handler_ = 0; } signalled_ |= requestMore; return true; } } return false; }