summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp')
-rw-r--r--3rdParty/Boost/src/boost/asio/detail/timer_queue.hpp334
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