bool CEventLoop::ProcessEvent(scoped_lock & l) { Events::value_type ev{}; bool requestMore = false; if (pending_events_.empty()) { return false; } ev = pending_events_.front(); pending_events_.pop_front(); requestMore = !pending_events_.empty() || quit_; if (ev.first && !ev.first->removing_) { active_handler_ = ev.first; l.unlock(); if (ev.second) { (*ev.first)(*ev.second); } delete ev.second; l.lock(); active_handler_ = 0; } else { delete ev.second; } return requestMore; }
bool CEventLoop::ProcessEvent(scoped_lock & l) { Events::value_type ev{}; if (pending_events_.empty()) { return false; } ev = pending_events_.front(); pending_events_.pop_front(); wxASSERT(ev.first); wxASSERT(ev.second); wxASSERT(!ev.first->removing_); active_handler_ = ev.first; l.unlock(); (*ev.first)(*ev.second); delete ev.second; l.lock(); active_handler_ = 0; return true; }
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; }
std::size_t do_run_one(scoped_lock& lock, task_io_service_thread_info& this_thread, int& ec) { while (!stopped_) { if (!op_que_.empty()) { operation* o = op_que_.front(); op_que_.pop_front(); bool more_handlers = (!op_que_.empty()); if (o == &task_operation_) { task_interrupted_ = more_handlers; if (more_handlers && !one_thread_) { if (!wake_one_idle_thread_and_unlock(lock)) { lock.unlock(); } } else { lock.unlock(); } task_cleanup on_exit = {this, &lock, &this_thread}; (void)on_exit; poller_->run(!more_handlers, this_thread.private_op_que); //std::cout << __func__ << " -- task incoming" << std::endl; //std::cout << __func__ << " -- more_handlers: " << more_handlers << std::endl; } else { //std::cout << __func__ << " -- o: " << o << std::endl; std::size_t task_result = o->task_result_; if (more_handlers && !one_thread_) { wake_one_thread_and_unlock(lock); } else { lock.unlock(); } work_cleanup on_exit = {this, &lock, &this_thread}; (void)on_exit; o->do_complete(ec, task_result); //std::cout << __func__ << " -- ok" << std::endl; return 1; } } else { // nothing to run this_thread.next = first_idle_thread_; first_idle_thread_ = &this_thread; this_thread.wakeup_event->clear(lock); this_thread.wakeup_event->wait(lock); //std::cout << __func__ << " -- nothing to run" << std::endl; } } std::cout << __func__ << " -- stopped" << std::endl; return 0; }
void wake_one_thread_and_unlock(scoped_lock& lock) { if (!wake_one_idle_thread_and_unlock(lock)) { if (!task_interrupted_ && poller_) { task_interrupted_ = true; // incomplete poller_->interrupt(); } lock.unlock(); } }
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; }