$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63577 - in trunk/boost/asio/detail: . impl
From: chris_at_[hidden]
Date: 2010-07-04 03:37:44
Author: chris_kohlhoff
Date: 2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
New Revision: 63577
URL: http://svn.boost.org/trac/boost/changeset/63577
Log:
Eliminate unnecessary uses of hash_map.
Added:
   trunk/boost/asio/detail/object_pool.hpp   (contents, props changed)
Text files modified: 
   trunk/boost/asio/detail/deadline_timer_service.hpp   |     5                                         
   trunk/boost/asio/detail/dev_poll_reactor.hpp         |     6                                         
   trunk/boost/asio/detail/epoll_reactor.hpp            |    31 ++---                                   
   trunk/boost/asio/detail/impl/dev_poll_reactor.hpp    |    21 ++-                                     
   trunk/boost/asio/detail/impl/dev_poll_reactor.ipp    |     3                                         
   trunk/boost/asio/detail/impl/epoll_reactor.hpp       |    23 ++-                                     
   trunk/boost/asio/detail/impl/epoll_reactor.ipp       |    67 ++++++++-----                           
   trunk/boost/asio/detail/impl/kqueue_reactor.hpp      |    23 ++-                                     
   trunk/boost/asio/detail/impl/kqueue_reactor.ipp      |    67 ++++++++-----                           
   trunk/boost/asio/detail/impl/select_reactor.hpp      |    23 ++-                                     
   trunk/boost/asio/detail/impl/select_reactor.ipp      |    14 +-                                      
   trunk/boost/asio/detail/impl/timer_queue.ipp         |     8                                         
   trunk/boost/asio/detail/impl/win_iocp_io_service.hpp |    14 +-                                      
   trunk/boost/asio/detail/kqueue_reactor.hpp           |    27 ++---                                   
   trunk/boost/asio/detail/select_reactor.hpp           |     6                                         
   trunk/boost/asio/detail/timer_queue.hpp              |   200 +++++++++++++++++++++++---------------- 
   trunk/boost/asio/detail/win_iocp_io_service.hpp      |     8 +                                       
   17 files changed, 321 insertions(+), 225 deletions(-)
Modified: trunk/boost/asio/detail/deadline_timer_service.hpp
==============================================================================
--- trunk/boost/asio/detail/deadline_timer_service.hpp	(original)
+++ trunk/boost/asio/detail/deadline_timer_service.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -56,6 +56,7 @@
   {
     time_type expiry;
     bool might_have_pending_waits;
+    typename timer_queue<Time_Traits>::per_timer_data timer_data;
   };
 
   // Constructor.
@@ -99,7 +100,7 @@
       ec = boost::system::error_code();
       return 0;
     }
-    std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
+    std::size_t count = scheduler_.cancel_timer(timer_queue_, impl.timer_data);
     impl.might_have_pending_waits = false;
     ec = boost::system::error_code();
     return count;
@@ -166,7 +167,7 @@
 
     impl.might_have_pending_waits = true;
 
-    scheduler_.schedule_timer(timer_queue_, impl.expiry, p.p, &impl);
+    scheduler_.schedule_timer(timer_queue_, impl.expiry, impl.timer_data, p.p);
     p.v = p.p = 0;
   }
 
Modified: trunk/boost/asio/detail/dev_poll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/dev_poll_reactor.hpp	(original)
+++ trunk/boost/asio/detail/dev_poll_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -103,12 +103,14 @@
   // specified absolute time.
   template <typename Time_Traits>
   void schedule_timer(timer_queue<Time_Traits>& queue,
-      const typename Time_Traits::time_type& time, timer_op* op, void* token);
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
 
   // Cancel the timer operations associated with the given token. Returns the
   // number of operations that have been posted or dispatched.
   template <typename Time_Traits>
-  std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer);
 
   // Run /dev/poll once until interrupted or events are ready to be dispatched.
   BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp	(original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -21,8 +21,8 @@
 
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/epoll_reactor_fwd.hpp>
-#include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/object_pool.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
@@ -46,15 +46,15 @@
     connect_op = 1, except_op = 2, max_ops = 3 };
 
   // Per-descriptor queues.
-  struct descriptor_state
+  class descriptor_state
   {
-    descriptor_state() {}
-    descriptor_state(const descriptor_state&) {}
-    void operator=(const descriptor_state&) {}
-
+    friend class epoll_reactor;
+    friend class object_pool_access;
     mutex mutex_;
     op_queue<reactor_op> op_queue_[max_ops];
     bool shutdown_;
+    descriptor_state* next_;
+    descriptor_state* prev_;
   };
 
   // Per-descriptor data.
@@ -111,13 +111,15 @@
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
-  void schedule_timer(timer_queue<Time_Traits>& timer_queue,
-      const typename Time_Traits::time_type& time, timer_op* op, void* token);
+  void schedule_timer(timer_queue<Time_Traits>& queue,
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
 
   // Cancel the timer operations associated with the given token. Returns the
   // number of operations that have been posted or dispatched.
   template <typename Time_Traits>
-  std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token);
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer);
 
   // Run epoll once until interrupted or events are ready to be dispatched.
   BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
