11 #ifndef ASIO_DETAIL_TIMER_QUEUE_HPP 12 #define ASIO_DETAIL_TIMER_QUEUE_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 34 template <
typename Time_Traits>
58 std::size_t heap_index_;
78 if (timer.prev_ == 0 && &timer != timers_)
80 if (this->is_positive_infinity(time))
83 timer.heap_index_ = (std::numeric_limits<std::size_t>::max)();
89 timer.heap_index_ = heap_.size();
90 heap_entry entry = { time, &timer };
91 heap_.push_back(entry);
92 up_heap(heap_.size() - 1);
96 timer.next_ = timers_;
99 timers_->prev_ = &timer;
104 timer.op_queue_.push(op);
107 return timer.heap_index_ == 0 && timer.op_queue_.front() == op;
122 return this->to_msec(
123 Time_Traits::to_posix_duration(
124 Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),
134 return this->to_usec(
135 Time_Traits::to_posix_duration(
136 Time_Traits::subtract(heap_[0].time_, Time_Traits::now())),
145 const time_type now = Time_Traits::now();
146 while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_))
149 ops.
push(timer->op_queue_);
150 remove_timer(*timer);
161 timers_ = timers_->next_;
162 ops.
push(timer->op_queue_);
172 std::size_t max_cancelled = (std::numeric_limits<std::size_t>::max)())
174 std::size_t num_cancelled = 0;
175 if (timer.prev_ != 0 || &timer == timers_)
177 while (
wait_op* op = (num_cancelled != max_cancelled)
178 ? timer.op_queue_.front() : 0)
181 timer.op_queue_.pop();
185 if (timer.op_queue_.empty())
188 return num_cancelled;
193 void up_heap(std::size_t index)
197 std::size_t parent = (index - 1) / 2;
198 if (!Time_Traits::less_than(heap_[index].time_, heap_[parent].time_))
200 swap_heap(index, parent);
206 void down_heap(std::size_t index)
208 std::size_t child = index * 2 + 1;
209 while (child < heap_.size())
211 std::size_t min_child = (child + 1 == heap_.size()
212 || Time_Traits::less_than(
213 heap_[child].time_, heap_[child + 1].time_))
215 if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_))
217 swap_heap(index, min_child);
219 child = index * 2 + 1;
224 void swap_heap(std::size_t index1, std::size_t index2)
226 heap_entry tmp = heap_[index1];
227 heap_[index1] = heap_[index2];
229 heap_[index1].timer_->heap_index_ = index1;
230 heap_[index2].timer_->heap_index_ = index2;
237 std::size_t index = timer.heap_index_;
238 if (!heap_.empty() && index < heap_.size())
240 if (index == heap_.size() - 1)
246 swap_heap(index, heap_.size() - 1);
248 if (index > 0 && Time_Traits::less_than(
249 heap_[index].time_, heap_[(index - 1) / 2].time_))
257 if (timers_ == &timer)
258 timers_ = timer.next_;
260 timer.prev_->next_ = timer.next_;
262 timer.next_->prev_= timer.prev_;
268 template <
typename Time_Type>
269 static bool is_positive_infinity(
const Time_Type&)
275 template <
typename T,
typename TimeSystem>
276 static bool is_positive_infinity(
279 return time.is_pos_infinity();
283 template <
typename Duration>
284 long to_msec(
const Duration& d,
long max_duration)
const 288 int64_t msec = d.total_milliseconds();
291 if (msec > max_duration)
293 return static_cast<long>(msec);
297 template <
typename Duration>
298 long to_usec(
const Duration& d,
long max_duration)
const 302 int64_t usec = d.total_microseconds();
305 if (usec > max_duration)
307 return static_cast<long>(usec);
323 std::vector<heap_entry> heap_;
331 #endif // ASIO_DETAIL_TIMER_QUEUE_HPP virtual void get_ready_timers(op_queue< operation > &ops)
virtual long wait_duration_usec(long max_duration) const
Time_Traits::time_type time_type
virtual bool empty() const
virtual long wait_duration_msec(long max_duration) const
virtual void get_all_timers(op_queue< operation > &ops)
bool enqueue_timer(const time_type &time, per_timer_data &timer, wait_op *op)
Time_Traits::duration_type duration_type
std::size_t cancel_timer(per_timer_data &timer, op_queue< operation > &ops, std::size_t max_cancelled=(std::numeric_limits< std::size_t >::max)())