33 operator const Scheduler::EventQueue::iterator&()
const
39 reset(
const Scheduler::EventQueue::iterator& newIterator)
41 m_event = newIterator;
46 Scheduler::EventQueue::iterator m_event;
50 Scheduler::EventInfo::EventInfo(
const time::nanoseconds& after,
51 const time::nanoseconds& period,
53 : m_scheduledTime(time::steady_clock::now() + after)
60 : m_scheduledTime(when)
61 , m_period(previousEvent.m_period)
62 , m_event(previousEvent.m_event)
63 , m_eventId(previousEvent.m_eventId)
68 Scheduler::EventInfo::expiresFromNow()
const
71 if (now > m_scheduledTime)
72 return time::seconds(0);
74 return m_scheduledTime - now;
79 : m_scheduledEvent(m_events.end())
80 , m_deadlineTimer(ioService)
81 , m_isEventExecuting(false)
94 const time::nanoseconds& period,
97 EventQueue::iterator i = m_events.insert(EventInfo(after, period, event));
98 i->m_eventId = make_shared<EventIdImpl>(boost::cref(i));
100 if (!m_isEventExecuting)
102 if (m_scheduledEvent == m_events.end() ||
103 *i < *m_scheduledEvent)
105 m_deadlineTimer.expires_from_now(after);
106 m_deadlineTimer.async_wait(bind(&Scheduler::onEvent,
this, _1));
107 m_scheduledEvent = i;
117 if (!static_cast<bool>(eventId) || !eventId->isValid())
120 if (static_cast<EventQueue::iterator>(*eventId) != m_scheduledEvent) {
121 m_events.erase(*eventId);
122 eventId->invalidate();
126 m_deadlineTimer.cancel();
127 m_events.erase(static_cast<EventQueue::iterator>(*eventId));
128 eventId->invalidate();
130 if (!m_isEventExecuting)
132 if (!m_events.empty())
134 m_deadlineTimer.expires_from_now(m_events.begin()->expiresFromNow());
135 m_deadlineTimer.async_wait(bind(&Scheduler::onEvent,
this, _1));
136 m_scheduledEvent = m_events.begin();
140 m_scheduledEvent = m_events.end();
146 Scheduler::onEvent(
const boost::system::error_code& error)
153 m_isEventExecuting =
true;
157 while(!m_events.empty() && m_events.begin()->m_scheduledTime <= now)
159 EventQueue::iterator head = m_events.begin();
161 Event event = head->m_event;
162 if (head->m_period < time::nanoseconds::zero())
164 head->m_eventId->invalidate();
165 m_events.erase(head);
170 EventInfo event(now + head->m_period, *head);
171 EventQueue::iterator i = m_events.insert(event);
172 i->m_eventId->reset(i);
173 m_events.erase(head);
179 if (!m_events.empty())
181 m_deadlineTimer.expires_from_now(m_events.begin()->m_scheduledTime - now);
182 m_deadlineTimer.async_wait(bind(&Scheduler::onEvent,
this, _1));
183 m_scheduledEvent = m_events.begin();
187 m_scheduledEvent = m_events.end();
190 m_isEventExecuting =
false;
EventId scheduleEvent(const time::nanoseconds &after, const Event &event)
Schedule one time event after the specified delay.
void reset(const Scheduler::EventQueue::iterator &newIterator)
shared_ptr< EventIdImpl > EventId
Private storage of information about the event.
EventIdImpl(const Scheduler::EventQueue::iterator &event)
void cancelEvent(const EventId &eventId)
Cancel scheduled event.
Scheduler(boost::asio::io_service &ioService)
EventId schedulePeriodicEvent(const time::nanoseconds &after, const time::nanoseconds &period, const Event &event)
Schedule periodic event that should be fired every specified period.