@@ -177,15 +179,8 @@
   // Mutex to protect access to the registered descriptors.
   mutex registered_descriptors_mutex_;
 
-  // Keep track of all registered descriptors. This code relies on the fact that
-  // the hash_map implementation pools deleted nodes, meaning that we can assume
-  // our descriptor_state pointer remains valid even after the entry is removed.
-  // Technically this is not true for C++98, as that standard says that spliced
-  // elements in a list are invalidated. However, C++0x fixes this shortcoming
-  // so we'll just assume that C++98 std::list implementations will do the right
-  // thing anyway.
-  typedef detail::hash_map<socket_type, descriptor_state> descriptor_map;
-  descriptor_map registered_descriptors_;
+  // Keep track of all registered descriptors.
+  object_pool<descriptor_state> registered_descriptors_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/impl/dev_poll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/impl/dev_poll_reactor.hpp	(original)
+++ trunk/boost/asio/detail/impl/dev_poll_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -39,25 +39,30 @@
 
 template <typename Time_Traits>
 void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
-    const typename Time_Traits::time_type& time, timer_op* op, void* token)
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
-  if (!shutdown_)
+
+  if (shutdown_)
   {
-    bool earliest = queue.enqueue_timer(time, op, token);
-    io_service_.work_started();
-    if (earliest)
-      interrupter_.interrupt();
+    io_service_.post_immediate_completion(op);
+    return;
   }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  io_service_.work_started();
+  if (earliest)
+    interrupter_.interrupt();
 }
 
 template <typename Time_Traits>
 std::size_t dev_poll_reactor::cancel_timer(
-    timer_queue<Time_Traits>& queue, void* token)
+    typename timer_queue<Time_Traits>::per_timer_data& timer)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
   op_queue<operation> ops;
-  std::size_t n = queue.cancel_timer(token, ops);
+  std::size_t n = queue.cancel_timer(timer, ops);
   lock.unlock();
   io_service_.post_deferred_completions(ops);
   return n;
Modified: trunk/boost/asio/detail/impl/dev_poll_reactor.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/dev_poll_reactor.ipp	(original)
+++ trunk/boost/asio/detail/impl/dev_poll_reactor.ipp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -82,7 +82,10 @@
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
   if (shutdown_)
+  {
+    post_immediate_completion(op);
     return;
+  }
 
   if (allow_speculative)
   {
Modified: trunk/boost/asio/detail/impl/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/impl/epoll_reactor.hpp	(original)
+++ trunk/boost/asio/detail/impl/epoll_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -37,25 +37,30 @@
 
 template <typename Time_Traits>
 void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
-    const typename Time_Traits::time_type& time, timer_op* op, void* token)
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op)
 {
   mutex::scoped_lock lock(mutex_);
-  if (!shutdown_)
+
+  if (shutdown_)
   {
-    bool earliest = queue.enqueue_timer(time, op, token);
-    io_service_.work_started();
-    if (earliest)
-      update_timeout();
+    io_service_.post_immediate_completion(op);
+    return;
   }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  io_service_.work_started();
+  if (earliest)
+    update_timeout();
 }
 
 template <typename Time_Traits>
