diff options
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp | 334 |
1 files changed, 86 insertions, 248 deletions
diff --git a/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp b/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp index 35c8a77..164b342 100644 --- a/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp +++ b/3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp @@ -19,7 +19,6 @@ #include <boost/asio/detail/push_options.hpp> #include <cstddef> -#include <functional> #include <memory> #include <vector> #include <boost/config.hpp> @@ -27,9 +26,9 @@ #include <boost/asio/detail/pop_options.hpp> #include <boost/asio/error.hpp> -#include <boost/asio/detail/handler_alloc_helpers.hpp> #include <boost/asio/detail/hash_map.hpp> -#include <boost/asio/detail/noncopyable.hpp> +#include <boost/asio/detail/op_queue.hpp> +#include <boost/asio/detail/timer_op.hpp> #include <boost/asio/detail/timer_queue_base.hpp> namespace boost { @@ -50,50 +49,36 @@ public: // Constructor. timer_queue() : timers_(), - heap_(), - cancelled_timers_(0), - complete_timers_(0) + heap_() { } // Add a new timer to the queue. Returns true if this is the timer that is // earliest in the queue, in which case the reactor's event demultiplexing // function call may need to be interrupted and restarted. - template <typename Handler> - bool enqueue_timer(const time_type& time, Handler handler, void* token) + bool enqueue_timer(const time_type& time, timer_op* op, void* token) { // Ensure that there is space for the timer in the heap. We reserve here so // that the push_back below will not throw due to a reallocation failure. heap_.reserve(heap_.size() + 1); - // Create a new timer object. - typedef timer<Handler> timer_type; - typedef handler_alloc_traits<Handler, timer_type> alloc_traits; - raw_handler_ptr<alloc_traits> raw_ptr(handler); - handler_ptr<alloc_traits> new_timer(raw_ptr, time, handler, token); - // Insert the new timer into the hash. - typedef typename hash_map<void*, timer_base*>::iterator iterator; - typedef typename hash_map<void*, timer_base*>::value_type value_type; + typedef typename hash_map<void*, timer>::iterator iterator; + typedef typename hash_map<void*, timer>::value_type value_type; std::pair<iterator, bool> result = - timers_.insert(value_type(token, new_timer.get())); - if (!result.second) + timers_.insert(value_type(token, timer())); + result.first->second.op_queue_.push(op); + if (result.second) { - result.first->second->prev_ = new_timer.get(); - new_timer.get()->next_ = result.first->second; - result.first->second = new_timer.get(); + // Put the new timer at the correct position in the heap. + result.first->second.time_ = time; + result.first->second.heap_index_ = heap_.size(); + result.first->second.token_ = token; + heap_.push_back(&result.first->second); + up_heap(heap_.size() - 1); } - // Put the timer at the correct position in the heap. - new_timer.get()->heap_index_ = heap_.size(); - heap_.push_back(new_timer.get()); - up_heap(heap_.size() - 1); - bool is_first = (heap_[0] == new_timer.get()); - - // Ownership of the timer is transferred to the timer queue. - new_timer.release(); - - return is_first; + return (heap_[0] == &result.first->second); } // Whether there are no timers in the queue. @@ -103,226 +88,106 @@ public: } // Get the time for the timer that is earliest in the queue. - virtual boost::posix_time::time_duration wait_duration() const + virtual long wait_duration_msec(long max_duration) const { if (heap_.empty()) - return boost::posix_time::pos_infin; - return Time_Traits::to_posix_duration( + return max_duration; + + boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); - } - // Dispatch the timers that are earlier than the specified time. - virtual void dispatch_timers() - { - const time_type now = Time_Traits::now(); - while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_)) - { - timer_base* t = heap_[0]; - remove_timer(t); - t->result_ = boost::system::error_code(); - t->prev_ = 0; - t->next_ = complete_timers_; - complete_timers_ = t; - } - } + if (duration > boost::posix_time::milliseconds(max_duration)) + duration = boost::posix_time::milliseconds(max_duration); + else if (duration < boost::posix_time::milliseconds(0)) + duration = boost::posix_time::milliseconds(0); - // Cancel the timers with the given token. Any timers pending for the token - // will be notified that they have been cancelled next time - // dispatch_cancellations is called. Returns the number of timers that were - // cancelled. - std::size_t cancel_timer(void* timer_token) - { - std::size_t num_cancelled = 0; - typedef typename hash_map<void*, timer_base*>::iterator iterator; - iterator it = timers_.find(timer_token); - if (it != timers_.end()) - { - timer_base* t = it->second; - while (t) - { - timer_base* next = t->next_; - remove_timer(t); - t->prev_ = 0; - t->next_ = cancelled_timers_; - cancelled_timers_ = t; - t = next; - ++num_cancelled; - } - } - return num_cancelled; + return duration.total_milliseconds(); } - // Dispatch any pending cancels for timers. - virtual void dispatch_cancellations() + // Get the time for the timer that is earliest in the queue. + virtual long wait_duration_usec(long max_duration) const { - while (cancelled_timers_) - { - timer_base* this_timer = cancelled_timers_; - this_timer->result_ = boost::asio::error::operation_aborted; - cancelled_timers_ = this_timer->next_; - this_timer->next_ = complete_timers_; - complete_timers_ = this_timer; - } + if (heap_.empty()) + return max_duration; + + boost::posix_time::time_duration duration = Time_Traits::to_posix_duration( + Time_Traits::subtract(heap_[0]->time_, Time_Traits::now())); + + if (duration > boost::posix_time::microseconds(max_duration)) + duration = boost::posix_time::microseconds(max_duration); + else if (duration < boost::posix_time::microseconds(0)) + duration = boost::posix_time::microseconds(0); + + return duration.total_microseconds(); } - // Complete any timers that are waiting to be completed. - virtual void complete_timers() + // Dequeue all timers not later than the current time. + virtual void get_ready_timers(op_queue<operation>& ops) { - while (complete_timers_) + const time_type now = Time_Traits::now(); + while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_)) { - timer_base* this_timer = complete_timers_; - complete_timers_ = this_timer->next_; - this_timer->next_ = 0; - this_timer->complete(); + timer* t = heap_[0]; + ops.push(t->op_queue_); + remove_timer(t); } } - // Destroy all timers. - virtual void destroy_timers() + // Dequeue all timers. + virtual void get_all_timers(op_queue<operation>& ops) { - typename hash_map<void*, timer_base*>::iterator i = timers_.begin(); - typename hash_map<void*, timer_base*>::iterator end = timers_.end(); + typename hash_map<void*, timer>::iterator i = timers_.begin(); + typename hash_map<void*, timer>::iterator end = timers_.end(); while (i != end) { - timer_base* t = i->second; - typename hash_map<void*, timer_base*>::iterator old_i = i++; + ops.push(i->second.op_queue_); + typename hash_map<void*, timer>::iterator old_i = i++; timers_.erase(old_i); - destroy_timer_list(t); } + heap_.clear(); timers_.clear(); - destroy_timer_list(cancelled_timers_); - destroy_timer_list(complete_timers_); } -private: - // Base class for timer operations. Function pointers are used instead of - // virtual functions to avoid the associated overhead. - class timer_base + // Cancel and dequeue the timers with the given token. + std::size_t cancel_timer(void* timer_token, op_queue<operation>& ops) { - public: - // Delete the timer and post the handler. - void complete() - { - complete_func_(this, result_); - } - - // Delete the timer. - void destroy() - { - destroy_func_(this); - } - - protected: - typedef void (*complete_func_type)(timer_base*, - const boost::system::error_code&); - typedef void (*destroy_func_type)(timer_base*); - - // Constructor. - timer_base(complete_func_type complete_func, destroy_func_type destroy_func, - const time_type& time, void* token) - : complete_func_(complete_func), - destroy_func_(destroy_func), - time_(time), - token_(token), - next_(0), - prev_(0), - heap_index_( - std::numeric_limits<size_t>::max BOOST_PREVENT_MACRO_SUBSTITUTION()) - { - } - - // Prevent deletion through this type. - ~timer_base() + std::size_t num_cancelled = 0; + typedef typename hash_map<void*, timer>::iterator iterator; + iterator it = timers_.find(timer_token); + if (it != timers_.end()) { + while (timer_op* op = it->second.op_queue_.front()) + { + op->ec_ = boost::asio::error::operation_aborted; + it->second.op_queue_.pop(); + ops.push(op); + ++num_cancelled; + } + remove_timer(&it->second); } + return num_cancelled; + } - private: - friend class timer_queue<Time_Traits>; - - // The function to be called to delete the timer and post the handler. - complete_func_type complete_func_; - - // The function to be called to delete the timer. - destroy_func_type destroy_func_; - - // The result of the timer operation. - boost::system::error_code result_; +private: + // Structure representing a single outstanding timer. + struct timer + { + timer() {} + timer(const timer&) {} + void operator=(const timer&) {} // The time when the timer should fire. time_type time_; - // The token associated with the timer. - void* token_; - - // The next timer known to the queue. - timer_base* next_; - - // The previous timer known to the queue. - timer_base* prev_; + // The operations waiting on the timer. + op_queue<timer_op> op_queue_; // The index of the timer in the heap. size_t heap_index_; - }; - // Adaptor class template for using handlers in timers. - template <typename Handler> - class timer - : public timer_base - { - public: - // Constructor. - timer(const time_type& time, Handler handler, void* token) - : timer_base(&timer<Handler>::complete_handler, - &timer<Handler>::destroy_handler, time, token), - handler_(handler) - { - } - - // Delete the timer and post the handler. - static void complete_handler(timer_base* base, - const boost::system::error_code& result) - { - // Take ownership of the timer object. - typedef timer<Handler> this_type; - this_type* this_timer(static_cast<this_type*>(base)); - typedef handler_alloc_traits<Handler, this_type> alloc_traits; - handler_ptr<alloc_traits> ptr(this_timer->handler_, this_timer); - - // Make a copy of the error_code and the handler so that the memory can - // be deallocated before the upcall is made. - boost::system::error_code ec(result); - Handler handler(this_timer->handler_); - - // Free the memory associated with the handler. - ptr.reset(); - - // Make the upcall. - handler(ec); - } - - // Delete the timer. - static void destroy_handler(timer_base* base) - { - // Take ownership of the timer object. - typedef timer<Handler> this_type; - this_type* this_timer(static_cast<this_type*>(base)); - typedef handler_alloc_traits<Handler, this_type> alloc_traits; - handler_ptr<alloc_traits> ptr(this_timer->handler_, this_timer); - - // A sub-object of the handler may be the true owner of the memory - // associated with the handler. Consequently, a local copy of the handler - // is required to ensure that any owning sub-object remains valid until - // after we have deallocated the memory here. - Handler handler(this_timer->handler_); - (void)handler; - - // Free the memory associated with the handler. - ptr.reset(); - } - - private: - Handler handler_; + // The token associated with the timer. + void* token_; }; // Move the item at the given index up the heap to its correct position. @@ -359,7 +224,7 @@ private: // Swap two entries in the heap. void swap_heap(size_t index1, size_t index2) { - timer_base* tmp = heap_[index1]; + timer* tmp = heap_[index1]; heap_[index1] = heap_[index2]; heap_[index2] = tmp; heap_[index1]->heap_index_ = index1; @@ -367,7 +232,7 @@ private: } // Remove a timer from the heap and list of timers. - void remove_timer(timer_base* t) + void remove_timer(timer* t) { // Remove the timer from the heap. size_t index = t->heap_index_; @@ -391,44 +256,17 @@ private: } // Remove the timer from the hash. - typedef typename hash_map<void*, timer_base*>::iterator iterator; + typedef typename hash_map<void*, timer>::iterator iterator; iterator it = timers_.find(t->token_); if (it != timers_.end()) - { - if (it->second == t) - it->second = t->next_; - if (t->prev_) - t->prev_->next_ = t->next_; - if (t->next_) - t->next_->prev_ = t->prev_; - if (it->second == 0) - timers_.erase(it); - } - } - - // Destroy all timers in a linked list. - void destroy_timer_list(timer_base*& t) - { - while (t) - { - timer_base* next = t->next_; - t->next_ = 0; - t->destroy(); - t = next; - } + timers_.erase(it); } // A hash of timer token to linked lists of timers. - hash_map<void*, timer_base*> timers_; + hash_map<void*, timer> timers_; // The heap of timers, with the earliest timer at the front. - std::vector<timer_base*> heap_; - - // The list of timers to be cancelled. - timer_base* cancelled_timers_; - - // The list of timers waiting to be completed. - timer_base* complete_timers_; + std::vector<timer*> heap_; }; } // namespace detail |