-std::size_t epoll_reactor::cancel_timer(
-    timer_queue<Time_Traits>& queue, void* token)
+std::size_t epoll_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer)
 {
   mutex::scoped_lock lock(mutex_);
   op_queue<operation> ops;
-  std::size_t n = queue.cancel_timer(token, ops);
+  std::size_t n = queue.cancel_timer(timer, ops);
   lock.unlock();
   io_service_.post_deferred_completions(ops);
   return n;
Modified: trunk/boost/asio/detail/impl/epoll_reactor.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/epoll_reactor.ipp	(original)
+++ trunk/boost/asio/detail/impl/epoll_reactor.ipp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -79,14 +79,12 @@
 
   op_queue<operation> ops;
 
-  descriptor_map::iterator iter = registered_descriptors_.begin();
-  descriptor_map::iterator end = registered_descriptors_.end();
-  while (iter != end)
+  while (descriptor_state* state = registered_descriptors_.first())
   {
     for (int i = 0; i < max_ops; ++i)
-      ops.push(iter->second.op_queue_[i]);
-    iter->second.shutdown_ = true;
-    ++iter;
+      ops.push(state->op_queue_[i]);
+    state->shutdown_ = true;
+    registered_descriptors_.free(state);
   }
 
   timer_queues_.get_all_timers(ops);
@@ -102,10 +100,7 @@
 {
   mutex::scoped_lock lock(registered_descriptors_mutex_);
 
-  descriptor_map::iterator new_entry = registered_descriptors_.insert(
-        std::make_pair(descriptor, descriptor_state())).first;
-  descriptor_data = &new_entry->second;
-
+  descriptor_data = registered_descriptors_.alloc();
   descriptor_data->shutdown_ = false;
 
   lock.unlock();
@@ -124,9 +119,20 @@
     epoll_reactor::per_descriptor_data& descriptor_data,
     reactor_op* op, bool allow_speculative)
 {
+  if (!descriptor_data)
+  {
+    op->ec_ = boost::asio::error::bad_descriptor;
+    post_immediate_completion(op);
+    return;
+  }
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
   if (descriptor_data->shutdown_)
+  {
+    post_immediate_completion(op);
     return;
+  }
 
   if (descriptor_data->op_queue_[op_type].empty())
   {
@@ -158,6 +164,9 @@
 void epoll_reactor::cancel_ops(socket_type,
     epoll_reactor::per_descriptor_data& descriptor_data)
 {
+  if (!descriptor_data)
+    return;
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
 
   op_queue<operation> ops;
@@ -179,31 +188,39 @@
 void epoll_reactor::close_descriptor(socket_type descriptor,
     epoll_reactor::per_descriptor_data& descriptor_data)
 {
+  if (!descriptor_data)
+    return;
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
   mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
 
-  // Remove the descriptor from the set of known descriptors. The descriptor
-  // will be automatically removed from the epoll set when it is closed.
-  descriptor_data->shutdown_ = true;
-
-  op_queue<operation> ops;
-  for (int i = 0; i < max_ops; ++i)
+  if (!descriptor_data->shutdown_)
   {
-    while (reactor_op* op = descriptor_data->op_queue_[i].front())
+    // Remove the descriptor from the set of known descriptors. The descriptor
+    // will be automatically removed from the epoll set when it is closed.
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
     {
-      op->ec_ = boost::asio::error::operation_aborted;
-      descriptor_data->op_queue_[i].pop();
-      ops.push(op);
+      while (reactor_op* op = descriptor_data->op_queue_[i].front())
+      {
+        op->ec_ = boost::asio::error::operation_aborted;
+        descriptor_data->op_queue_[i].pop();
+        ops.push(op);
+      }
     }
-  }
 
-  descriptor_lock.unlock();
+    descriptor_data->shutdown_ = true;
 
-  registered_descriptors_.erase(descriptor);
+    descriptor_lock.unlock();
 
-  descriptors_lock.unlock();
+    registered_descriptors_.free(descriptor_data);
+    descriptor_data = 0;
 
-  io_service_.post_deferred_completions(ops);
+    descriptors_lock.unlock();
+
+    io_service_.post_deferred_completions(ops);
+  }
 }
 
 void epoll_reactor::run(bool block, op_queue<operation>& ops)
Modified: trunk/boost/asio/detail/impl/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/impl/kqueue_reactor.hpp	(original)
+++ trunk/boost/asio/detail/impl/kqueue_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -41,25 +41,30 @@
 
 template <typename Time_Traits>
 void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
-    const typename Time_Traits::time_type& time, timer_op* op, void* token)
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
-  if (!shutdown_)
+
+  if (shutdown_)
   {
-    bool earliest = queue.enqueue_timer(time, op, token);
-    io_service_.work_started();
-    if (earliest)
-      interrupter_.interrupt();
+    io_service_.post_immediate_completion(op);
+    return;
   }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  io_service_.work_started();
+  if (earliest)
+    interrupter_.interrupt();
 }
 
 template <typename Time_Traits>
-std::size_t kqueue_reactor::cancel_timer(
-    timer_queue<Time_Traits>& queue, void* token)
+std::size_t kqueue_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
   op_queue<operation> ops;
-  std::size_t n = queue.cancel_timer(token, ops);
+  std::size_t n = queue.cancel_timer(timer, ops);
   lock.unlock();
   io_service_.post_deferred_completions(ops);
   return n;
Modified: trunk/boost/asio/detail/impl/kqueue_reactor.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/kqueue_reactor.ipp	(original)
+++ trunk/boost/asio/detail/impl/kqueue_reactor.ipp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -57,14 +57,12 @@
 
   op_queue<operation> ops;
 
-  descriptor_map::iterator iter = registered_descriptors_.begin();
-  descriptor_map::iterator end = registered_descriptors_.end();
-  while (iter != end)
+  while (descriptor_state* state = registered_descriptors_.first())
   {
     for (int i = 0; i < max_ops; ++i)
-      ops.push(iter->second.op_queue_[i]);
-    iter->second.shutdown_ = true;
-    ++iter;
+      ops.push(state->op_queue_[i]);
+    state->shutdown_ = true;
+    registered_descriptors_.free(state);
   }
 
   timer_queues_.get_all_timers(ops);
@@ -80,10 +78,7 @@
 {
   mutex::scoped_lock lock(registered_descriptors_mutex_);
 
-  descriptor_map::iterator new_entry = registered_descriptors_.insert(
-        std::make_pair(descriptor, descriptor_state())).first;
-  descriptor_data = &new_entry->second;
-
+  descriptor_data = registered_descriptors_.alloc();
   descriptor_data->shutdown_ = false;
 
   return 0;
@@ -93,9 +88,20 @@
     kqueue_reactor::per_descriptor_data& descriptor_data,
     reactor_op* op, bool allow_speculative)
 {
+  if (!descriptor_data)
+  {
+    op->ec_ = boost::asio::error::bad_descriptor;
+    post_immediate_completion(op);
+    return;
+  }
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
   if (descriptor_data->shutdown_)
+  {
+    post_immediate_completion(op);
     return;
+  }
 
   bool first = descriptor_data->op_queue_[op_type].empty();
   if (first)
@@ -151,6 +157,9 @@
 void kqueue_reactor::cancel_ops(socket_type,
     kqueue_reactor::per_descriptor_data& descriptor_data)
 {
+  if (!descriptor_data)
+    return;
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
 
   op_queue<operation> ops;
@@ -172,31 +181,39 @@
 void kqueue_reactor::close_descriptor(socket_type descriptor,
     kqueue_reactor::per_descriptor_data& descriptor_data)
 {
+  if (!descriptor_data)
+    return;
+
   mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
   mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
 
-  // Remove the descriptor from the set of known descriptors. The descriptor
-  // will be automatically removed from the kqueue set when it is closed.
-  descriptor_data->shutdown_ = true;
-
-  op_queue<operation> ops;
-  for (int i = 0; i < max_ops; ++i)
+  if (!descriptor_data->shutdown_)
   {
-    while (reactor_op* op = descriptor_data->op_queue_[i].front())
+    // Remove the descriptor from the set of known descriptors. The descriptor
+    // will be automatically removed from the kqueue set when it is closed.
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
     {
-      op->ec_ = boost::asio::error::operation_aborted;
-      descriptor_data->op_queue_[i].pop();
-      ops.push(op);
+      while (reactor_op* op = descriptor_data->op_queue_[i].front())
+      {
+        op->ec_ = boost::asio::error::operation_aborted;
+        descriptor_data->op_queue_[i].pop();
+        ops.push(op);
+      }
     }
-  }
 
-  descriptor_lock.unlock();
+    descriptor_data->shutdown_ = true;
 
-  registered_descriptors_.erase(descriptor);
+    descriptor_lock.unlock();
 
-  descriptors_lock.unlock();
+    registered_descriptors_.free(descriptor_data);
+    descriptor_data = 0;
 
-  io_service_.post_deferred_completions(ops);
+    descriptors_lock.unlock();
+
+    io_service_.post_deferred_completions(ops);
+  }
 }
 
 void kqueue_reactor::run(bool block, op_queue<operation>& ops)
Modified: trunk/boost/asio/detail/impl/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/impl/select_reactor.hpp	(original)
+++ trunk/boost/asio/detail/impl/select_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -43,25 +43,30 @@
 
 template <typename Time_Traits>
 void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
-    const typename Time_Traits::time_type& time, timer_op* op, void* token)
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
-  if (!shutdown_)
+
+  if (shutdown_)
   {
-    bool earliest = queue.enqueue_timer(time, op, token);
-    io_service_.work_started();
-    if (earliest)
-      interrupter_.interrupt();
+    io_service_.post_immediate_completion(op);
+    return;
   }
+
+  bool earliest = queue.enqueue_timer(time, timer, op);
+  io_service_.work_started();
+  if (earliest)
+    interrupter_.interrupt();
 }
 
 template <typename Time_Traits>
-std::size_t select_reactor::cancel_timer(
-    timer_queue<Time_Traits>& queue, void* token)
+std::size_t select_reactor::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
   op_queue<operation> ops;
-  std::size_t n = queue.cancel_timer(token, ops);
+  std::size_t n = queue.cancel_timer(timer, ops);
   lock.unlock();
   io_service_.post_deferred_completions(ops);
   return n;
Modified: trunk/boost/asio/detail/impl/select_reactor.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/select_reactor.ipp	(original)
+++ trunk/boost/asio/detail/impl/select_reactor.ipp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -99,13 +99,17 @@
     select_reactor::per_descriptor_data&, reactor_op* op, bool)
 {
   boost::asio::detail::mutex::scoped_lock lock(mutex_);
-  if (!shutdown_)
+
+  if (shutdown_)
   {
-    bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
-    io_service_.work_started();
-    if (first)
-      interrupter_.interrupt();
+    post_immediate_completion(op);
+    return;
   }
+
+  bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+  io_service_.work_started();
+  if (first)
+    interrupter_.interrupt();
 }
 
 void select_reactor::cancel_ops(socket_type descriptor,
Modified: trunk/boost/asio/detail/impl/timer_queue.ipp
==============================================================================
--- trunk/boost/asio/detail/impl/timer_queue.ipp	(original)
+++ trunk/boost/asio/detail/impl/timer_queue.ipp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -36,9 +36,9 @@
 }
 
 bool timer_queue<time_traits<boost::posix_time::ptime> >::enqueue_timer(
-    const time_type& time, timer_op* op, void* token)
+    const time_type& time, per_timer_data& timer, timer_op* op)
 {
-  return impl_.enqueue_timer(time, op, token);
+  return impl_.enqueue_timer(time, timer, op);
 }
 
 bool timer_queue<time_traits<boost::posix_time::ptime> >::empty() const
@@ -71,9 +71,9 @@
 }
 
 std::size_t timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer(
-    void* timer_token, op_queue<operation>& ops)
+    per_timer_data& timer, op_queue<operation>& ops)
 {
-  return impl_.cancel_timer(timer_token, ops);
+  return impl_.cancel_timer(timer, ops);
 }
 
 } // namespace detail
Modified: trunk/boost/asio/detail/impl/win_iocp_io_service.hpp
==============================================================================
--- trunk/boost/asio/detail/impl/win_iocp_io_service.hpp	(original)
+++ trunk/boost/asio/detail/impl/win_iocp_io_service.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -73,23 +73,27 @@
 
 template <typename Time_Traits>
 void win_iocp_io_service::schedule_timer(timer_queue<Time_Traits>& queue,
-    const typename Time_Traits::time_type& time, timer_op* op, void* token)
+    const typename Time_Traits::time_type& time,
+    typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op)
 {
   // If the service has been shut down we silently discard the timer.
   if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
+  {
+    post_immediate_completion(op);
     return;
+  }
 
   mutex::scoped_lock lock(dispatch_mutex_);
 
-  bool earliest = queue.enqueue_timer(time, op, token);
+  bool earliest = queue.enqueue_timer(time, timer, op);
   work_started();
   if (earliest)
     update_timeout();
 }
 
 template <typename Time_Traits>
-std::size_t win_iocp_io_service::cancel_timer(
-    timer_queue<Time_Traits>& queue, void* token)
+std::size_t win_iocp_io_service::cancel_timer(timer_queue<Time_Traits>& queue,
+    typename timer_queue<Time_Traits>::per_timer_data& timer)
 {
   // If the service has been shut down we silently ignore the cancellation.
   if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
@@ -97,7 +101,7 @@
 
   mutex::scoped_lock lock(dispatch_mutex_);
   op_queue<win_iocp_operation> ops;
-  std::size_t n = queue.cancel_timer(token, ops);
+  std::size_t n = queue.cancel_timer(timer, ops);
   post_deferred_completions(ops);
   return n;
 }
Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp	(original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -24,9 +24,9 @@
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/time.h>
-#include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/kqueue_reactor_fwd.hpp>
 #include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/object_pool.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
@@ -59,13 +59,13 @@
   // Per-descriptor queues.
   struct descriptor_state
   {
-    descriptor_state() {}
-    descriptor_state(const descriptor_state&) {}
-    void operator=(const descriptor_state&) {}
-
+    friend class kqueue_reactor;
+    friend class object_pool_access;
     mutex mutex_;
     op_queue<reactor_op> op_queue_[max_ops];
     bool shutdown_;
+    descriptor_state* next_;
+    descriptor_state* prev_;
   };
 
   // Per-descriptor data.
@@ -123,12 +123,14 @@
   // specified absolute time.
   template <typename Time_Traits>
   void schedule_timer(timer_queue<Time_Traits>& queue,
-      const typename Time_Traits::time_type& time, timer_op* op, void* token);
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
 
   // Cancel the timer operations associated with the given token. Returns the
   // number of operations that have been posted or dispatched.
   template <typename Time_Traits>
-  std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer);
 
   // Run the kqueue loop.
   BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
@@ -171,15 +173,8 @@
   // Mutex to protect access to the registered descriptors.
   mutex registered_descriptors_mutex_;
 
-  // Keep track of all registered descriptors. This code relies on the fact that
-  // the hash_map implementation pools deleted nodes, meaning that we can assume
-  // our descriptor_state pointer remains valid even after the entry is removed.
-  // Technically this is not true for C++98, as that standard says that spliced
-  // elements in a list are invalidated. However, C++0x fixes this shortcoming
-  // so we'll just assume that C++98 std::list implementations will do the right
-  // thing anyway.
-  typedef detail::hash_map<socket_type, descriptor_state> descriptor_map;
-  descriptor_map registered_descriptors_;
+  // Keep track of all registered descriptors.
+  object_pool<descriptor_state> registered_descriptors_;
 };
 
 } // namespace detail
Added: trunk/boost/asio/detail/object_pool.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/object_pool.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -0,0 +1,148 @@
+//
+// detail/object_pool.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
+#define BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Object>
+class object_pool;
+
+class object_pool_access
+{
+public:
+  template <typename Object>
+  static Object* create()
+  {
+    return new Object;
+  }
+
+  template <typename Object>
+  static void destroy(Object* o)
+  {
+    delete o;
+  }
+
+  template <typename Object>
+  static Object*& next(Object* o)
+  {
+    return o->next_;
+  }
+
+  template <typename Object>
+  static Object*& prev(Object* o)
+  {
+    return o->prev_;
+  }
+};
+
+template <typename Object>
+class object_pool
+  : private noncopyable
+{
+public:
+  // Constructor.
+  object_pool()
+    : live_list_(0),
+      free_list_(0)
+  {
+  }
+
+  // Destructor destroys all objects.
+  ~object_pool()
+  {
+    destroy_list(live_list_);
+    destroy_list(free_list_);
+  }
+
+  // Get the object at the start of the live list.
+  Object* first()
+  {
+    return live_list_;
+  }
+
+  // Allocate a new object.
+  Object* alloc()
+  {
+    Object* o = free_list_;
+    if (o)
+      free_list_ = object_pool_access::next(free_list_);
+    else
+      o = object_pool_access::create<Object>();
+
+    object_pool_access::next(o) = live_list_;
+    object_pool_access::prev(o) = 0;
+    if (live_list_)
+      object_pool_access::prev(live_list_) = o;
+    live_list_ = o;
+
+    return o;
+  }
+
+  // Free an object. Moves it to the free list. No destructors are run.
+  void free(Object* o)
+  {
+    if (live_list_ == o)
+      live_list_ = object_pool_access::next(o);
+
+    if (object_pool_access::prev(o))
+    {
+      object_pool_access::next(object_pool_access::prev(o))
+        = object_pool_access::next(o);
+    }
+
+    if (object_pool_access::next(o))
+    {
+      object_pool_access::prev(object_pool_access::next(o))
+        = object_pool_access::prev(o);
+    }
+
+    object_pool_access::next(o) = free_list_;
+    object_pool_access::prev(o) = 0;
+    free_list_ = o;
+  }
+
+private:
+  // Helper function to destroy all elements in a list.
+  void destroy_list(Object* list)
+  {
+    while (list)
+    {
+      Object* o = list;
+      list = object_pool_access::next(o);
+      object_pool_access::destroy(o);
+    }
+  }
+
+  // The list of live objects.
+  Object* live_list_;
+
+  // The free list.
+  Object* free_list_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_OBJECT_POOL_HPP
Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp	(original)
+++ trunk/boost/asio/detail/select_reactor.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -112,12 +112,14 @@
   // specified absolute time.
   template <typename Time_Traits>
   void schedule_timer(timer_queue<Time_Traits>& queue,
-      const typename Time_Traits::time_type& time, timer_op* op, void* token);
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
 
   // Cancel the timer operations associated with the given token. Returns the
   // number of operations that have been posted or dispatched.
   template <typename Time_Traits>
-  std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer);
 
   // Run select once until interrupted or events are ready to be dispatched.
   BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
Modified: trunk/boost/asio/detail/timer_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue.hpp	(original)
+++ trunk/boost/asio/detail/timer_queue.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -17,11 +17,9 @@
 
 #include <boost/asio/detail/config.hpp>
 #include <cstddef>
-#include <memory>
 #include <vector>
 #include <boost/config.hpp>
 #include <boost/limits.hpp>
-#include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/timer_op.hpp>
 #include <boost/asio/detail/timer_queue_base.hpp>
@@ -49,6 +47,26 @@
   // The duration type.
   typedef typename Time_Traits::duration_type duration_type;
 
+  // Per-timer data.
+  class per_timer_data
+  {
+  public:
+    per_timer_data() : next_(0), prev_(0) {}
+
+  private:
+    friend class timer_queue;
+
+    // The operations waiting on the timer.
+    op_queue<timer_op> op_queue_;
+
+    // The index of the timer in the heap.
+    std::size_t heap_index_;
+
+    // Pointers to adjacent timers in a linked list.
+    per_timer_data* next_;
+    per_timer_data* prev_;
+  };
+
   // Constructor.
   timer_queue()
     : timers_(),
@@ -59,35 +77,44 @@
   // 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.
-  bool enqueue_timer(const time_type& time, timer_op* op, void* token)
+  bool enqueue_timer(const time_type& time, per_timer_data& timer, timer_op* op)
   {
     // 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);
 
-    // Insert the new timer into the hash.
-    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, timer()));
-    result.first->second.op_queue_.push(op);
-    if (result.second)
+    timer.op_queue_.push(op);
+    if (timer.prev_ == 0 && &timer != timers_)
     {
+      // Insert the new timer into the linked list of active timers.
+      timer.next_ = timers_;
+      timer.prev_ = 0;
+      if (timers_)
+        timers_->prev_ = &timer;
+      timers_ = &timer;
+
       // 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);
+      if (this->is_positive_infinity(time))
+      {
+        timer.heap_index_ = (std::numeric_limits<std::size_t>::max)();
+        return false; // No need to interrupt reactor as timer never expires.
+      }
+      else
+      {
+        timer.heap_index_ = heap_.size();
+        heap_entry entry = { time, &timer };
+        heap_.push_back(entry);
+        up_heap(heap_.size() - 1);
+      }
     }
 
-    return (heap_[0] == &result.first->second);
+    return (heap_[0].timer_ == &timer);
   }
 
   // Whether there are no timers in the queue.
   virtual bool empty() const
   {
-    return heap_.empty();
+    return timers_ == 0;
   }
 
   // Get the time for the timer that is earliest in the queue.
@@ -97,7 +124,7 @@
       return max_duration;
 
     boost::posix_time::time_duration duration = Time_Traits::to_posix_duration(
-        Time_Traits::subtract(heap_[0]->time_, Time_Traits::now()));
+        Time_Traits::subtract(heap_[0].time_, Time_Traits::now()));
 
     if (duration > boost::posix_time::milliseconds(max_duration))
       duration = boost::posix_time::milliseconds(max_duration);
@@ -116,7 +143,7 @@
       return max_duration;
 
     boost::posix_time::time_duration duration = Time_Traits::to_posix_duration(
-        Time_Traits::subtract(heap_[0]->time_, Time_Traits::now()));
+        Time_Traits::subtract(heap_[0].time_, Time_Traits::now()));
 
     if (duration > boost::posix_time::microseconds(max_duration))
       duration = boost::posix_time::microseconds(max_duration);
@@ -132,77 +159,54 @@
   virtual void get_ready_timers(op_queue<operation>& ops)
   {
     const time_type now = Time_Traits::now();
-    while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0]->time_))
+    while (!heap_.empty() && !Time_Traits::less_than(now, heap_[0].time_))
     {
-      timer* t = heap_[0];
-      ops.push(t->op_queue_);
-      remove_timer(t);
+      per_timer_data* timer = heap_[0].timer_;
+      ops.push(timer->op_queue_);
+      remove_timer(*timer);
     }
   }
 
   // Dequeue all timers.
   virtual void get_all_timers(op_queue<operation>& ops)
   {
-    typename hash_map<void*, timer>::iterator i = timers_.begin();
-    typename hash_map<void*, timer>::iterator end = timers_.end();
-    while (i != end)
+    while (timers_)
     {
-      ops.push(i->second.op_queue_);
-      typename hash_map<void*, timer>::iterator old_i = i++;
-      timers_.erase(old_i);
+      per_timer_data* timer = timers_;
+      timers_ = timers_->next_;
+      ops.push(timer->op_queue_);
+      timer->next_ = 0;
+      timer->prev_ = 0;
     }
 
     heap_.clear();
-    timers_.clear();
   }
 
   // Cancel and dequeue the timers with the given token.
-  std::size_t cancel_timer(void* timer_token, op_queue<operation>& ops)
+  std::size_t cancel_timer(per_timer_data& timer, op_queue<operation>& ops)
   {
     std::size_t num_cancelled = 0;
-    typedef typename hash_map<void*, timer>::iterator iterator;
-    iterator it = timers_.find(timer_token);
-    if (it != timers_.end())
+    if (timer.prev_ != 0 || &timer == timers_)
     {
-      while (timer_op* op = it->second.op_queue_.front())
+      while (timer_op* op = timer.op_queue_.front())
       {
         op->ec_ = boost::asio::error::operation_aborted;
-        it->second.op_queue_.pop();
+        timer.op_queue_.pop();
         ops.push(op);
         ++num_cancelled;
       }
-      remove_timer(&it->second);
+      remove_timer(timer);
     }
     return num_cancelled;
   }
 
 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 operations waiting on the timer.
-    op_queue<timer_op> op_queue_;
-
-    // The index of the timer in the heap.
-    size_t heap_index_;
-
-    // The token associated with the timer.
-    void* token_;
-  };
-
   // Move the item at the given index up the heap to its correct position.
-  void up_heap(size_t index)
+  void up_heap(std::size_t index)
   {
-    size_t parent = (index - 1) / 2;
+    std::size_t parent = (index - 1) / 2;
     while (index > 0
-        && Time_Traits::less_than(heap_[index]->time_, heap_[parent]->time_))
+        && Time_Traits::less_than(heap_[index].time_, heap_[parent].time_))
     {
       swap_heap(index, parent);
       index = parent;
@@ -211,16 +215,16 @@
   }
 
   // Move the item at the given index down the heap to its correct position.
-  void down_heap(size_t index)
+  void down_heap(std::size_t index)
   {
-    size_t child = index * 2 + 1;
+    std::size_t child = index * 2 + 1;
     while (child < heap_.size())
     {
-      size_t min_child = (child + 1 == heap_.size()
+      std::size_t min_child = (child + 1 == heap_.size()
           || Time_Traits::less_than(
-            heap_[child]->time_, heap_[child + 1]->time_))
+            heap_[child].time_, heap_[child + 1].time_))
         ? child : child + 1;
-      if (Time_Traits::less_than(heap_[index]->time_, heap_[min_child]->time_))
+      if (Time_Traits::less_than(heap_[index].time_, heap_[min_child].time_))
         break;
       swap_heap(index, min_child);
       index = min_child;
@@ -229,20 +233,20 @@
   }
 
   // Swap two entries in the heap.
-  void swap_heap(size_t index1, size_t index2)
+  void swap_heap(std::size_t index1, std::size_t index2)
   {
-    timer* tmp = heap_[index1];
+    heap_entry tmp = heap_[index1];
     heap_[index1] = heap_[index2];
     heap_[index2] = tmp;
-    heap_[index1]->heap_index_ = index1;
-    heap_[index2]->heap_index_ = index2;
+    heap_[index1].timer_->heap_index_ = index1;
+    heap_[index2].timer_->heap_index_ = index2;
   }
 
   // Remove a timer from the heap and list of timers.
-  void remove_timer(timer* t)
+  void remove_timer(per_timer_data& timer)
   {
     // Remove the timer from the heap.
-    size_t index = t->heap_index_;
+    std::size_t index = timer.heap_index_;
     if (!heap_.empty() && index < heap_.size())
     {
       if (index == heap_.size() - 1)
@@ -253,27 +257,53 @@
       {
         swap_heap(index, heap_.size() - 1);
         heap_.pop_back();
-        size_t parent = (index - 1) / 2;
+        std::size_t parent = (index - 1) / 2;
         if (index > 0 && Time_Traits::less_than(
-              heap_[index]->time_, heap_[parent]->time_))
+              heap_[index].time_, heap_[parent].time_))
           up_heap(index);
         else
           down_heap(index);
       }
     }
 
-    // Remove the timer from the hash.
-    typedef typename hash_map<void*, timer>::iterator iterator;
-    iterator it = timers_.find(t->token_);
-    if (it != timers_.end())
-      timers_.erase(it);
+    // Remove the timer from the linked list of active timers.
+    if (timers_ == &timer)
+      timers_ = timer.next_;
+    if (timer.prev_)
+      timer.prev_->next_ = timer.next_;
+    if (timer.next_)
+      timer.next_->prev_= timer.prev_;
+    timer.next_ = 0;
+    timer.prev_ = 0;
+  }
+
+  // Determine if the specified absolute time is positive infinity.
+  template <typename Time_Type>
+  static bool is_positive_infinity(const Time_Type& time)
+  {
+    return false;
+  }
+
+  // Determine if the specified absolute time is positive infinity.
+  static bool is_positive_infinity(const boost::posix_time::ptime& time)
+  {
+    return time == boost::posix_time::pos_infin;
   }
 
-  // A hash of timer token to linked lists of timers.
-  hash_map<void*, timer> timers_;
+  // The head of a linked list of all active timers.
+  per_timer_data* timers_;
+
+  struct heap_entry
+  {
+    // The time when the timer should fire.
+    time_type time_;
+
+    // The associated timer with enqueued operations.
+    per_timer_data* timer_;
+  };
 
   // The heap of timers, with the earliest timer at the front.
-  std::vector<timer*> heap_;
+  std::vector<heap_entry> heap_;
 };
 
 #if !defined(BOOST_ASIO_HEADER_ONLY)
@@ -292,6 +322,10 @@
   // The duration type.
   typedef boost::posix_time::time_duration duration_type;
 
+  // Per-timer data.
+  typedef timer_queue<forwarding_posix_time_traits>::per_timer_data
+    per_timer_data;
+
   // Constructor.
   BOOST_ASIO_DECL timer_queue();
 
@@ -302,7 +336,7 @@
   // earliest in the queue, in which case the reactor's event demultiplexing
   // function call may need to be interrupted and restarted.
   BOOST_ASIO_DECL bool enqueue_timer(const time_type& time,
-      timer_op* op, void* token);
+      per_timer_data& timer, timer_op* op);
 
   // Whether there are no timers in the queue.
   BOOST_ASIO_DECL virtual bool empty() const;
@@ -321,7 +355,7 @@
 
   // Cancel and dequeue the timers with the given token.
   BOOST_ASIO_DECL std::size_t cancel_timer(
-      void* timer_token, op_queue<operation>& ops);
+      per_timer_data& timer, op_queue<operation>& ops);
 
 private:
   timer_queue<forwarding_posix_time_traits> impl_;
Modified: trunk/boost/asio/detail/win_iocp_io_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_io_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_io_service.hpp	2010-07-04 03:37:42 EDT (Sun, 04 Jul 2010)
@@ -148,13 +148,15 @@
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
-  void schedule_timer(timer_queue<Time_Traits>& timer_queue,
-      const typename Time_Traits::time_type& time, timer_op* op, void* token);
+  void schedule_timer(timer_queue<Time_Traits>& queue,
+      const typename Time_Traits::time_type& time,
+      typename timer_queue<Time_Traits>::per_timer_data& timer, timer_op* op);
 
   // Cancel the timer associated with the given token. Returns the number of
   // handlers that have been posted or dispatched.
   template <typename Time_Traits>
-  std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token);
+  std::size_t cancel_timer(timer_queue<Time_Traits>& queue,
+      typename timer_queue<Time_Traits>::per_timer_data& timer);
 
 private:
 #if defined(WINVER) && (WINVER < 0x0500)