$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r60380 - in trunk/boost/asio: . detail impl ip posix ssl/detail windows
From: chris_at_[hidden]
Date: 2010-03-09 07:50:16
Author: chris_kohlhoff
Date: 2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
New Revision: 60380
URL: http://svn.boost.org/trac/boost/changeset/60380
Log:
Reworked implementation.
Added:
   trunk/boost/asio/detail/base_from_completion_cond.hpp   (contents, props changed)
   trunk/boost/asio/detail/buffer_sequence_adapter.hpp   (contents, props changed)
   trunk/boost/asio/detail/completion_handler.hpp   (contents, props changed)
   trunk/boost/asio/detail/fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/gcc_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/gcc_x86_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/macos_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/null_buffers_op.hpp   (contents, props changed)
   trunk/boost/asio/detail/null_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/op_queue.hpp   (contents, props changed)
   trunk/boost/asio/detail/operation.hpp   (contents, props changed)
   trunk/boost/asio/detail/reactor.hpp   (contents, props changed)
   trunk/boost/asio/detail/reactor_fwd.hpp   (contents, props changed)
   trunk/boost/asio/detail/reactor_op.hpp   (contents, props changed)
   trunk/boost/asio/detail/solaris_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/task_io_service_operation.hpp   (contents, props changed)
   trunk/boost/asio/detail/timer_op.hpp   (contents, props changed)
   trunk/boost/asio/detail/timer_queue_fwd.hpp   (contents, props changed)
   trunk/boost/asio/detail/timer_queue_set.hpp   (contents, props changed)
   trunk/boost/asio/detail/timer_scheduler.hpp   (contents, props changed)
   trunk/boost/asio/detail/timer_scheduler_fwd.hpp   (contents, props changed)
   trunk/boost/asio/detail/win_fenced_block.hpp   (contents, props changed)
   trunk/boost/asio/detail/win_iocp_operation.hpp   (contents, props changed)
Removed:
   trunk/boost/asio/detail/const_buffers_iterator.hpp
   trunk/boost/asio/detail/handler_base_from_member.hpp
   trunk/boost/asio/detail/handler_queue.hpp
   trunk/boost/asio/detail/indirect_handler_queue.hpp
   trunk/boost/asio/detail/task_io_service_2lock.hpp
Text files modified: 
   trunk/boost/asio/buffers_iterator.hpp                     |   138 +++                                     
   trunk/boost/asio/datagram_socket_service.hpp              |    29                                         
   trunk/boost/asio/deadline_timer_service.hpp               |    36                                         
   trunk/boost/asio/detail/consuming_buffers.hpp             |    54 +                                       
   trunk/boost/asio/detail/deadline_timer_service.hpp        |    63                                         
   trunk/boost/asio/detail/dev_poll_reactor.hpp              |   408 ++-------                               
   trunk/boost/asio/detail/dev_poll_reactor_fwd.hpp          |     1                                         
   trunk/boost/asio/detail/epoll_reactor.hpp                 |   749 ++++++-----------                       
   trunk/boost/asio/detail/epoll_reactor_fwd.hpp             |     1                                         
   trunk/boost/asio/detail/hash_map.hpp                      |    93 +                                       
   trunk/boost/asio/detail/kqueue_reactor.hpp                |   476 ++--------                              
   trunk/boost/asio/detail/kqueue_reactor_fwd.hpp            |     1                                         
   trunk/boost/asio/detail/null_event.hpp                    |     6                                         
   trunk/boost/asio/detail/posix_event.hpp                   |    10                                         
   trunk/boost/asio/detail/posix_mutex.hpp                   |    22                                         
   trunk/boost/asio/detail/reactive_descriptor_service.hpp   |   486 ++++------                              
   trunk/boost/asio/detail/reactive_serial_port_service.hpp  |    25                                         
   trunk/boost/asio/detail/reactive_socket_service.hpp       |  1160 ++++++++++++--------------              
   trunk/boost/asio/detail/reactor_op_queue.hpp              |   383 +-------                                
   trunk/boost/asio/detail/resolver_service.hpp              |   241 +++-                                    
   trunk/boost/asio/detail/select_reactor.hpp                |   455 +++-------                              
   trunk/boost/asio/detail/service_registry.hpp              |   175 ++-                                     
   trunk/boost/asio/detail/strand_service.hpp                |   445 +++-------                              
   trunk/boost/asio/detail/task_io_service.hpp               |   293 +++---                                  
   trunk/boost/asio/detail/timer_queue.hpp                   |   338 ++-----                                 
   trunk/boost/asio/detail/timer_queue_base.hpp              |    32                                         
   trunk/boost/asio/detail/win_event.hpp                     |     9                                         
   trunk/boost/asio/detail/win_iocp_handle_service.hpp       |   427 +++------                               
   trunk/boost/asio/detail/win_iocp_io_service.hpp           |   545 +++++-------                            
   trunk/boost/asio/detail/win_iocp_overlapped_ptr.hpp       |   124 +-                                      
   trunk/boost/asio/detail/win_iocp_serial_port_service.hpp  |    10                                         
   trunk/boost/asio/detail/win_iocp_socket_service.hpp       |  1699 +++++++++++++++------------------------ 
   trunk/boost/asio/detail/win_mutex.hpp                     |    42                                         
   trunk/boost/asio/impl/io_service.ipp                      |    12                                         
   trunk/boost/asio/impl/read.ipp                            |   202 ++-                                     
   trunk/boost/asio/impl/read_at.ipp                         |     8                                         
   trunk/boost/asio/impl/write.ipp                           |   180 +++                                     
   trunk/boost/asio/impl/write_at.ipp                        |     8                                         
   trunk/boost/asio/io_service.hpp                           |    31                                         
   trunk/boost/asio/ip/basic_resolver_iterator.hpp           |    76 +                                       
   trunk/boost/asio/posix/stream_descriptor_service.hpp      |    35                                         
   trunk/boost/asio/raw_socket_service.hpp                   |    29                                         
   trunk/boost/asio/serial_port_service.hpp                  |    19                                         
   trunk/boost/asio/socket_acceptor_service.hpp              |    29                                         
   trunk/boost/asio/ssl/detail/openssl_operation.hpp         |     3                                         
   trunk/boost/asio/ssl/detail/openssl_stream_service.hpp    |    59 +                                       
   trunk/boost/asio/stream_socket_service.hpp                |    29                                         
   trunk/boost/asio/windows/random_access_handle_service.hpp |     7                                         
   trunk/boost/asio/windows/stream_handle_service.hpp        |     7                                         
   49 files changed, 3946 insertions(+), 5764 deletions(-)
Modified: trunk/boost/asio/buffers_iterator.hpp
==============================================================================
--- trunk/boost/asio/buffers_iterator.hpp	(original)
+++ trunk/boost/asio/buffers_iterator.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -22,7 +22,7 @@
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator.hpp>
 #include <boost/type_traits/is_convertible.hpp>
 #include <boost/type_traits/add_const.hpp>
 #include <boost/asio/detail/pop_options.hpp>
@@ -76,11 +76,10 @@
 /// A random access iterator over the bytes in a buffer sequence.
 template <typename BufferSequence, typename ByteType = char>
 class buffers_iterator
-  : public boost::iterator_facade<
-        buffers_iterator<BufferSequence, ByteType>,
-        typename detail::buffers_iterator_types<
-          BufferSequence, ByteType>::byte_type,
-        boost::random_access_traversal_tag>
+  : public boost::iterator<
+      std::random_access_iterator_tag,
+      typename detail::buffers_iterator_types<
+        BufferSequence, ByteType>::byte_type>
 {
 private:
   typedef typename detail::buffers_iterator_types<
@@ -139,9 +138,132 @@
     return new_iter;
   }
 
-private:
-  friend class boost::iterator_core_access;
+  /// Dereference an iterator.
+  byte_type& operator*() const
+  {
+    return dereference();
+  }
+
+  /// Dereference an iterator.
+  byte_type* operator->() const
+  {
+    return &dereference();
+  }
+
+  /// Access an individual element.
+  byte_type& operator[](std::ptrdiff_t difference) const
+  {
+    buffers_iterator tmp(*this);
+    tmp.advance(difference);
+    return *tmp;
+  }
+
+  /// Increment operator (prefix).
+  buffers_iterator& operator++()
+  {
+    increment();
+    return *this;
+  }
+
+  /// Increment operator (postfix).
+  buffers_iterator operator++(int)
+  {
+    buffers_iterator tmp(*this);
+    ++*this;
+    return tmp;
+  }
+
+  /// Decrement operator (prefix).
+  buffers_iterator& operator--()
+  {
+    decrement();
+    return *this;
+  }
+
+  /// Decrement operator (postfix).
+  buffers_iterator operator--(int)
+  {
+    buffers_iterator tmp(*this);
+    --*this;
+    return tmp;
+  }
+
+  /// Addition operator.
+  buffers_iterator& operator+=(std::ptrdiff_t difference)
+  {
+    advance(difference);
+    return *this;
+  }
+
+  /// Subtraction operator.
+  buffers_iterator& operator-=(std::ptrdiff_t difference)
+  {
+    advance(-difference);
+    return *this;
+  }
 
+  /// Addition operator.
+  friend buffers_iterator operator+(const buffers_iterator& iter,
+      std::ptrdiff_t difference)
+  {
+    buffers_iterator tmp(iter);
+    tmp.advance(difference);
+    return tmp;
+  }
+
+  /// Subtraction operator.
+  friend buffers_iterator operator-(const buffers_iterator& iter,
+      std::ptrdiff_t difference)
+  {
+    buffers_iterator tmp(iter);
+    tmp.advance(-difference);
+    return tmp;
+  }
+
+  /// Subtraction operator.
+  friend std::ptrdiff_t operator-(const buffers_iterator& a,
+      const buffers_iterator& b)
+  {
+    return b.distance_to(a);
+  }
+
+  /// Test two iterators for equality.
+  friend bool operator==(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return a.equal(b);
+  }
+
+  /// Test two iterators for inequality.
+  friend bool operator!=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !a.equal(b);
+  }
+
+  /// Compare two iterators.
+  friend bool operator<(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return a.distance_to(b) > 0;
+  }
+
+  /// Compare two iterators.
+  friend bool operator<=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !(b < a);
+  }
+
+  /// Compare two iterators.
+  friend bool operator>(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return b < a;
+  }
+
+  /// Compare two iterators.
+  friend bool operator>=(const buffers_iterator& a, const buffers_iterator& b)
+  {
+    return !(a < b);
+  }
+
+private:
   // Dereference the iterator.
   byte_type& dereference() const
   {
Modified: trunk/boost/asio/datagram_socket_service.hpp
==============================================================================
--- trunk/boost/asio/datagram_socket_service.hpp	(original)
+++ trunk/boost/asio/datagram_socket_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -28,17 +28,7 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
 #else
-# include <boost/asio/detail/select_reactor.hpp>
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
@@ -70,18 +60,8 @@
   // The type of the platform-specific implementation.
 #if defined(BOOST_ASIO_HAS_IOCP)
   typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::dev_poll_reactor<false> > service_impl_type;
 #else
-  typedef detail::reactive_socket_service<
-      Protocol, detail::select_reactor<false> > service_impl_type;
+  typedef detail::reactive_socket_service<Protocol> service_impl_type;
 #endif
 
 public:
@@ -103,13 +83,14 @@
   explicit datagram_socket_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         datagram_socket_service<Protocol> >(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new datagram socket implementation.
@@ -324,8 +305,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Modified: trunk/boost/asio/deadline_timer_service.hpp
==============================================================================
--- trunk/boost/asio/deadline_timer_service.hpp	(original)
+++ trunk/boost/asio/deadline_timer_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -27,18 +27,6 @@
 #include <boost/asio/detail/deadline_timer_service.hpp>
 #include <boost/asio/detail/service_base.hpp>
 
-#if defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_io_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-#else
-# include <boost/asio/detail/select_reactor.hpp>
-#endif
-
 namespace boost {
 namespace asio {
 
@@ -70,22 +58,7 @@
 
 private:
   // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_HAS_IOCP)
-  typedef detail::deadline_timer_service<
-    traits_type, detail::win_iocp_io_service> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::deadline_timer_service<
-    traits_type, detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::deadline_timer_service<
-    traits_type, detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::deadline_timer_service<
-    traits_type, detail::dev_poll_reactor<false> > service_impl_type;
-#else
-  typedef detail::deadline_timer_service<
-    traits_type, detail::select_reactor<false> > service_impl_type;
-#endif
+  typedef detail::deadline_timer_service<traits_type> service_impl_type;
 
 public:
   /// The implementation type of the deadline timer.
@@ -99,13 +72,14 @@
   explicit deadline_timer_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         deadline_timer_service<TimeType, TimeTraits> >(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new timer implementation.
@@ -166,8 +140,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Added: trunk/boost/asio/detail/base_from_completion_cond.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/base_from_completion_cond.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,67 @@
+//
+// base_from_completion_cond.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_BASE_FROM_COMPLETION_COND_HPP
+#define BOOST_ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/completion_condition.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename CompletionCondition>
+class base_from_completion_cond
+{
+protected:
+  explicit base_from_completion_cond(CompletionCondition completion_condition)
+    : completion_condition_(completion_condition)
+  {
+  }
+
+  std::size_t check(const boost::system::error_code& ec,
+      std::size_t total_transferred)
+  {
+    return detail::adapt_completion_condition_result(
+        completion_condition_(ec, total_transferred));
+  }
+
+private:
+  CompletionCondition completion_condition_;
+};
+
+template <>
+class base_from_completion_cond<transfer_all_t>
+{
+protected:
+  explicit base_from_completion_cond(transfer_all_t)
+  {
+  }
+
+  static std::size_t check(const boost::system::error_code& ec,
+      std::size_t total_transferred)
+  {
+    return transfer_all_t()(ec, total_transferred);
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BASE_FROM_COMPLETION_COND_HPP
Added: trunk/boost/asio/detail/buffer_sequence_adapter.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/buffer_sequence_adapter.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,254 @@
+//
+// buffer_sequence_adapter.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_BUFFER_SEQUENCE_ADAPTER_HPP
+#define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/buffer.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class buffer_sequence_adapter_base
+{
+protected:
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  typedef WSABUF native_buffer_type;
+
+  static void init_native_buffer(WSABUF& buf,
+      const boost::asio::mutable_buffer& buffer)
+  {
+    buf.buf = boost::asio::buffer_cast<char*>(buffer);
+    buf.len = boost::asio::buffer_size(buffer);
+  }
+
+  static void init_native_buffer(WSABUF& buf,
+      const boost::asio::const_buffer& buffer)
+  {
+    buf.buf = const_cast<char*>(boost::asio::buffer_cast<const char*>(buffer));
+    buf.len = boost::asio::buffer_size(buffer);
+  }
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  typedef iovec native_buffer_type;
+
+  static void init_iov_base(void*& base, void* addr)
+  {
+    base = addr;
+  }
+
+  template <typename T>
+  static void init_iov_base(T& base, void* addr)
+  {
+    base = static_cast<T>(addr);
+  }
+
+  static void init_native_buffer(iovec& iov,
+      const boost::asio::mutable_buffer& buffer)
+  {
+    init_iov_base(iov.iov_base, boost::asio::buffer_cast<void*>(buffer));
+    iov.iov_len = boost::asio::buffer_size(buffer);
+  }
+
+  static void init_native_buffer(iovec& iov,
+      const boost::asio::const_buffer& buffer)
+  {
+    init_iov_base(iov.iov_base, const_cast<void*>(
+          boost::asio::buffer_cast<const void*>(buffer)));
+    iov.iov_len = boost::asio::buffer_size(buffer);
+  }
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+};
+
+// Helper class to translate buffers into the native buffer representation.
+template <typename Buffer, typename Buffers>
+class buffer_sequence_adapter
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(const Buffers& buffers)
+    : count_(0), total_buffer_size_(0)
+  {
+    typename Buffers::const_iterator iter = buffers.begin();
+    typename Buffers::const_iterator end = buffers.end();
+    for (; iter != end && count_ < max_buffers; ++iter, ++count_)
+    {
+      Buffer buffer(*iter);
+      init_native_buffer(buffers_[count_], buffer);
+      total_buffer_size_ += boost::asio::buffer_size(buffer);
+    }
+  }
+
+  native_buffer_type* buffers()
+  {
+    return buffers_;
+  }
+
+  std::size_t count() const
+  {
+    return count_;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const Buffers& buffers)
+  {
+    typename Buffers::const_iterator iter = buffers.begin();
+    typename Buffers::const_iterator end = buffers.end();
+    std::size_t i = 0;
+    for (; iter != end && i < max_buffers; ++iter, ++i)
+      if (boost::asio::buffer_size(Buffer(*iter)) > 0)
+        return false;
+    return true;
+  }
+
+  static void validate(const Buffers& buffers)
+  {
+    typename Buffers::const_iterator iter = buffers.begin();
+    typename Buffers::const_iterator end = buffers.end();
+    for (; iter != end; ++iter)
+    {
+      Buffer buffer(*iter);
+      boost::asio::buffer_cast<const void*>(buffer);
+    }
+  }
+
+  static Buffer first(const Buffers& buffers)
+  {
+    typename Buffers::const_iterator iter = buffers.begin();
+    typename Buffers::const_iterator end = buffers.end();
+    for (; iter != end; ++iter)
+    {
+      Buffer buffer(*iter);
+      if (boost::asio::buffer_size(buffer) != 0)
+        return buffer;
+    }
+    return Buffer();
+  }
+
+private:
+  // The maximum number of buffers to support in a single operation.
+  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
+
+  native_buffer_type buffers_[max_buffers];
+  std::size_t count_;
+  std::size_t total_buffer_size_;
+};
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::mutable_buffers_1& buffers)
+  {
+    init_native_buffer(buffer_, buffers);
+    total_buffer_size_ = boost::asio::buffer_size(buffers);
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::mutable_buffers_1& buffers)
+  {
+    return boost::asio::buffer_size(buffers) == 0;
+  }
+
+  static void validate(const boost::asio::mutable_buffers_1& buffers)
+  {
+    boost::asio::buffer_cast<const void*>(buffers);
+  }
+
+  static Buffer first(const boost::asio::mutable_buffers_1& buffers)
+  {
+    return Buffer(buffers);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+template <typename Buffer>
+class buffer_sequence_adapter<Buffer, boost::asio::const_buffers_1>
+  : buffer_sequence_adapter_base
+{
+public:
+  explicit buffer_sequence_adapter(
+      const boost::asio::const_buffers_1& buffers)
+  {
+    init_native_buffer(buffer_, buffers);
+    total_buffer_size_ = boost::asio::buffer_size(buffers);
+  }
+
+  native_buffer_type* buffers()
+  {
+    return &buffer_;
+  }
+
+  std::size_t count() const
+  {
+    return 1;
+  }
+
+  bool all_empty() const
+  {
+    return total_buffer_size_ == 0;
+  }
+
+  static bool all_empty(const boost::asio::const_buffers_1& buffers)
+  {
+    return boost::asio::buffer_size(buffers) == 0;
+  }
+
+  static void validate(const boost::asio::const_buffers_1& buffers)
+  {
+    boost::asio::buffer_cast<const void*>(buffers);
+  }
+
+  static Buffer first(const boost::asio::const_buffers_1& buffers)
+  {
+    return Buffer(buffers);
+  }
+
+private:
+  native_buffer_type buffer_;
+  std::size_t total_buffer_size_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
Added: trunk/boost/asio/detail/completion_handler.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/completion_handler.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,73 @@
+//
+// completion_handler.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_COMPLETION_HANDLER_HPP
+#define BOOST_ASIO_DETAIL_COMPLETION_HANDLER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/operation.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class completion_handler : public operation
+{
+public:
+  completion_handler(Handler h)
+    : operation(&completion_handler::do_complete),
+      handler_(h)
+  {
+  }
+
+  static void do_complete(io_service_impl* owner, operation* base,
+      boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    completion_handler* h(static_cast<completion_handler*>(base));
+    typedef handler_alloc_traits<Handler, completion_handler> alloc_traits;
+    handler_ptr<alloc_traits> ptr(h->handler_, h);
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      // Make a copy of the handler so that the memory can be deallocated
+      // before the upcall is made. Even if we're not about to make an
+      // upcall, 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(h->handler_);
+      ptr.reset();
+      boost::asio::detail::fenced_block b;
+      boost_asio_handler_invoke_helpers::invoke(handler, handler);
+    }
+  }
+
+private:
+  Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_COMPLETION_HANDLER_HPP
Deleted: trunk/boost/asio/detail/const_buffers_iterator.hpp
==============================================================================
--- trunk/boost/asio/detail/const_buffers_iterator.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
+++ (empty file)
@@ -1,153 +0,0 @@
-//
-// const_buffers_iterator.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_CONST_BUFFERS_ITERATOR_HPP
-#define BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/buffer.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-// A proxy iterator for a sub-range in a list of buffers.
-template <typename ConstBufferSequence>
-class const_buffers_iterator
-  : public boost::iterator_facade<const_buffers_iterator<ConstBufferSequence>,
-        const char, boost::bidirectional_traversal_tag>
-{
-public:
-  // Default constructor creates an iterator in an undefined state.
-  const_buffers_iterator()
-  {
-  }
-
-  // Create an iterator for the specified position.
-  const_buffers_iterator(const ConstBufferSequence& buffers,
-      std::size_t position)
-    : begin_(buffers.begin()),
-      current_(buffers.begin()),
-      end_(buffers.end()),
-      position_(0)
-  {
-    while (current_ != end_)
-    {
-      current_buffer_ = *current_;
-      std::size_t buffer_size = boost::asio::buffer_size(current_buffer_);
-      if (position - position_ < buffer_size)
-      {
-        current_buffer_position_ = position - position_;
-        position_ = position;
-        return;
-      }
-      position_ += buffer_size;
-      ++current_;
-    }
-    current_buffer_ = boost::asio::const_buffer();
-    current_buffer_position_ = 0;
-  }
-
-  std::size_t position() const
-  {
-    return position_;
-  }
-
-private:
-  friend class boost::iterator_core_access;
-
-  void increment()
-  {
-    if (current_ == end_)
-      return;
-
-    ++position_;
-
-    ++current_buffer_position_;
-    if (current_buffer_position_ != boost::asio::buffer_size(current_buffer_))
-      return;
-
-    ++current_;
-    current_buffer_position_ = 0;
-    while (current_ != end_)
-    {
-      current_buffer_ = *current_;
-      if (boost::asio::buffer_size(current_buffer_) > 0)
-        return;
-      ++current_;
-    }
-  }
-
-  void decrement()
-  {
-    if (position_ == 0)
-      return;
-
-    --position_;
-
-    if (current_buffer_position_ != 0)
-    {
-      --current_buffer_position_;
-      return;
-    }
-
-    typename ConstBufferSequence::const_iterator iter = current_;
-    while (iter != begin_)
-    {
-      --iter;
-      boost::asio::const_buffer buffer = *iter;
-      std::size_t buffer_size = boost::asio::buffer_size(buffer);
-      if (buffer_size > 0)
-      {
-        current_ = iter;
-        current_buffer_ = buffer;
-        current_buffer_position_ = buffer_size - 1;
-        return;
-      }
-    }
-  }
-
-  bool equal(const const_buffers_iterator& other) const
-  {
-    return position_ == other.position_;
-  }
-
-  const char& dereference() const
-  {
-    return boost::asio::buffer_cast<const char*>(
-        current_buffer_)[current_buffer_position_];
-  }
-
-  boost::asio::const_buffer current_buffer_;
-  std::size_t current_buffer_position_;
-  typename ConstBufferSequence::const_iterator begin_;
-  typename ConstBufferSequence::const_iterator current_;
-  typename ConstBufferSequence::const_iterator end_;
-  std::size_t position_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_CONST_BUFFERS_ITERATOR_HPP
Modified: trunk/boost/asio/detail/consuming_buffers.hpp
==============================================================================
--- trunk/boost/asio/detail/consuming_buffers.hpp	(original)
+++ trunk/boost/asio/detail/consuming_buffers.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -21,12 +21,11 @@
 #include <algorithm>
 #include <cstddef>
 #include <boost/config.hpp>
-#include <boost/iterator/iterator_facade.hpp>
+#include <boost/iterator.hpp>
 #include <boost/limits.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
 #include <boost/asio/buffer.hpp>
-#include <boost/asio/completion_condition.hpp>
 
 namespace boost {
 namespace asio {
@@ -35,9 +34,7 @@
 // A proxy iterator for a sub-range in a list of buffers.
 template <typename Buffer, typename Buffer_Iterator>
 class consuming_buffers_iterator
-  : public boost::iterator_facade<
-        consuming_buffers_iterator<Buffer, Buffer_Iterator>,
-        const Buffer, boost::forward_traversal_tag>
+  : public boost::iterator<std::forward_iterator_tag, const Buffer>
 {
 public:
   // Default constructor creates an end iterator.
@@ -60,9 +57,48 @@
   {
   }
 
-private:
-  friend class boost::iterator_core_access;
+  // Dereference an iterator.
+  const Buffer& operator*() const
+  {
+    return dereference();
+  }
+
+  // Dereference an iterator.
+  const Buffer* operator->() const
+  {
+    return &dereference();
+  }
+
+  // Increment operator (prefix).
+  consuming_buffers_iterator& operator++()
+  {
+    increment();
+    return *this;
+  }
 
+  // Increment operator (postfix).
+  consuming_buffers_iterator operator++(int)
+  {
+    consuming_buffers_iterator tmp(*this);
+    ++*this;
+    return tmp;
+  }
+
+  // Test two iterators for equality.
+  friend bool operator==(const consuming_buffers_iterator& a,
+      const consuming_buffers_iterator& b)
+  {
+    return a.equal(b);
+  }
+
+  // Test two iterators for inequality.
+  friend bool operator!=(const consuming_buffers_iterator& a,
+      const consuming_buffers_iterator& b)
+  {
+    return !a.equal(b);
+  }
+
+private:
   void increment()
   {
     if (!at_end_)
@@ -170,7 +206,7 @@
   }
 
   // Set the maximum size for a single transfer.
-  void set_max_size(std::size_t max_size)
+  void prepare(std::size_t max_size)
   {
     max_size_ = max_size;
   }
@@ -226,7 +262,7 @@
     // No-op.
   }
 
-  void set_max_size(std::size_t)
+  void prepare(std::size_t)
   {
     // No-op.
   }
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-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -26,21 +26,20 @@
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/handler_base_from_member.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/timer_op.hpp>
 #include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_scheduler.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <typename Time_Traits, typename Timer_Scheduler>
+template <typename Time_Traits>
 class deadline_timer_service
-  : public boost::asio::detail::service_base<
-      deadline_timer_service<Time_Traits, Timer_Scheduler> >
 {
 public:
   // The time type.
@@ -60,9 +59,7 @@
 
   // Constructor.
   deadline_timer_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
-      scheduler_(boost::asio::use_service<Timer_Scheduler>(io_service))
+    : scheduler_(boost::asio::use_service<timer_scheduler>(io_service))
   {
     scheduler_.init_task();
     scheduler_.add_timer_queue(timer_queue_);
@@ -156,34 +153,58 @@
   }
 
   template <typename Handler>
-  class wait_handler : 
-    public handler_base_from_member<Handler>
+  class wait_handler : public timer_op
   {
   public:
-    wait_handler(boost::asio::io_service& io_service, Handler handler)
-      : handler_base_from_member<Handler>(handler),
-        io_service_(io_service),
-        work_(io_service)
+    wait_handler(Handler handler)
+      : timer_op(&wait_handler::do_complete),
+        handler_(handler)
     {
     }
 
-    void operator()(const boost::system::error_code& result)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
     {
-      io_service_.post(detail::bind_handler(this->handler_, result));
+      // Take ownership of the handler object.
+      wait_handler* h(static_cast<wait_handler*>(base));
+      typedef handler_alloc_traits<Handler, wait_handler> alloc_traits;
+      handler_ptr<alloc_traits> ptr(h->handler_, h);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder1<Handler, boost::system::error_code>
+          handler(h->handler_, h->ec_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
+    Handler handler_;
   };
 
   // Start an asynchronous wait on the timer.
   template <typename Handler>
   void async_wait(implementation_type& impl, Handler handler)
   {
+    // Allocate and construct an operation to wrap the handler.
+    typedef wait_handler<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
     impl.might_have_pending_waits = true;
-    scheduler_.schedule_timer(timer_queue_, impl.expiry,
-        wait_handler<Handler>(this->get_io_service(), handler), &impl);
+
+    scheduler_.schedule_timer(timer_queue_, impl.expiry, ptr.get(), &impl);
+    ptr.release();
   }
 
 private:
@@ -191,7 +212,7 @@
   timer_queue<Time_Traits> timer_queue_;
 
   // The object that schedules and executes timers. Usually a reactor.
-  Timer_Scheduler& scheduler_;
+  timer_scheduler& scheduler_;
 };
 
 } // namespace detail
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-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -33,27 +33,30 @@
 
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/task_io_service.hpp>
-#include <boost/asio/detail/thread.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/reactor_op_queue.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
 #include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/signal_blocker.hpp>
 #include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_op.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_fwd.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class dev_poll_reactor
-  : public boost::asio::detail::service_base<dev_poll_reactor<Own_Thread> >
+  : public boost::asio::detail::service_base<dev_poll_reactor>
 {
 public:
+  enum { read_op = 0, write_op = 1,
+    connect_op = 1, except_op = 2, max_ops = 3 };
+
   // Per-descriptor data.
   struct per_descriptor_data
   {
@@ -61,28 +64,13 @@
 
   // Constructor.
   dev_poll_reactor(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        dev_poll_reactor<Own_Thread> >(io_service),
+    : boost::asio::detail::service_base<dev_poll_reactor>(io_service),
+      io_service_(use_service<io_service_impl>(io_service)),
       mutex_(),
       dev_poll_fd_(do_dev_poll_create()),
-      wait_in_progress_(false),
       interrupter_(),
-      read_op_queue_(),
-      write_op_queue_(),
-      except_op_queue_(),
-      pending_cancellations_(),
-      stop_thread_(false),
-      thread_(0),
       shutdown_(false)
   {
-    // Start the reactor's internal thread only if needed.
-    if (Own_Thread)
-    {
-      boost::asio::detail::signal_blocker sb;
-      thread_ = new boost::asio::detail::thread(
-          bind_handler(&dev_poll_reactor::call_run_thread, this));
-    }
-
     // Add the interrupter's descriptor to /dev/poll.
     ::pollfd ev = { 0 };
     ev.fd = interrupter_.read_descriptor();
@@ -103,35 +91,20 @@
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     shutdown_ = true;
-    stop_thread_ = true;
     lock.unlock();
 
-    if (thread_)
-    {
-      interrupter_.interrupt();
-      thread_->join();
-      delete thread_;
-      thread_ = 0;
-    }
+    op_queue<operation> ops;
+
+    for (int i = 0; i < max_ops; ++i)
+      op_queue_[i].get_all_operations(ops);
 
-    read_op_queue_.destroy_operations();
-    write_op_queue_.destroy_operations();
-    except_op_queue_.destroy_operations();
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->destroy_timers();
-    timer_queues_.clear();
+    timer_queues_.get_all_timers(ops);
   } 
 
-  // Initialise the task, but only if the reactor is not in its own thread.
+  // Initialise the task.
   void init_task()
   {
-    if (!Own_Thread)
-    {
-      typedef task_io_service<dev_poll_reactor<Own_Thread> >
-        task_io_service_type;
-      use_service<task_io_service_type>(this->get_io_service()).init_task();
-    }
+    io_service_.init_task();
   }
 
   // Register a socket with the reactor. Returns 0 on success, system error
@@ -141,121 +114,44 @@
     return 0;
   }
 
-  // Start a new read operation. The handler object will be invoked when the
-  // given descriptor is ready to be read, or an error has occurred.
-  template <typename Handler>
-  void start_read_op(socket_type descriptor, per_descriptor_data&,
-      Handler handler, bool allow_speculative_read = true)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (allow_speculative_read)
-    {
-      if (!read_op_queue_.has_operation(descriptor))
-      {
-        boost::system::error_code ec;
-        std::size_t bytes_transferred = 0;
-        if (handler.perform(ec, bytes_transferred))
-        {
-          handler.complete(ec, bytes_transferred);
-          return;
-        }
-      }
-    }
-
-    if (read_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      ::pollfd& ev = add_pending_event_change(descriptor);
-      ev.events = POLLIN | POLLERR | POLLHUP;
-      if (write_op_queue_.has_operation(descriptor))
-        ev.events |= POLLOUT;
-      if (except_op_queue_.has_operation(descriptor))
-        ev.events |= POLLPRI;
-      interrupter_.interrupt();
-    }
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready to be written, or an error has occurred.
-  template <typename Handler>
-  void start_write_op(socket_type descriptor, per_descriptor_data&,
-      Handler handler, bool allow_speculative_write = true)
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  void start_op(int op_type, socket_type descriptor,
+      per_descriptor_data&, reactor_op* op, bool allow_speculative)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     if (shutdown_)
       return;
 
-    if (allow_speculative_write)
+    if (allow_speculative)
     {
-      if (!write_op_queue_.has_operation(descriptor))
+      if (!op_queue_[op_type].has_operation(descriptor))
       {
-        boost::system::error_code ec;
-        std::size_t bytes_transferred = 0;
-        if (handler.perform(ec, bytes_transferred))
+        if (op->perform())
         {
-          handler.complete(ec, bytes_transferred);
+          lock.unlock();
+          io_service_.post_immediate_completion(op);
           return;
         }
       }
     }
 
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      ::pollfd& ev = add_pending_event_change(descriptor);
-      ev.events = POLLOUT | POLLERR | POLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
-        ev.events |= POLLIN;
-      if (except_op_queue_.has_operation(descriptor))
-        ev.events |= POLLPRI;
-      interrupter_.interrupt();
-    }
-  }
 
-  // Start a new exception operation. The handler object will be invoked when
-  // the given descriptor has exception information, or an error has occurred.
-  template <typename Handler>
-  void start_except_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (except_op_queue_.enqueue_operation(descriptor, handler))
+    bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+    io_service_.work_started();
+    if (first)
     {
       ::pollfd& ev = add_pending_event_change(descriptor);
-      ev.events = POLLPRI | POLLERR | POLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
+      ev.events = POLLERR | POLLHUP;
+      if (op_type == read_op
+          || op_queue_[read_op].has_operation(descriptor))
         ev.events |= POLLIN;
-      if (write_op_queue_.has_operation(descriptor))
+      if (op_type == write_op
+          || op_queue_[write_op].has_operation(descriptor))
         ev.events |= POLLOUT;
-      interrupter_.interrupt();
-    }
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // information available, or an error has occurred.
-  template <typename Handler>
-  void start_connect_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      ::pollfd& ev = add_pending_event_change(descriptor);
-      ev.events = POLLOUT | POLLERR | POLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
-        ev.events |= POLLIN;
-      if (except_op_queue_.has_operation(descriptor))
+      if (op_type == except_op
+          || op_queue_[except_op].has_operation(descriptor))
         ev.events |= POLLPRI;
       interrupter_.interrupt();
     }
@@ -267,7 +163,7 @@
   void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    cancel_ops_unlocked(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Cancel any operations that are running against the descriptor and remove
@@ -282,7 +178,7 @@
     interrupter_.interrupt();
 
     // Cancel any outstanding operations associated with the descriptor.
-    cancel_ops_unlocked(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Add a new timer queue to the reactor.
@@ -290,7 +186,7 @@
   void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    timer_queues_.push_back(&timer_queue);
+    timer_queues_.insert(&timer_queue);
   }
 
   // Remove a timer queue from the reactor.
@@ -298,71 +194,48 @@
   void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      if (timer_queues_[i] == &timer_queue)
-      {
-        timer_queues_.erase(timer_queues_.begin() + i);
-        return;
-      }
-    }
+    timer_queues_.erase(&timer_queue);
   }
 
-  // Schedule a timer in the given timer queue to expire at the specified
-  // absolute time. The handler object will be invoked when the timer expires.
-  template <typename Time_Traits, typename Handler>
+  // 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, Handler handler, void* token)
+      const typename Time_Traits::time_type& time, timer_op* op, void* token)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
-      if (timer_queue.enqueue_timer(time, handler, token))
+    {
+      bool earliest = timer_queue.enqueue_timer(time, op, token);
+      io_service_.work_started();
+      if (earliest)
         interrupter_.interrupt();
+    }
   }
 
-  // Cancel the timer associated with the given token. Returns the number of
-  // handlers that have been posted or dispatched.
+  // 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)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    std::size_t n = timer_queue.cancel_timer(token);
-    if (n > 0)
-      interrupter_.interrupt();
+    op_queue<operation> ops;
+    std::size_t n = timer_queue.cancel_timer(token, ops);
+    lock.unlock();
+    io_service_.post_deferred_completions(ops);
     return n;
   }
 
-private:
-  friend class task_io_service<dev_poll_reactor<Own_Thread> >;
-
   // Run /dev/poll once until interrupted or events are ready to be dispatched.
-  void run(bool block)
+  void run(bool block, op_queue<operation>& ops)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    // Dispatch any operation cancellations that were made while the select
-    // loop was not running.
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->dispatch_cancellations();
-
-    // Check if the thread is supposed to stop.
-    if (stop_thread_)
-    {
-      complete_operations_and_timers(lock);
-      return;
-    }
-
     // We can return immediately if there's no work to do and the reactor is
     // not supposed to block.
-    if (!block && read_op_queue_.empty() && write_op_queue_.empty()
-        && except_op_queue_.empty() && all_timer_queues_are_empty())
-    {
-      complete_operations_and_timers(lock);
+    if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty()
+        && op_queue_[except_op].empty() && timer_queues_.all_empty())
       return;
-    }
 
     // Write the pending event registration changes to the /dev/poll descriptor.
     std::size_t events_size = sizeof(::pollfd) * pending_event_changes_.size();
@@ -373,14 +246,13 @@
           &pending_event_changes_[0], events_size);
       if (result != static_cast<int>(events_size))
       {
+        boost::system::error_code ec = boost::system::error_code(
+            errno, boost::asio::error::get_system_category());
         for (std::size_t i = 0; i < pending_event_changes_.size(); ++i)
         {
           int descriptor = pending_event_changes_[i].fd;
-          boost::system::error_code ec = boost::system::error_code(
-              errno, boost::asio::error::get_system_category());
-          read_op_queue_.perform_all_operations(descriptor, ec);
-          write_op_queue_.perform_all_operations(descriptor, ec);
-          except_op_queue_.perform_all_operations(descriptor, ec);
+          for (int j = 0; j < max_ops; ++j)
+            op_queue_[j].cancel_operations(descriptor, ops, ec);
         }
       }
       pending_event_changes_.clear();
@@ -388,7 +260,6 @@
     }
 
     int timeout = block ? get_timeout() : 0;
-    wait_in_progress_ = true;
     lock.unlock();
 
     // Block on the /dev/poll descriptor.
@@ -400,7 +271,6 @@
     int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp);
 
     lock.lock();
-    wait_in_progress_ = false;
 
     // Dispatch the waiting events.
     for (int i = 0; i < num_events; ++i)
@@ -415,24 +285,24 @@
         bool more_reads = false;
         bool more_writes = false;
         bool more_except = false;
-        boost::system::error_code ec;
 
         // Exception operations must be processed first to ensure that any
         // out-of-band data is read before normal data.
         if (events[i].events & (POLLPRI | POLLERR | POLLHUP))
-          more_except = except_op_queue_.perform_operation(descriptor, ec);
+          more_except =
+            op_queue_[except_op].perform_operations(descriptor, ops);
         else
-          more_except = except_op_queue_.has_operation(descriptor);
+          more_except = op_queue_[except_op].has_operation(descriptor);
 
         if (events[i].events & (POLLIN | POLLERR | POLLHUP))
-          more_reads = read_op_queue_.perform_operation(descriptor, ec);
+          more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
         else
-          more_reads = read_op_queue_.has_operation(descriptor);
+          more_reads = op_queue_[read_op].has_operation(descriptor);
 
         if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
-          more_writes = write_op_queue_.perform_operation(descriptor, ec);
+          more_writes = op_queue_[write_op].perform_operations(descriptor, ops);
         else
-          more_writes = write_op_queue_.has_operation(descriptor);
+          more_writes = op_queue_[write_op].has_operation(descriptor);
 
         if ((events[i].events & (POLLERR | POLLHUP)) != 0
               && !more_except && !more_reads && !more_writes)
@@ -463,48 +333,15 @@
           int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
           if (result != sizeof(ev))
           {
-            ec = boost::system::error_code(errno,
+            boost::system::error_code ec(errno,
                 boost::asio::error::get_system_category());
-            read_op_queue_.perform_all_operations(descriptor, ec);
-            write_op_queue_.perform_all_operations(descriptor, ec);
-            except_op_queue_.perform_all_operations(descriptor, ec);
+            for (int j = 0; j < max_ops; ++j)
+              op_queue_[j].cancel_operations(descriptor, ops, ec);
           }
         }
       }
     }
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      timer_queues_[i]->dispatch_timers();
-      timer_queues_[i]->dispatch_cancellations();
-    }
-
-    // Issue any pending cancellations.
-    for (size_t i = 0; i < pending_cancellations_.size(); ++i)
-      cancel_ops_unlocked(pending_cancellations_[i]);
-    pending_cancellations_.clear();
-
-    complete_operations_and_timers(lock);
-  }
-
-  // Run the select loop in the thread.
-  void run_thread()
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    while (!stop_thread_)
-    {
-      lock.unlock();
-      run(true);
-      lock.lock();
-    }
-  }
-
-  // Entry point for the select loop thread.
-  static void call_run_thread(dev_poll_reactor* reactor)
-  {
-    reactor->run_thread();
+    timer_queues_.get_ready_timers(ops);
   }
 
   // Interrupt the select loop.
@@ -513,6 +350,7 @@
     interrupter_.interrupt();
   }
 
+private:
   // Create the /dev/poll file descriptor. Throws an exception if the descriptor
   // cannot be created.
   static int do_dev_poll_create()
@@ -529,75 +367,32 @@
     return fd;
   }
 
-  // Check if all timer queues are empty.
-  bool all_timer_queues_are_empty() const
-  {
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      if (!timer_queues_[i]->empty())
-        return false;
-    return true;
-  }
-
   // Get the timeout value for the /dev/poll DP_POLL operation. The timeout
   // value is returned as a number of milliseconds. A return value of -1
   // indicates that the poll should block indefinitely.
   int get_timeout()
   {
-    if (all_timer_queues_are_empty())
-      return -1;
-
     // By default we will wait no longer than 5 minutes. This will ensure that
     // any changes to the system clock are detected after no longer than this.
-    boost::posix_time::time_duration minimum_wait_duration
-      = boost::posix_time::minutes(5);
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      boost::posix_time::time_duration wait_duration
-        = timer_queues_[i]->wait_duration();
-      if (wait_duration < minimum_wait_duration)
-        minimum_wait_duration = wait_duration;
-    }
-
-    if (minimum_wait_duration > boost::posix_time::time_duration())
-    {
-      int milliseconds = minimum_wait_duration.total_milliseconds();
-      return milliseconds > 0 ? milliseconds : 1;
-    }
-    else
-    {
-      return 0;
-    }
+    return timer_queues_.wait_duration_msec(5 * 60 * 1000);
   }
 
   // Cancel all operations associated with the given descriptor. The do_cancel
   // function of the handler objects will be invoked. This function does not
   // acquire the dev_poll_reactor's mutex.
-  void cancel_ops_unlocked(socket_type descriptor)
+  void cancel_ops_unlocked(socket_type descriptor,
+      const boost::system::error_code& ec)
   {
-    bool interrupt = read_op_queue_.cancel_operations(descriptor);
-    interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
-    interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
-    if (interrupt)
+    bool need_interrupt = false;
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      need_interrupt = op_queue_[i].cancel_operations(
+          descriptor, ops, ec) || need_interrupt;
+    io_service_.post_deferred_completions(ops);
+    if (need_interrupt)
       interrupter_.interrupt();
   }
 
-  // Clean up operations and timers. We must not hold the lock since the
-  // destructors may make calls back into this reactor. We make a copy of the
-  // vector of timer queues since the original may be modified while the lock
-  // is not held.
-  void complete_operations_and_timers(
-      boost::asio::detail::mutex::scoped_lock& lock)
-  {
-    timer_queues_for_cleanup_ = timer_queues_;
-    lock.unlock();
-    read_op_queue_.complete_operations();
-    write_op_queue_.complete_operations();
-    except_op_queue_.complete_operations();
-    for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
-      timer_queues_for_cleanup_[i]->complete_timers();
-  }
-
   // Add a pending event entry for the given descriptor.
   ::pollfd& add_pending_event_change(int descriptor)
   {
@@ -619,6 +414,9 @@
     }
   }
 
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_;
+
   // Mutex to protect access to internal data.
   boost::asio::detail::mutex mutex_;
 
@@ -631,36 +429,14 @@
   // Hash map to associate a descriptor with a pending event change index.
   hash_map<int, std::size_t> pending_event_change_index_;
 
-  // Whether the DP_POLL operation is currently in progress
-  bool wait_in_progress_;
-
   // The interrupter is used to break a blocking DP_POLL operation.
   select_interrupter interrupter_;
 
-  // The queue of read operations.
-  reactor_op_queue<socket_type> read_op_queue_;
-
-  // The queue of write operations.
-  reactor_op_queue<socket_type> write_op_queue_;
-
-  // The queue of except operations.
-  reactor_op_queue<socket_type> except_op_queue_;
+  // The queues of read, write and except operations.
+  reactor_op_queue<socket_type> op_queue_[max_ops];
 
   // The timer queues.
-  std::vector<timer_queue_base*> timer_queues_;
-
-  // A copy of the timer queues, used when cleaning up timers. The copy is
-  // stored as a class data member to avoid unnecessary memory allocation.
-  std::vector<timer_queue_base*> timer_queues_for_cleanup_;
-
-  // The descriptors that are pending cancellation.
-  std::vector<socket_type> pending_cancellations_;
-
-  // Does the reactor loop thread need to stop.
-  bool stop_thread_;
-
-  // The thread that is running the reactor loop.
-  boost::asio::detail::thread* thread_;
+  timer_queue_set timer_queues_;
 
   // Whether the service has been shut down.
   bool shutdown_;
Modified: trunk/boost/asio/detail/dev_poll_reactor_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/dev_poll_reactor_fwd.hpp	(original)
+++ trunk/boost/asio/detail/dev_poll_reactor_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -27,7 +27,6 @@
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class dev_poll_reactor;
 
 } // namespace detail
Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp	(original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -23,115 +23,126 @@
 
 #include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
-#include <vector>
 #include <sys/epoll.h>
 #include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/system/system_error.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/task_io_service.hpp>
-#include <boost/asio/detail/thread.hpp>
-#include <boost/asio/detail/reactor_op_queue.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
 #include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/signal_blocker.hpp>
 #include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_op.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_fwd.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
+
+#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+# define BOOST_ASIO_HAS_TIMERFD 1
+#endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# include <boost/asio/detail/push_options.hpp>
+# include <sys/timerfd.h>
+# include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class epoll_reactor
-  : public boost::asio::detail::service_base<epoll_reactor<Own_Thread> >
+  : public boost::asio::detail::service_base<epoll_reactor>
 {
 public:
-  // Per-descriptor data.
-  struct per_descriptor_data
+  enum { read_op = 0, write_op = 1,
+    connect_op = 1, except_op = 2, max_ops = 3 };
+
+  // Per-descriptor queues.
+  struct descriptor_state
   {
-    bool allow_speculative_read;
-    bool allow_speculative_write;
+    descriptor_state() {}
+    descriptor_state(const descriptor_state&) {}
+    void operator=(const descriptor_state&) {}
+
+    mutex mutex_;
+    op_queue<reactor_op> op_queue_[max_ops];
+    bool shutdown_;
   };
 
+  // Per-descriptor data.
+  typedef descriptor_state* per_descriptor_data;
+
   // Constructor.
   epoll_reactor(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
+    : boost::asio::detail::service_base<epoll_reactor>(io_service),
+      io_service_(use_service<io_service_impl>(io_service)),
       mutex_(),
       epoll_fd_(do_epoll_create()),
-      wait_in_progress_(false),
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+      timer_fd_(timerfd_create(CLOCK_MONOTONIC, 0)),
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+      timer_fd_(-1),
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
       interrupter_(),
-      read_op_queue_(),
-      write_op_queue_(),
-      except_op_queue_(),
-      pending_cancellations_(),
-      stop_thread_(false),
-      thread_(0),
-      shutdown_(false),
-      need_epoll_wait_(true)
+      shutdown_(false)
   {
-    // Start the reactor's internal thread only if needed.
-    if (Own_Thread)
-    {
-      boost::asio::detail::signal_blocker sb;
-      thread_ = new boost::asio::detail::thread(
-          bind_handler(&epoll_reactor::call_run_thread, this));
-    }
-
     // Add the interrupter's descriptor to epoll.
     epoll_event ev = { 0, { 0 } };
-    ev.events = EPOLLIN | EPOLLERR;
-    ev.data.fd = interrupter_.read_descriptor();
+    ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+    ev.data.ptr = &interrupter_;
     epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, interrupter_.read_descriptor(), &ev);
+    interrupter_.interrupt();
+
+    // Add the timer descriptor to epoll.
+    if (timer_fd_ != -1)
+    {
+      ev.events = EPOLLIN | EPOLLERR;
+      ev.data.ptr = &timer_fd_;
+      epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, timer_fd_, &ev);
+    }
   }
 
   // Destructor.
   ~epoll_reactor()
   {
-    shutdown_service();
     close(epoll_fd_);
+    if (timer_fd_ != -1)
+      close(timer_fd_);
   }
 
   // Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
+    mutex::scoped_lock lock(mutex_);
     shutdown_ = true;
-    stop_thread_ = true;
     lock.unlock();
 
-    if (thread_)
+    op_queue<operation> ops;
+
+    descriptor_map::iterator iter = registered_descriptors_.begin();
+    descriptor_map::iterator end = registered_descriptors_.end();
+    while (iter != end)
     {
-      interrupter_.interrupt();
-      thread_->join();
-      delete thread_;
-      thread_ = 0;
+      for (int i = 0; i < max_ops; ++i)
+        ops.push(iter->second.op_queue_[i]);
+      iter->second.shutdown_ = true;
+      ++iter;
     }
 
-    read_op_queue_.destroy_operations();
-    write_op_queue_.destroy_operations();
-    except_op_queue_.destroy_operations();
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->destroy_timers();
-    timer_queues_.clear();
+    timer_queues_.get_all_timers(ops);
   }
 
-  // Initialise the task, but only if the reactor is not in its own thread.
+  // Initialise the task.
   void init_task()
   {
-    if (!Own_Thread)
-    {
-      typedef task_io_service<epoll_reactor<Own_Thread> > task_io_service_type;
-      use_service<task_io_service_type>(this->get_io_service()).init_task();
-    }
+    io_service_.init_task();
   }
 
   // Register a socket with the reactor. Returns 0 on success, system error
@@ -139,454 +150,258 @@
   int register_descriptor(socket_type descriptor,
       per_descriptor_data& descriptor_data)
   {
-    // No need to lock according to epoll documentation.
+    mutex::scoped_lock lock(registered_descriptors_mutex_);
 
-    descriptor_data.allow_speculative_read = true;
-    descriptor_data.allow_speculative_write = true;
+    descriptor_map::iterator new_entry = registered_descriptors_.insert(
+          std::make_pair(descriptor, descriptor_state())).first;
+    descriptor_data = &new_entry->second;
 
     epoll_event ev = { 0, { 0 } };
-    ev.events = 0;
-    ev.data.fd = descriptor;
+    ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET;
+    ev.data.ptr = descriptor_data;
     int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
     if (result != 0)
       return errno;
-    return 0;
-  }
-
-  // Start a new read operation. The handler object will be invoked when the
-  // given descriptor is ready to be read, or an error has occurred.
-  template <typename Handler>
-  void start_read_op(socket_type descriptor,
-      per_descriptor_data& descriptor_data,
-      Handler handler, bool allow_speculative_read = true)
-  {
-    if (allow_speculative_read && descriptor_data.allow_speculative_read)
-    {
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
-      {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-
-      // We only get one shot at a speculative read in this function.
-      allow_speculative_read = false;
-    }
-
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    if (shutdown_)
-      return;
-
-    if (!allow_speculative_read)
-      need_epoll_wait_ = true;
-    else if (!read_op_queue_.has_operation(descriptor))
-    {
-      // Speculative reads are ok as there are no queued read operations.
-      descriptor_data.allow_speculative_read = true;
+    descriptor_data->shutdown_ = false;
 
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
-      {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-    }
-
-    // Speculative reads are not ok as there will be queued read operations.
-    descriptor_data.allow_speculative_read = false;
-
-    if (read_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      epoll_event ev = { 0, { 0 } };
-      ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
-      if (write_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLOUT;
-      if (except_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLPRI;
-      ev.data.fd = descriptor;
-
-      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
-      if (result != 0 && errno == ENOENT)
-        result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
-      if (result != 0)
-      {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        read_op_queue_.perform_all_operations(descriptor, ec);
-      }
-    }
+    return 0;
   }
 
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready to be written, or an error has occurred.
-  template <typename Handler>
-  void start_write_op(socket_type descriptor,
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  void start_op(int op_type, socket_type descriptor,
       per_descriptor_data& descriptor_data,
-      Handler handler, bool allow_speculative_write = true)
+      reactor_op* op, bool allow_speculative)
   {
-    if (allow_speculative_write && descriptor_data.allow_speculative_write)
-    {
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
-      {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-
-      // We only get one shot at a speculative write in this function.
-      allow_speculative_write = false;
-    }
-
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
+    mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+    if (descriptor_data->shutdown_)
       return;
 
-    if (!allow_speculative_write)
-      need_epoll_wait_ = true;
-    else if (!write_op_queue_.has_operation(descriptor))
+    if (descriptor_data->op_queue_[op_type].empty())
     {
-      // Speculative writes are ok as there are no queued write operations.
-      descriptor_data.allow_speculative_write = true;
-
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
+      if (allow_speculative)
       {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-    }
-
-    // Speculative writes are not ok as there will be queued write operations.
-    descriptor_data.allow_speculative_write = false;
-
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      epoll_event ev = { 0, { 0 } };
-      ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLIN;
-      if (except_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLPRI;
-      ev.data.fd = descriptor;
-
-      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
-      if (result != 0 && errno == ENOENT)
-        result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
-      if (result != 0)
-      {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        write_op_queue_.perform_all_operations(descriptor, ec);
+        if (op->perform())
+        {
+          descriptor_lock.unlock();
+          io_service_.post_immediate_completion(op);
+          return;
+        }
       }
-    }
-  }
-
-  // Start a new exception operation. The handler object will be invoked when
-  // the given descriptor has exception information, or an error has occurred.
-  template <typename Handler>
-  void start_except_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (except_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      epoll_event ev = { 0, { 0 } };
-      ev.events = EPOLLPRI | EPOLLERR | EPOLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLIN;
-      if (write_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLOUT;
-      ev.data.fd = descriptor;
-
-      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
-      if (result != 0 && errno == ENOENT)
-        result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
-      if (result != 0)
+      else
       {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        except_op_queue_.perform_all_operations(descriptor, ec);
+        epoll_event ev = { 0, { 0 } };
+        ev.events = EPOLLIN | EPOLLERR | EPOLLHUP
+          | EPOLLOUT | EPOLLPRI | EPOLLET;
+        ev.data.ptr = descriptor_data;
+        epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
       }
     }
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready for writing or an error has occurred. Speculative
-  // writes are not allowed.
-  template <typename Handler>
-  void start_connect_op(socket_type descriptor,
-      per_descriptor_data& descriptor_data, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    if (shutdown_)
-      return;
-
-    // Speculative writes are not ok as there will be queued write operations.
-    descriptor_data.allow_speculative_write = false;
-
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      epoll_event ev = { 0, { 0 } };
-      ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP;
-      if (read_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLIN;
-      if (except_op_queue_.has_operation(descriptor))
-        ev.events |= EPOLLPRI;
-      ev.data.fd = descriptor;
-
-      int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
-      if (result != 0 && errno == ENOENT)
-        result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
-      if (result != 0)
-      {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        write_op_queue_.perform_all_operations(descriptor, ec);
-      }
-    }
+    descriptor_data->op_queue_[op_type].push(op);
+    io_service_.work_started();
   }
 
   // Cancel all operations associated with the given descriptor. The
   // handlers associated with the descriptor will be invoked with the
   // operation_aborted error.
-  void cancel_ops(socket_type descriptor, per_descriptor_data&)
+  void cancel_ops(socket_type descriptor, per_descriptor_data& descriptor_data)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    cancel_ops_unlocked(descriptor);
+    mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      ops.push(descriptor_data->op_queue_[i]);
+
+    descriptor_lock.unlock();
+
+    io_service_.post_deferred_completions(ops);
   }
 
   // Cancel any operations that are running against the descriptor and remove
   // its registration from the reactor.
-  void close_descriptor(socket_type descriptor, per_descriptor_data&)
+  void close_descriptor(socket_type descriptor,
+      per_descriptor_data& descriptor_data)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
+    mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+    mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
 
-    // Remove the descriptor from epoll.
-    epoll_event ev = { 0, { 0 } };
-    epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
+    // 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)
+      ops.push(descriptor_data->op_queue_[i]);
+
+    descriptor_lock.unlock();
 
-    // Cancel any outstanding operations associated with the descriptor.
-    cancel_ops_unlocked(descriptor);
+    registered_descriptors_.erase(descriptor);
+
+    descriptors_lock.unlock();
+
+    io_service_.post_deferred_completions(ops);
   }
 
   // Add a new timer queue to the reactor.
   template <typename Time_Traits>
   void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    timer_queues_.push_back(&timer_queue);
+    mutex::scoped_lock lock(mutex_);
+    timer_queues_.insert(&timer_queue);
   }
 
   // Remove a timer queue from the reactor.
   template <typename Time_Traits>
   void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      if (timer_queues_[i] == &timer_queue)
-      {
-        timer_queues_.erase(timer_queues_.begin() + i);
-        return;
-      }
-    }
+    mutex::scoped_lock lock(mutex_);
+    timer_queues_.erase(&timer_queue);
   }
 
-  // Schedule a timer in the given timer queue to expire at the specified
-  // absolute time. The handler object will be invoked when the timer expires.
-  template <typename Time_Traits, typename Handler>
+  // 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, Handler handler, void* token)
+      const typename Time_Traits::time_type& time, timer_op* op, void* token)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
+    mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
-      if (timer_queue.enqueue_timer(time, handler, token))
+    {
+      bool earliest = timer_queue.enqueue_timer(time, op, token);
+      io_service_.work_started();
+      if (earliest)
+      {
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+        if (timer_fd_ != -1)
+        {
+          itimerspec new_timeout;
+          itimerspec old_timeout;
+          int flags = get_timeout(new_timeout);
+          timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+          return;
+        }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
         interrupter_.interrupt();
+      }
+    }
   }
 
-  // Cancel the timer associated with the given token. Returns the number of
-  // handlers that have been posted or dispatched.
+  // 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)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    std::size_t n = timer_queue.cancel_timer(token);
-    if (n > 0)
-      interrupter_.interrupt();
+    mutex::scoped_lock lock(mutex_);
+    op_queue<operation> ops;
+    std::size_t n = timer_queue.cancel_timer(token, ops);
+    lock.unlock();
+    io_service_.post_deferred_completions(ops);
     return n;
   }
 
-private:
-  friend class task_io_service<epoll_reactor<Own_Thread> >;
-
   // Run epoll once until interrupted or events are ready to be dispatched.
-  void run(bool block)
+  void run(bool block, op_queue<operation>& ops)
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    // Dispatch any operation cancellations that were made while the select
-    // loop was not running.
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->dispatch_cancellations();
-
-    // Check if the thread is supposed to stop.
-    if (stop_thread_)
-    {
-      complete_operations_and_timers(lock);
-      return;
-    }
-
-    // We can return immediately if there's no work to do and the reactor is
-    // not supposed to block.
-    if (!block && read_op_queue_.empty() && write_op_queue_.empty()
-        && except_op_queue_.empty() && all_timer_queues_are_empty())
+    // Calculate a timeout only if timerfd is not used.
+    int timeout;
+    if (timer_fd_ != -1)
+      timeout = block ? -1 : 0;
+    else
     {
-      complete_operations_and_timers(lock);
-      return;
+      mutex::scoped_lock lock(mutex_);
+      timeout = block ? get_timeout() : 0;
     }
 
-    int timeout = block ? get_timeout() : 0;
-    wait_in_progress_ = true;
-    lock.unlock();
-
     // Block on the epoll descriptor.
     epoll_event events[128];
-    int num_events = (block || need_epoll_wait_)
-      ? epoll_wait(epoll_fd_, events, 128, timeout)
-      : 0;
+    int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
 
-    lock.lock();
-    wait_in_progress_ = false;
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+    bool check_timers = (timer_fd_ == -1);
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+    bool check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
 
     // Dispatch the waiting events.
     for (int i = 0; i < num_events; ++i)
     {
-      int descriptor = events[i].data.fd;
-      if (descriptor == interrupter_.read_descriptor())
+      void* ptr = events[i].data.ptr;
+      if (ptr == &interrupter_)
       {
-        interrupter_.reset();
+        // No need to reset the interrupter since we're leaving the descriptor
+        // in a ready-to-read state and relying on edge-triggered notifications
+        // to make it so that we only get woken up when the descriptor's epoll
+        // registration is updated.
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+        if (timer_fd_ == -1)
+          check_timers = true;
+#else // defined(BOOST_ASIO_HAS_TIMERFD)
+        check_timers = true;
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
       }
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+      else if (ptr == &timer_fd_)
+      {
+        check_timers = true;
+      }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
       else
       {
-        bool more_reads = false;
-        bool more_writes = false;
-        bool more_except = false;
-        boost::system::error_code ec;
+        descriptor_state* descriptor_data = static_cast<descriptor_state*>(ptr);
+        mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
 
         // Exception operations must be processed first to ensure that any
         // out-of-band data is read before normal data.
-        if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))
-          more_except = except_op_queue_.perform_operation(descriptor, ec);
-        else
-          more_except = except_op_queue_.has_operation(descriptor);
-
-        if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
-          more_reads = read_op_queue_.perform_operation(descriptor, ec);
-        else
-          more_reads = read_op_queue_.has_operation(descriptor);
-
-        if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
-          more_writes = write_op_queue_.perform_operation(descriptor, ec);
-        else
-          more_writes = write_op_queue_.has_operation(descriptor);
-
-        if ((events[i].events & (EPOLLERR | EPOLLHUP)) != 0
-              && (events[i].events & ~(EPOLLERR | EPOLLHUP)) == 0
-              && !more_except && !more_reads && !more_writes)
+        static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
+        for (int j = max_ops - 1; j >= 0; --j)
         {
-          // If we have an event and no operations associated with the
-          // descriptor then we need to delete the descriptor from epoll. The
-          // epoll_wait system call can produce EPOLLHUP or EPOLLERR events
-          // when there is no operation pending, so if we do not remove the
-          // descriptor we can end up in a tight loop of repeated
-          // calls to epoll_wait.
-          epoll_event ev = { 0, { 0 } };
-          epoll_ctl(epoll_fd_, EPOLL_CTL_DEL, descriptor, &ev);
-        }
-        else
-        {
-          epoll_event ev = { 0, { 0 } };
-          ev.events = EPOLLERR | EPOLLHUP;
-          if (more_reads)
-            ev.events |= EPOLLIN;
-          if (more_writes)
-            ev.events |= EPOLLOUT;
-          if (more_except)
-            ev.events |= EPOLLPRI;
-          ev.data.fd = descriptor;
-          int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
-          if (result != 0 && errno == ENOENT)
-            result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev);
-          if (result != 0)
+          if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP))
           {
-            ec = boost::system::error_code(errno,
-                boost::asio::error::get_system_category());
-            read_op_queue_.perform_all_operations(descriptor, ec);
-            write_op_queue_.perform_all_operations(descriptor, ec);
-            except_op_queue_.perform_all_operations(descriptor, ec);
+            while (reactor_op* op = descriptor_data->op_queue_[j].front())
+            {
+              if (op->perform())
+              {
+                descriptor_data->op_queue_[j].pop();
+                ops.push(op);
+              }
+              else
+                break;
+            }
           }
         }
       }
     }
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      timer_queues_[i]->dispatch_timers();
-      timer_queues_[i]->dispatch_cancellations();
-    }
-
-    // Issue any pending cancellations.
-    for (size_t i = 0; i < pending_cancellations_.size(); ++i)
-      cancel_ops_unlocked(pending_cancellations_[i]);
-    pending_cancellations_.clear();
 
-    // Determine whether epoll_wait should be called when the reactor next runs.
-    need_epoll_wait_ = !read_op_queue_.empty()
-      || !write_op_queue_.empty() || !except_op_queue_.empty();
-
-    complete_operations_and_timers(lock);
-  }
-
-  // Run the select loop in the thread.
-  void run_thread()
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    while (!stop_thread_)
+    if (check_timers)
     {
-      lock.unlock();
-      run(true);
-      lock.lock();
-    }
-  }
+      mutex::scoped_lock common_lock(mutex_);
+      timer_queues_.get_ready_timers(ops);
 
-  // Entry point for the select loop thread.
-  static void call_run_thread(epoll_reactor* reactor)
-  {
-    reactor->run_thread();
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+      if (timer_fd_ != -1)
+      {
+        itimerspec new_timeout;
+        itimerspec old_timeout;
+        int flags = get_timeout(new_timeout);
+        timerfd_settime(timer_fd_, flags, &new_timeout, &old_timeout);
+      }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+    }
   }
 
   // Interrupt the select loop.
   void interrupt()
   {
-    interrupter_.interrupt();
+    epoll_event ev = { 0, { 0 } };
+    ev.events = EPOLLIN | EPOLLERR | EPOLLET;
+    ev.data.ptr = &interrupter_;
+    epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, interrupter_.read_descriptor(), &ev);
   }
 
+private:
   // The hint to pass to epoll_create to size its data structures.
   enum { epoll_size = 20000 };
 
@@ -606,117 +421,65 @@
     return fd;
   }
 
-  // Check if all timer queues are empty.
-  bool all_timer_queues_are_empty() const
-  {
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      if (!timer_queues_[i]->empty())
-        return false;
-    return true;
-  }
-
   // Get the timeout value for the epoll_wait call. The timeout value is
   // returned as a number of milliseconds. A return value of -1 indicates
   // that epoll_wait should block indefinitely.
   int get_timeout()
   {
-    if (all_timer_queues_are_empty())
-      return -1;
-
     // By default we will wait no longer than 5 minutes. This will ensure that
     // any changes to the system clock are detected after no longer than this.
-    boost::posix_time::time_duration minimum_wait_duration
-      = boost::posix_time::minutes(5);
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      boost::posix_time::time_duration wait_duration
-        = timer_queues_[i]->wait_duration();
-      if (wait_duration < minimum_wait_duration)
-        minimum_wait_duration = wait_duration;
-    }
-
-    if (minimum_wait_duration > boost::posix_time::time_duration())
-    {
-      int milliseconds = minimum_wait_duration.total_milliseconds();
-      return milliseconds > 0 ? milliseconds : 1;
-    }
-    else
-    {
-      return 0;
-    }
+    return timer_queues_.wait_duration_msec(5 * 60 * 1000);
   }
 
-  // Cancel all operations associated with the given descriptor. The do_cancel
-  // function of the handler objects will be invoked. This function does not
-  // acquire the epoll_reactor's mutex.
-  void cancel_ops_unlocked(socket_type descriptor)
-  {
-    bool interrupt = read_op_queue_.cancel_operations(descriptor);
-    interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
-    interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
-    if (interrupt)
-      interrupter_.interrupt();
-  }
-
-  // Clean up operations and timers. We must not hold the lock since the
-  // destructors may make calls back into this reactor. We make a copy of the
-  // vector of timer queues since the original may be modified while the lock
-  // is not held.
-  void complete_operations_and_timers(
-      boost::asio::detail::mutex::scoped_lock& lock)
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+  // Get the timeout value for the timer descriptor. The return value is the
+  // flag argument to be used when calling timerfd_settime.
+  int get_timeout(itimerspec& ts)
   {
-    timer_queues_for_cleanup_ = timer_queues_;
-    lock.unlock();
-    read_op_queue_.complete_operations();
-    write_op_queue_.complete_operations();
-    except_op_queue_.complete_operations();
-    for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
-      timer_queues_for_cleanup_[i]->complete_timers();
+    ts.it_interval.tv_sec = 0;
+    ts.it_interval.tv_nsec = 0;
+
+    long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+    ts.it_value.tv_sec = usec / 1000000;
+    ts.it_value.tv_nsec = usec ? (usec % 1000000) * 1000 : 1;
+
+    return usec ? 0 : TFD_TIMER_ABSTIME;
   }
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_;
 
   // Mutex to protect access to internal data.
-  boost::asio::detail::mutex mutex_;
+  mutex mutex_;
 
   // The epoll file descriptor.
   int epoll_fd_;
 
-  // Whether the epoll_wait call is currently in progress
-  bool wait_in_progress_;
+  // The timer file descriptor.
+  int timer_fd_;
 
   // The interrupter is used to break a blocking epoll_wait call.
   select_interrupter interrupter_;
 
-  // The queue of read operations.
-  reactor_op_queue<socket_type> read_op_queue_;
-
-  // The queue of write operations.
-  reactor_op_queue<socket_type> write_op_queue_;
-
-  // The queue of except operations.
-  reactor_op_queue<socket_type> except_op_queue_;
-
   // The timer queues.
-  std::vector<timer_queue_base*> timer_queues_;
-
-  // A copy of the timer queues, used when cleaning up timers. The copy is
-  // stored as a class data member to avoid unnecessary memory allocation.
-  std::vector<timer_queue_base*> timer_queues_for_cleanup_;
-
-  // The descriptors that are pending cancellation.
-  std::vector<socket_type> pending_cancellations_;
-
-  // Does the reactor loop thread need to stop.
-  bool stop_thread_;
-
-  // The thread that is running the reactor loop.
-  boost::asio::detail::thread* thread_;
+  timer_queue_set timer_queues_;
 
   // Whether the service has been shut down.
   bool shutdown_;
 
-  // Whether we need to call epoll_wait the next time the reactor is run.
-  bool need_epoll_wait_;
+  // 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_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/epoll_reactor_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor_fwd.hpp	(original)
+++ trunk/boost/asio/detail/epoll_reactor_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -33,7 +33,6 @@
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class epoll_reactor;
 
 } // namespace detail
Added: trunk/boost/asio/detail/fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,68 @@
+//
+// fenced_block.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_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if 1//!defined(BOOST_HAS_THREADS)
+# include <boost/asio/detail/null_fenced_block.hpp>
+#elif defined(__MACH__) && defined(__APPLE__)
+# include <boost/asio/detail/macos_fenced_block.hpp>
+#elif defined(__sun)
+# include <boost/asio/detail/solaris_fenced_block.hpp>
+#elif defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+# include <boost/asio/detail/gcc_fenced_block.hpp>
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+# include <boost/asio/detail/gcc_x86_fenced_block.hpp>
+#elif defined(BOOST_WINDOWS)
+# include <boost/asio/detail/win_fenced_block.hpp>
+#else
+# include <boost/asio/detail/null_fenced_block.hpp>
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if 1//!defined(BOOST_HAS_THREADS)
+typedef null_fenced_block fenced_block;
+#elif defined(__MACH__) && defined(__APPLE__)
+typedef macos_fenced_block fenced_block;
+#elif defined(__sun)
+typedef solaris_fenced_block fenced_block;
+#elif defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+typedef gcc_fenced_block fenced_block;
+#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+typedef gcc_x86_fenced_block fenced_block;
+#elif defined(BOOST_WINDOWS)
+typedef win_fenced_block fenced_block;
+#else
+typedef null_fenced_block fenced_block;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP
Added: trunk/boost/asio/detail/gcc_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/gcc_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,61 @@
+//
+// gcc_fenced_block.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_GCC_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(__GNUC__) \
+  && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  gcc_fenced_block()
+    : value_(0)
+  {
+    __sync_lock_test_and_set(&value_, 1);
+  }
+
+  // Destructor.
+  ~gcc_fenced_block()
+  {
+    __sync_lock_release(&value_);
+  }
+
+private:
+  int value_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(__GNUC__)
+       // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP
Added: trunk/boost/asio/detail/gcc_x86_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/gcc_x86_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,63 @@
+//
+// gcc_x86_fenced_block.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_GCC_X86_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class gcc_x86_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  gcc_x86_fenced_block()
+  {
+    barrier();
+  }
+
+  // Destructor.
+  ~gcc_x86_fenced_block()
+  {
+    barrier();
+  }
+
+private:
+  static int barrier()
+  {
+    int r = 0;
+    __asm__ __volatile__ ("xchgl %%eax, %0" : "=m" (r) : : "memory", "cc");
+    return r;
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP
Deleted: trunk/boost/asio/detail/handler_base_from_member.hpp
==============================================================================
--- trunk/boost/asio/detail/handler_base_from_member.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
+++ (empty file)
@@ -1,78 +0,0 @@
-//
-// handler_base_from_member.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_HANDLER_BASE_FROM_MEMBER_HPP
-#define BOOST_ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-// Base class for classes that need a handler data member. Forwards the custom
-// allocation and invocation hooks to the contained handler.
-template <typename Handler>
-class handler_base_from_member
-{
-public:
-  handler_base_from_member(Handler handler)
-    : handler_(handler)
-  {
-  }
-
-//protected:
-  Handler handler_;
-
-protected:
-  // Protected destructor to prevent deletion through this type.
-  ~handler_base_from_member()
-  {
-  }
-};
-
-template <typename Handler>
-inline void* asio_handler_allocate(std::size_t size,
-    handler_base_from_member<Handler>* this_handler)
-{
-  return boost_asio_handler_alloc_helpers::allocate(
-      size, this_handler->handler_);
-}
-
-template <typename Handler>
-inline void asio_handler_deallocate(void* pointer, std::size_t size,
-    handler_base_from_member<Handler>* this_handler)
-{
-  boost_asio_handler_alloc_helpers::deallocate(
-      pointer, size, this_handler->handler_);
-}
-
-template <typename Function, typename Handler>
-inline void asio_handler_invoke(const Function& function,
-    handler_base_from_member<Handler>* this_handler)
-{
-  boost_asio_handler_invoke_helpers::invoke(
-      function, this_handler->handler_);
-}
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_HANDLER_BASE_FROM_MEMBER_HPP
Deleted: trunk/boost/asio/detail/handler_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/handler_queue.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
+++ (empty file)
@@ -1,231 +0,0 @@
-//
-// handler_queue.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_HANDLER_QUEUE_HPP
-#define BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-class handler_queue
-  : private noncopyable
-{
-public:
-  // Base class for handlers in the queue.
-  class handler
-    : private noncopyable
-  {
-  public:
-    void invoke()
-    {
-      invoke_func_(this);
-    }
-
-    void destroy()
-    {
-      destroy_func_(this);
-    }
-
-  protected:
-    typedef void (*invoke_func_type)(handler*);
-    typedef void (*destroy_func_type)(handler*);
-
-    handler(invoke_func_type invoke_func,
-        destroy_func_type destroy_func)
-      : next_(0),
-        invoke_func_(invoke_func),
-        destroy_func_(destroy_func)
-    {
-    }
-
-    ~handler()
-    {
-    }
-
-  private:
-    friend class handler_queue;
-    handler* next_;
-    invoke_func_type invoke_func_;
-    destroy_func_type destroy_func_;
-  };
-
-  // Smart point to manager handler lifetimes.
-  class scoped_ptr
-    : private noncopyable
-  {
-  public:
-    explicit scoped_ptr(handler* h)
-      : handler_(h)
-    {
-    }
-
-    ~scoped_ptr()
-    {
-      if (handler_)
-        handler_->destroy();
-    }
-
-    handler* get() const
-    {
-      return handler_;
-    }
-
-    handler* release()
-    {
-      handler* tmp = handler_;
-      handler_ = 0;
-      return tmp;
-    }
-
-  private:
-    handler* handler_;
-  };
-
-  // Constructor.
-  handler_queue()
-    : front_(0),
-      back_(0)
-  {
-  }
-
-  // Wrap a handler to be pushed into the queue.
-  template <typename Handler>
-  static handler* wrap(Handler h)
-  {
-    // Allocate and construct an object to wrap the handler.
-    typedef handler_wrapper<Handler> value_type;
-    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
-    raw_handler_ptr<alloc_traits> raw_ptr(h);
-    handler_ptr<alloc_traits> ptr(raw_ptr, h);
-    return ptr.release();
-  }
-
-  // Get the handler at the front of the queue.
-  handler* front()
-  {
-    return front_;
-  }
-
-  // Pop a handler from the front of the queue.
-  void pop()
-  {
-    if (front_)
-    {
-      handler* tmp = front_;
-      front_ = front_->next_;
-      if (front_ == 0)
-        back_ = 0;
-      tmp->next_= 0;
-    }
-  }
-
-  // Push a handler on to the back of the queue.
-  void push(handler* h)
-  {
-    h->next_ = 0;
-    if (back_)
-    {
-      back_->next_ = h;
-      back_ = h;
-    }
-    else
-    {
-      front_ = back_ = h;
-    }
-  }
-
-  // Whether the queue is empty.
-  bool empty() const
-  {
-    return front_ == 0;
-  }
-
-private:
-  // Template wrapper for handlers.
-  template <typename Handler>
-  class handler_wrapper
-    : public handler
-  {
-  public:
-    handler_wrapper(Handler h)
-      : handler(
-          &handler_wrapper<Handler>::do_call,
-          &handler_wrapper<Handler>::do_destroy),
-        handler_(h)
-    {
-    }
-
-    static void do_call(handler* base)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(h->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Make the upcall.
-      boost_asio_handler_invoke_helpers::invoke(handler, handler);
-    }
-
-    static void do_destroy(handler* base)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      // 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(h->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-    }
-
-  private:
-    Handler handler_;
-  };
-
-  // The front of the queue.
-  handler* front_;
-
-  // The back of the queue.
-  handler* back_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_HANDLER_QUEUE_HPP
Modified: trunk/boost/asio/detail/hash_map.hpp
==============================================================================
--- trunk/boost/asio/detail/hash_map.hpp	(original)
+++ trunk/boost/asio/detail/hash_map.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -21,7 +21,6 @@
 #include <cassert>
 #include <list>
 #include <utility>
-#include <vector>
 #include <boost/functional/hash.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
@@ -62,9 +61,16 @@
 
   // Constructor.
   hash_map()
-    : size_(0)
+    : size_(0),
+      buckets_(0),
+      num_buckets_(0)
   {
-    rehash(hash_size(0));
+  }
+
+  // Destructor.
+  ~hash_map()
+  {
+    delete[] buckets_;
   }
 
   // Get an iterator for the beginning of the map.
@@ -100,17 +106,20 @@
   // Find an entry in the map.
   iterator find(const K& k)
   {
-    size_t bucket = calculate_hash_value(k) % buckets_.size();
-    iterator it = buckets_[bucket].first;
-    if (it == values_.end())
-      return values_.end();
-    iterator end = buckets_[bucket].last;
-    ++end;
-    while (it != end)
+    if (num_buckets_)
     {
-      if (it->first == k)
-        return it;
-      ++it;
+      size_t bucket = calculate_hash_value(k) % num_buckets_;
+      iterator it = buckets_[bucket].first;
+      if (it == values_.end())
+        return values_.end();
+      iterator end = buckets_[bucket].last;
+      ++end;
+      while (it != end)
+      {
+        if (it->first == k)
+          return it;
+        ++it;
+      }
     }
     return values_.end();
   }
@@ -118,17 +127,20 @@
   // Find an entry in the map.
   const_iterator find(const K& k) const
   {
-    size_t bucket = calculate_hash_value(k) % buckets_.size();
-    const_iterator it = buckets_[bucket].first;
-    if (it == values_.end())
-      return it;
-    const_iterator end = buckets_[bucket].last;
-    ++end;
-    while (it != end)
+    if (num_buckets_)
     {
-      if (it->first == k)
+      size_t bucket = calculate_hash_value(k) % num_buckets_;
+      const_iterator it = buckets_[bucket].first;
+      if (it == values_.end())
         return it;
-      ++it;
+      const_iterator end = buckets_[bucket].last;
+      ++end;
+      while (it != end)
+      {
+        if (it->first == k)
+          return it;
+        ++it;
+      }
     }
     return values_.end();
   }
@@ -136,9 +148,9 @@
   // Insert a new entry into the map.
   std::pair<iterator, bool> insert(const value_type& v)
   {
-    if (size_ + 1 >= buckets_.size())
+    if (size_ + 1 >= num_buckets_)
       rehash(hash_size(size_ + 1));
-    size_t bucket = calculate_hash_value(v.first) % buckets_.size();
+    size_t bucket = calculate_hash_value(v.first) % num_buckets_;
     iterator it = buckets_[bucket].first;
     if (it == values_.end())
     {
@@ -165,7 +177,7 @@
   {
     assert(it != values_.end());
 
-    size_t bucket = calculate_hash_value(it->first) % buckets_.size();
+    size_t bucket = calculate_hash_value(it->first) % num_buckets_;
     bool is_first = (it == buckets_[bucket].first);
     bool is_last = (it == buckets_[bucket].last);
     if (is_first && is_last)
@@ -179,6 +191,14 @@
     --size_;
   }
 
+  // Erase a key from the map.
+  void erase(const K& k)
+  {
+    iterator it = find(k);
+    if (it != values_.end())
+      erase(it);
+  }
+
   // Remove all entries from the map.
   void clear()
   {
@@ -187,8 +207,9 @@
     size_ = 0;
 
     // Initialise all buckets to empty.
-    for (size_t i = 0; i < buckets_.size(); ++i)
-      buckets_[i].first = buckets_[i].last = values_.end();
+    iterator end = values_.end();
+    for (size_t i = 0; i < num_buckets_; ++i)
+      buckets_[i].first = buckets_[i].last = end;
   }
 
 private:
@@ -215,21 +236,24 @@
   // Re-initialise the hash from the values already contained in the list.
   void rehash(std::size_t num_buckets)
   {
-    if (num_buckets == buckets_.size())
+    if (num_buckets == num_buckets_)
       return;
+    num_buckets_ = num_buckets;
 
     iterator end = values_.end();
 
     // Update number of buckets and initialise all buckets to empty.
-    buckets_.resize(num_buckets);
-    for (std::size_t i = 0; i < buckets_.size(); ++i)
+    bucket_type* tmp = new bucket_type[num_buckets_];
+    delete[] buckets_;
+    buckets_ = tmp;
+    for (std::size_t i = 0; i < num_buckets_; ++i)
       buckets_[i].first = buckets_[i].last = end;
 
     // Put all values back into the hash.
     iterator iter = values_.begin();
     while (iter != end)
     {
-      std::size_t bucket = calculate_hash_value(iter->first) % buckets_.size();
+      std::size_t bucket = calculate_hash_value(iter->first) % num_buckets_;
       if (buckets_[bucket].last == end)
       {
         buckets_[bucket].first = buckets_[bucket].last = iter++;
@@ -282,14 +306,15 @@
   // The type for a bucket in the hash table.
   struct bucket_type
   {
-    bucket_type() {}
-    bucket_type(const bucket_type&) { /* noop */ }
     iterator first;
     iterator last;
   };
 
   // The buckets in the hash.
-  std::vector<bucket_type> buckets_;
+  bucket_type* buckets_;
+
+  // The number of buckets in the hash.
+  std::size_t num_buckets_;
 };
 
 } // namespace detail
Deleted: trunk/boost/asio/detail/indirect_handler_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/indirect_handler_queue.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
+++ (empty file)
@@ -1,293 +0,0 @@
-//
-// indirect_handler_queue.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_INDIRECT_HANDLER_QUEUE_HPP
-#define BOOST_ASIO_DETAIL_INDIRECT_HANDLER_QUEUE_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1310)
-extern "C" void _ReadWriteBarrier();
-# pragma intrinsic(_ReadWriteBarrier)
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1310)
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-class indirect_handler_queue
-  : private noncopyable
-{
-public:
-  class handler;
-
-  // Element for a node in the queue.
-  class node
-  {
-  public:
-    node()
-      : version_(0),
-        handler_(0),
-        next_(0)
-    {
-    }
-
-  private:
-    friend class indirect_handler_queue;
-    unsigned long version_;
-    handler* handler_;
-    node* next_;
-  };
-
-  // Base class for handlers in the queue.
-  class handler
-    : private noncopyable
-  {
-  public:
-    void invoke()
-    {
-      invoke_func_(this);
-    }
-
-    void destroy()
-    {
-      destroy_func_(this);
-    }
-
-  protected:
-    typedef void (*invoke_func_type)(handler*);
-    typedef void (*destroy_func_type)(handler*);
-
-    handler(invoke_func_type invoke_func,
-        destroy_func_type destroy_func)
-      : node_(new node),
-        invoke_func_(invoke_func),
-        destroy_func_(destroy_func)
-    {
-    }
-
-    ~handler()
-    {
-      if (node_)
-        delete node_;
-    }
-
-  private:
-    friend class indirect_handler_queue;
-    node* node_;
-    invoke_func_type invoke_func_;
-    destroy_func_type destroy_func_;
-  };
-
-  // Smart point to manager handler lifetimes.
-  class scoped_ptr
-    : private noncopyable
-  {
-  public:
-    explicit scoped_ptr(handler* h)
-      : handler_(h)
-    {
-    }
-
-    ~scoped_ptr()
-    {
-      if (handler_)
-        handler_->destroy();
-    }
-
-    handler* get() const
-    {
-      return handler_;
-    }
-
-    handler* release()
-    {
-      handler* tmp = handler_;
-      handler_ = 0;
-      return tmp;
-    }
-
-  private:
-    handler* handler_;
-  };
-
-  // Constructor.
-  indirect_handler_queue()
-    : front_(new node),
-      back_(front_),
-      next_version_(1)
-  {
-  }
-
-  // Destructor.
-  ~indirect_handler_queue()
-  {
-    while (front_)
-    {
-      node* tmp = front_;
-      front_ = front_->next_;
-      delete tmp;
-    }
-  }
-
-  // Wrap a handler to be pushed into the queue.
-  template <typename Handler>
-  static handler* wrap(Handler h)
-  {
-    // Allocate and construct an object to wrap the handler.
-    typedef handler_wrapper<Handler> value_type;
-    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
-    raw_handler_ptr<alloc_traits> raw_ptr(h);
-    handler_ptr<alloc_traits> ptr(raw_ptr, h);
-    return ptr.release();
-  }
-
-  // Determine whether the queue has something ready to pop.
-  bool poppable()
-  {
-    return front_->next_ != 0;
-  }
-
-  // The version number at the front of the queue.
-  unsigned long front_version()
-  {
-    return front_->version_;
-  }
-
-  // The version number at the back of the queue.
-  unsigned long back_version()
-  {
-    return back_->version_;
-  }
-
-  // Pop a handler from the front of the queue.
-  handler* pop()
-  {
-    node* n = front_;
-    node* new_front = n->next_;
-    if (new_front)
-    {
-      handler* h = new_front->handler_;
-      h->node_ = n;
-      new_front->handler_ = 0;
-      front_ = new_front;
-      return h;
-    }
-    return 0;
-  }
-
-  // Push a handler on to the back of the queue.
-  void push(handler* h)
-  {
-    node* n = h->node_;
-    h->node_ = 0;
-    n->version_ = next_version_;
-    next_version_ += 2;
-    n->handler_ = h;
-    n->next_ = 0;
-    memory_barrier();
-    back_->next_ = n;
-    back_ = n;
-  }
-
-private:
-  // Template wrapper for handlers.
-  template <typename Handler>
-  class handler_wrapper
-    : public handler
-  {
-  public:
-    handler_wrapper(Handler h)
-      : handler(
-          &handler_wrapper<Handler>::do_call,
-          &handler_wrapper<Handler>::do_destroy),
-        handler_(h)
-    {
-    }
-
-    static void do_call(handler* base)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(h->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Make the upcall.
-      boost_asio_handler_invoke_helpers::invoke(handler, handler);
-    }
-
-    static void do_destroy(handler* base)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      // 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(h->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-    }
-
-  private:
-    Handler handler_;
-  };
-
-  // Helper function to create a memory barrier.
-  static void memory_barrier()
-  {
-#if defined(_GLIBCXX_WRITE_MEM_BARRIER)
-    _GLIBCXX_WRITE_MEM_BARRIER;
-#elif defined(_MSC_VER) && (_MSC_VER >= 1310)
-    _ReadWriteBarrier();
-#else
-# error memory barrier required
-#endif
-  }
-
-  // The front of the queue.
-  node* front_;
-
-  // The back of the queue.
-  node* back_;
-
-  // The next version counter to be assigned to a node.
-  unsigned long next_version_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_INDIRECT_HANDLER_QUEUE_HPP
Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp	(original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -24,28 +24,27 @@
 
 #include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
-#include <vector>
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/time.h>
 #include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/system/system_error.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/task_io_service.hpp>
-#include <boost/asio/detail/thread.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/reactor_op_queue.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
 #include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/signal_blocker.hpp>
 #include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_op.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_fwd.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
 
 // Older versions of Mac OS X may not define EV_OOBAND.
 #if !defined(EV_OOBAND)
@@ -56,43 +55,29 @@
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class kqueue_reactor
-  : public boost::asio::detail::service_base<kqueue_reactor<Own_Thread> >
+  : public boost::asio::detail::service_base<kqueue_reactor>
 {
 public:
+  enum { read_op = 0, write_op = 1,
+    connect_op = 1, except_op = 2, max_ops = 3 };
+
   // Per-descriptor data.
   struct per_descriptor_data
   {
-    bool allow_speculative_read;
-    bool allow_speculative_write;
+    bool allow_speculative[max_ops];
   };
 
   // Constructor.
   kqueue_reactor(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        kqueue_reactor<Own_Thread> >(io_service),
+    : boost::asio::detail::service_base<kqueue_reactor>(io_service),
+      io_service_(use_service<io_service_impl>(io_service)),
       mutex_(),
       kqueue_fd_(do_kqueue_create()),
-      wait_in_progress_(false),
       interrupter_(),
-      read_op_queue_(),
-      write_op_queue_(),
-      except_op_queue_(),
-      pending_cancellations_(),
-      stop_thread_(false),
-      thread_(0),
       shutdown_(false),
       need_kqueue_wait_(true)
   {
-    // Start the reactor's internal thread only if needed.
-    if (Own_Thread)
-    {
-      boost::asio::detail::signal_blocker sb;
-      thread_ = new boost::asio::detail::thread(
-          bind_handler(&kqueue_reactor::call_run_thread, this));
-    }
-
     // Add the interrupter's descriptor to the kqueue.
     struct kevent event;
     EV_SET(&event, interrupter_.read_descriptor(),
@@ -112,65 +97,49 @@
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     shutdown_ = true;
-    stop_thread_ = true;
     lock.unlock();
 
-    if (thread_)
-    {
-      interrupter_.interrupt();
-      thread_->join();
-      delete thread_;
-      thread_ = 0;
-    }
+    op_queue<operation> ops;
 
-    read_op_queue_.destroy_operations();
-    write_op_queue_.destroy_operations();
-    except_op_queue_.destroy_operations();
+    for (int i = 0; i < max_ops; ++i)
+      op_queue_[i].get_all_operations(ops);
 
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->destroy_timers();
-    timer_queues_.clear();
+    timer_queues_.get_all_timers(ops);
   }
 
-  // Initialise the task, but only if the reactor is not in its own thread.
+  // Initialise the task.
   void init_task()
   {
-    if (!Own_Thread)
-    {
-      typedef task_io_service<kqueue_reactor<Own_Thread> > task_io_service_type;
-      use_service<task_io_service_type>(this->get_io_service()).init_task();
-    }
+    io_service_.init_task();
   }
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
   int register_descriptor(socket_type, per_descriptor_data& descriptor_data)
   {
-    descriptor_data.allow_speculative_read = true;
-    descriptor_data.allow_speculative_write = true;
+    descriptor_data.allow_speculative[read_op] = true;
+    descriptor_data.allow_speculative[write_op] = true;
+    descriptor_data.allow_speculative[except_op] = true;
 
     return 0;
   }
 
-  // Start a new read operation. The handler object will be invoked when the
-  // given descriptor is ready to be read, or an error has occurred.
-  template <typename Handler>
-  void start_read_op(socket_type descriptor,
-      per_descriptor_data& descriptor_data, Handler handler,
-      bool allow_speculative_read = true)
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  void start_op(int op_type, socket_type descriptor,
+      per_descriptor_data& descriptor_data,
+      reactor_op* op, bool allow_speculative)
   {
-    if (allow_speculative_read && descriptor_data.allow_speculative_read)
+    if (allow_speculative && descriptor_data.allow_speculative[op_type])
     {
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
+      if (op->perform())
       {
-        handler.complete(ec, bytes_transferred);
+        io_service_.post_immediate_completion(op);
         return;
       }
 
       // We only get one shot at a speculative read in this function.
-      allow_speculative_read = false;
+      allow_speculative = false;
     }
 
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
@@ -178,146 +147,49 @@
     if (shutdown_)
       return;
 
-    if (!allow_speculative_read)
+    if (!allow_speculative)
       need_kqueue_wait_ = true;
-    else if (!read_op_queue_.has_operation(descriptor))
+    else if (!op_queue_[op_type].has_operation(descriptor))
     {
       // Speculative reads are ok as there are no queued read operations.
-      descriptor_data.allow_speculative_read = true;
+      descriptor_data.allow_speculative[op_type] = true;
 
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
+      if (op->perform())
       {
-        handler.complete(ec, bytes_transferred);
+        lock.unlock();
+        io_service_.post_immediate_completion(op);
         return;
       }
     }
 
     // Speculative reads are not ok as there will be queued read operations.
-    descriptor_data.allow_speculative_read = false;
+    descriptor_data.allow_speculative[op_type] = false;
 
-    if (read_op_queue_.enqueue_operation(descriptor, handler))
+    bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+    io_service_.work_started();
+    if (first)
     {
       struct kevent event;
-      EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
-      if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
+      switch (op_type)
       {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        read_op_queue_.perform_all_operations(descriptor, ec);
-      }
-    }
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready to be written, or an error has occurred.
-  template <typename Handler>
-  void start_write_op(socket_type descriptor,
-      per_descriptor_data& descriptor_data, Handler handler,
-      bool allow_speculative_write = true)
-  {
-    if (allow_speculative_write && descriptor_data.allow_speculative_write)
-    {
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
-      {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-
-      // We only get one shot at a speculative write in this function.
-      allow_speculative_write = false;
-    }
-
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (!allow_speculative_write)
-      need_kqueue_wait_ = true;
-    else if (!write_op_queue_.has_operation(descriptor))
-    {
-      // Speculative writes are ok as there are no queued write operations.
-      descriptor_data.allow_speculative_write = true;
-
-      boost::system::error_code ec;
-      std::size_t bytes_transferred = 0;
-      if (handler.perform(ec, bytes_transferred))
-      {
-        handler.complete(ec, bytes_transferred);
-        return;
-      }
-    }
-
-    // Speculative writes are not ok as there will be queued write operations.
-    descriptor_data.allow_speculative_write = false;
-
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      struct kevent event;
-      EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
-      if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
-      {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        write_op_queue_.perform_all_operations(descriptor, ec);
-      }
-    }
-  }
-
-  // Start a new exception operation. The handler object will be invoked when
-  // the given descriptor has exception information, or an error has occurred.
-  template <typename Handler>
-  void start_except_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    if (except_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      struct kevent event;
-      if (read_op_queue_.has_operation(descriptor))
+      case read_op:
         EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
-      else
-        EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
-      if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
-      {
-        boost::system::error_code ec(errno,
-            boost::asio::error::get_system_category());
-        except_op_queue_.perform_all_operations(descriptor, ec);
+        break;
+      case write_op:
+        EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
+        break;
+      case except_op:
+        if (op_queue_[read_op].has_operation(descriptor))
+          EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
+        else
+          EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, EV_OOBAND, 0, 0);
+        break;
       }
-    }
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready to be written, or an error has occurred.
-  template <typename Handler>
-  void start_connect_op(socket_type descriptor,
-      per_descriptor_data& descriptor_data, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    if (shutdown_)
-      return;
-
-    // Speculative writes are not ok as there will be queued write operations.
-    descriptor_data.allow_speculative_write = false;
-
-    if (write_op_queue_.enqueue_operation(descriptor, handler))
-    {
-      struct kevent event;
-      EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
       if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
       {
         boost::system::error_code ec(errno,
             boost::asio::error::get_system_category());
-        write_op_queue_.perform_all_operations(descriptor, ec);
+        cancel_ops_unlocked(descriptor, ec);
       }
     }
   }
@@ -328,7 +200,7 @@
   void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    cancel_ops_unlocked(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Cancel any operations that are running against the descriptor and remove
@@ -344,7 +216,7 @@
     ::kevent(kqueue_fd_, event, 2, 0, 0, 0);
     
     // Cancel any outstanding operations associated with the descriptor.
-    cancel_ops_unlocked(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Add a new timer queue to the reactor.
@@ -352,7 +224,7 @@
   void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    timer_queues_.push_back(&timer_queue);
+    timer_queues_.insert(&timer_queue);
   }
 
   // Remove a timer queue from the reactor.
@@ -360,77 +232,53 @@
   void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      if (timer_queues_[i] == &timer_queue)
-      {
-        timer_queues_.erase(timer_queues_.begin() + i);
-        return;
-      }
-    }
+    timer_queues_.erase(&timer_queue);
   }
 
-  // Schedule a timer in the given timer queue to expire at the specified
-  // absolute time. The handler object will be invoked when the timer expires.
-  template <typename Time_Traits, typename Handler>
+  // 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, Handler handler, void* token)
+      const typename Time_Traits::time_type& time, timer_op* op, void* token)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
-      if (timer_queue.enqueue_timer(time, handler, token))
+    {
+      bool earliest = timer_queue.enqueue_timer(time, op, token);
+      io_service_.work_started();
+      if (earliest)
         interrupter_.interrupt();
+    }
   }
 
-  // Cancel the timer associated with the given token. Returns the number of
-  // handlers that have been posted or dispatched.
+  // 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)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    std::size_t n = timer_queue.cancel_timer(token);
-    if (n > 0)
-      interrupter_.interrupt();
+    op_queue<operation> ops;
+    std::size_t n = timer_queue.cancel_timer(token, ops);
+    lock.unlock();
+    io_service_.post_deferred_completions(ops);
     return n;
   }
 
-private:
-  friend class task_io_service<kqueue_reactor<Own_Thread> >;
-
   // Run the kqueue loop.
-  void run(bool block)
+  void run(bool block, op_queue<operation>& ops)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    // Dispatch any operation cancellations that were made while the select
-    // loop was not running.
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->dispatch_cancellations();
-
-    // Check if the thread is supposed to stop.
-    if (stop_thread_)
-    {
-      complete_operations_and_timers(lock);
-      return;
-    }
-
     // We can return immediately if there's no work to do and the reactor is
     // not supposed to block.
-    if (!block && read_op_queue_.empty() && write_op_queue_.empty()
-        && except_op_queue_.empty() && all_timer_queues_are_empty())
-    {
-      complete_operations_and_timers(lock);
+    if (!block && op_queue_[read_op].empty() && op_queue_[write_op].empty()
+        && op_queue_[except_op].empty() && timer_queues_.all_empty())
       return;
-    }
 
     // Determine how long to block while waiting for events.
     timespec timeout_buf = { 0, 0 };
     timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf;
 
-    wait_in_progress_ = true;
     lock.unlock();
 
     // Block on the kqueue descriptor.
@@ -440,7 +288,6 @@
       : 0;
 
     lock.lock();
-    wait_in_progress_ = false;
 
     // Dispatch the waiting events.
     for (int i = 0; i < num_events; ++i)
@@ -459,23 +306,22 @@
         {
           boost::system::error_code error(
               events[i].data, boost::asio::error::get_system_category());
-          except_op_queue_.perform_all_operations(descriptor, error);
-          read_op_queue_.perform_all_operations(descriptor, error);
+          op_queue_[except_op].perform_operations(descriptor, ops);
+          op_queue_[read_op].perform_operations(descriptor, ops);
         }
         else if (events[i].flags & EV_OOBAND)
         {
-          boost::system::error_code error;
-          more_except = except_op_queue_.perform_operation(descriptor, error);
+          more_except
+            = op_queue_[except_op].perform_operations(descriptor, ops);
           if (events[i].data > 0)
-            more_reads = read_op_queue_.perform_operation(descriptor, error);
+            more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
           else
-            more_reads = read_op_queue_.has_operation(descriptor);
+            more_reads = op_queue_[read_op].has_operation(descriptor);
         }
         else
         {
-          boost::system::error_code error;
-          more_reads = read_op_queue_.perform_operation(descriptor, error);
-          more_except = except_op_queue_.has_operation(descriptor);
+          more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
+          more_except = op_queue_[except_op].has_operation(descriptor);
         }
 
         // Update the descriptor in the kqueue.
@@ -490,8 +336,8 @@
         {
           boost::system::error_code error(errno,
               boost::asio::error::get_system_category());
-          except_op_queue_.perform_all_operations(descriptor, error);
-          read_op_queue_.perform_all_operations(descriptor, error);
+          op_queue_[except_op].cancel_operations(descriptor, ops, error);
+          op_queue_[read_op].cancel_operations(descriptor, ops, error);
         }
       }
       else if (events[i].filter == EVFILT_WRITE)
@@ -502,12 +348,11 @@
         {
           boost::system::error_code error(
               events[i].data, boost::asio::error::get_system_category());
-          write_op_queue_.perform_all_operations(descriptor, error);
+          op_queue_[write_op].cancel_operations(descriptor, ops, error);
         }
         else
         {
-          boost::system::error_code error;
-          more_writes = write_op_queue_.perform_operation(descriptor, error);
+          more_writes = op_queue_[write_op].perform_operations(descriptor, ops);
         }
 
         // Update the descriptor in the kqueue.
@@ -520,48 +365,15 @@
         {
           boost::system::error_code error(errno,
               boost::asio::error::get_system_category());
-          write_op_queue_.perform_all_operations(descriptor, error);
+          op_queue_[write_op].cancel_operations(descriptor, ops, error);
         }
       }
     }
-
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      timer_queues_[i]->dispatch_timers();
-      timer_queues_[i]->dispatch_cancellations();
-    }
-
-    // Issue any pending cancellations.
-    for (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
-      cancel_ops_unlocked(pending_cancellations_[i]);
-    pending_cancellations_.clear();
+    timer_queues_.get_ready_timers(ops);
 
     // Determine whether kqueue needs to be called next time the reactor is run.
-    need_kqueue_wait_ = !read_op_queue_.empty()
-      || !write_op_queue_.empty() || !except_op_queue_.empty();
-
-    complete_operations_and_timers(lock);
-  }
-
-  // Run the select loop in the thread.
-  void run_thread()
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    while (!stop_thread_)
-    {
-      lock.unlock();
-      run(true);
-      lock.lock();
-    }
-  }
-
-  // Entry point for the select loop thread.
-  static void call_run_thread(kqueue_reactor* reactor)
-  {
-    reactor->run_thread();
+    need_kqueue_wait_ = !op_queue_[read_op].empty()
+      || !op_queue_[write_op].empty() || !op_queue_[except_op].empty();
   }
 
   // Interrupt the select loop.
@@ -570,6 +382,7 @@
     interrupter_.interrupt();
   }
 
+private:
   // Create the kqueue file descriptor. Throws an exception if the descriptor
   // cannot be created.
   static int do_kqueue_create()
@@ -586,112 +399,45 @@
     return fd;
   }
 
-  // Check if all timer queues are empty.
-  bool all_timer_queues_are_empty() const
-  {
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      if (!timer_queues_[i]->empty())
-        return false;
-    return true;
-  }
-
   // Get the timeout value for the kevent call.
   timespec* get_timeout(timespec& ts)
   {
-    if (all_timer_queues_are_empty())
-      return 0;
-
     // By default we will wait no longer than 5 minutes. This will ensure that
     // any changes to the system clock are detected after no longer than this.
-    boost::posix_time::time_duration minimum_wait_duration
-      = boost::posix_time::minutes(5);
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      boost::posix_time::time_duration wait_duration
-        = timer_queues_[i]->wait_duration();
-      if (wait_duration < minimum_wait_duration)
-        minimum_wait_duration = wait_duration;
-    }
-
-    if (minimum_wait_duration > boost::posix_time::time_duration())
-    {
-      ts.tv_sec = minimum_wait_duration.total_seconds();
-      ts.tv_nsec = minimum_wait_duration.total_nanoseconds() % 1000000000;
-    }
-    else
-    {
-      ts.tv_sec = 0;
-      ts.tv_nsec = 0;
-    }
-
+    long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+    ts.tv_sec = usec / 1000000;
+    ts.tv_nsec = (usec % 1000000) * 1000;
     return &ts;
   }
 
-  // Cancel all operations associated with the given descriptor. The do_cancel
-  // function of the handler objects will be invoked. This function does not
-  // acquire the kqueue_reactor's mutex.
-  void cancel_ops_unlocked(socket_type descriptor)
-  {
-    bool interrupt = read_op_queue_.cancel_operations(descriptor);
-    interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
-    interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
-    if (interrupt)
-      interrupter_.interrupt();
-  }
-
-  // Clean up operations and timers. We must not hold the lock since the
-  // destructors may make calls back into this reactor. We make a copy of the
-  // vector of timer queues since the original may be modified while the lock
-  // is not held.
-  void complete_operations_and_timers(
-      boost::asio::detail::mutex::scoped_lock& lock)
-  {
-    timer_queues_for_cleanup_ = timer_queues_;
-    lock.unlock();
-    read_op_queue_.complete_operations();
-    write_op_queue_.complete_operations();
-    except_op_queue_.complete_operations();
-    for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
-      timer_queues_for_cleanup_[i]->complete_timers();
+  // Cancel all operations associated with the given descriptor. This function
+  // does not acquire the kqueue_reactor's mutex.
+  void cancel_ops_unlocked(socket_type descriptor,
+      const boost::system::error_code& ec)
+  {
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      op_queue_[i].cancel_operations(descriptor, ops, ec);
+    io_service_.post_deferred_completions(ops);
   }
 
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_;
+
   // Mutex to protect access to internal data.
   boost::asio::detail::mutex mutex_;
 
   // The kqueue file descriptor.
   int kqueue_fd_;
 
-  // Whether the kqueue wait call is currently in progress
-  bool wait_in_progress_;
-
   // The interrupter is used to break a blocking kevent call.
   select_interrupter interrupter_;
 
-  // The queue of read operations.
-  reactor_op_queue<socket_type> read_op_queue_;
-
-  // The queue of write operations.
-  reactor_op_queue<socket_type> write_op_queue_;
-
-  // The queue of except operations.
-  reactor_op_queue<socket_type> except_op_queue_;
+  // The queues of read, write and except operations.
+  reactor_op_queue<socket_type> op_queue_[max_ops];
 
   // The timer queues.
-  std::vector<timer_queue_base*> timer_queues_;
-
-  // A copy of the timer queues, used when cleaning up timers. The copy is
-  // stored as a class data member to avoid unnecessary memory allocation.
-  std::vector<timer_queue_base*> timer_queues_for_cleanup_;
-
-  // The descriptors that are pending cancellation.
-  std::vector<socket_type> pending_cancellations_;
-
-  // Does the reactor loop thread need to stop.
-  bool stop_thread_;
-
-  // The thread that is running the reactor loop.
-  boost::asio::detail::thread* thread_;
+  timer_queue_set timer_queues_;
 
   // Whether the service has been shut down.
   bool shutdown_;
Modified: trunk/boost/asio/detail/kqueue_reactor_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor_fwd.hpp	(original)
+++ trunk/boost/asio/detail/kqueue_reactor_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -30,7 +30,6 @@
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class kqueue_reactor;
 
 } // namespace detail
Added: trunk/boost/asio/detail/macos_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/macos_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,59 @@
+//
+// macos_fenced_block.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_MACOS_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#include <boost/asio/detail/push_options.hpp>
+#include <libkern/OSAtomic.h>
+#include <boost/asio/detail/pop_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class macos_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  macos_fenced_block()
+  {
+    OSMemoryBarrier();
+  }
+
+  // Destructor.
+  ~macos_fenced_block()
+  {
+    OSMemoryBarrier();
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(__MACH__) && defined(__APPLE__)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP
Added: trunk/boost/asio/detail/null_buffers_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/null_buffers_op.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,79 @@
+//
+// null_buffers_op.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_NULL_BUFFERS_OP_HPP
+#define BOOST_ASIO_DETAIL_NULL_BUFFERS_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class null_buffers_op : public reactor_op
+{
+public:
+  null_buffers_op(Handler handler)
+    : reactor_op(&null_buffers_op::do_perform, &null_buffers_op::do_complete),
+      handler_(handler)
+  {
+  }
+
+  static bool do_perform(reactor_op*)
+  {
+    return true;
+  }
+
+  static void do_complete(io_service_impl* owner, operation* base,
+      boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+  {
+    // Take ownership of the handler object.
+    null_buffers_op* o(static_cast<null_buffers_op*>(base));
+    typedef handler_alloc_traits<Handler, null_buffers_op> alloc_traits;
+    handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+    // Make the upcall if required.
+    if (owner)
+    {
+      // Make a copy of the handler so that the memory can be deallocated
+      // before the upcall is made. Even if we're not about to make an upcall,
+      // 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.
+      detail::binder2<Handler, boost::system::error_code, std::size_t>
+        handler(o->handler_, o->ec_, o->bytes_transferred_);
+      ptr.reset();
+      boost::asio::detail::fenced_block b;
+      boost_asio_handler_invoke_helpers::invoke(handler, handler);
+    }
+  }
+
+private:
+  Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_NULL_BUFFERS_OP_HPP
Modified: trunk/boost/asio/detail/null_event.hpp
==============================================================================
--- trunk/boost/asio/detail/null_event.hpp	(original)
+++ trunk/boost/asio/detail/null_event.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -49,6 +49,12 @@
   {
   }
 
+  // Signal the event and unlock the mutex.
+  template <typename Lock>
+  void signal_and_unlock(Lock&)
+  {
+  }
+
   // Reset the event.
   template <typename Lock>
   void clear(Lock&)
Added: trunk/boost/asio/detail/null_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/null_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,45 @@
+//
+// null_fenced_block.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_NULL_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_NULL_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class null_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  null_fenced_block()
+  {
+  }
+
+  // Destructor.
+  ~null_fenced_block()
+  {
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_NULL_FENCED_BLOCK_HPP
Added: trunk/boost/asio/detail/op_queue.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/op_queue.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,158 @@
+//
+// op_queue.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_OP_QUEUE_HPP
+#define BOOST_ASIO_DETAIL_OP_QUEUE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/noncopyable.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Operation>
+class op_queue;
+
+class op_queue_access
+{
+public:
+  template <typename Operation>
+  static Operation* next(Operation* o)
+  {
+    return static_cast<Operation*>(o->next_);
+  }
+
+  template <typename Operation1, typename Operation2>
+  static void next(Operation1*& o1, Operation2* o2)
+  {
+    o1->next_ = o2;
+  }
+
+  template <typename Operation>
+  static void destroy(Operation* o)
+  {
+    o->destroy();
+  }
+
+  template <typename Operation>
+  static Operation*& front(op_queue<Operation>& q)
+  {
+    return q.front_;
+  }
+
+  template <typename Operation>
+  static Operation*& back(op_queue<Operation>& q)
+  {
+    return q.back_;
+  }
+};
+
+template <typename Operation>
+class op_queue
+  : private noncopyable
+{
+public:
+  // Constructor.
+  op_queue()
+    : front_(0),
+      back_(0)
+  {
+  }
+
+  // Destructor destroys all operations.
+  ~op_queue()
+  {
+    while (Operation* op = front_)
+    {
+      pop();
+      op_queue_access::destroy(op);
+    }
+  }
+
+  // Get the operation at the front of the queue.
+  Operation* front()
+  {
+    return front_;
+  }
+
+  // Pop an operation from the front of the queue.
+  void pop()
+  {
+    if (front_)
+    {
+      Operation* tmp = front_;
+      front_ = op_queue_access::next(front_);
+      if (front_ == 0)
+        back_ = 0;
+      op_queue_access::next(tmp, static_cast<Operation*>(0));
+    }
+  }
+
+  // Push an operation on to the back of the queue.
+  void push(Operation* h)
+  {
+    op_queue_access::next(h, static_cast<Operation*>(0));
+    if (back_)
+    {
+      op_queue_access::next(back_, h);
+      back_ = h;
+    }
+    else
+    {
+      front_ = back_ = h;
+    }
+  }
+
+  // Push all operations from another queue on to the back of the queue. The
+  // source queue may contain operations of a derived type.
+  template <typename OtherOperation>
+  void push(op_queue<OtherOperation>& q)
+  {
+    if (Operation* other_front = op_queue_access::front(q))
+    {
+      if (back_)
+        op_queue_access::next(back_, other_front);
+      else
+        front_ = other_front;
+      back_ = op_queue_access::back(q);
+      op_queue_access::front(q) = 0;
+      op_queue_access::back(q) = 0;
+    }
+  }
+
+  // Whether the queue is empty.
+  bool empty() const
+  {
+    return front_ == 0;
+  }
+
+private:
+  friend class op_queue_access;
+
+  // The front of the queue.
+  Operation* front_;
+
+  // The back of the queue.
+  Operation* back_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_OP_QUEUE_HPP
Added: trunk/boost/asio/detail/operation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/operation.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,45 @@
+//
+// operation.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_OPERATION_HPP
+#define BOOST_ASIO_DETAIL_OPERATION_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_operation.hpp>
+#else
+# include <boost/asio/detail/reactor_fwd.hpp>
+# include <boost/asio/detail/task_io_service_operation.hpp>
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+typedef win_iocp_operation operation;
+#else
+typedef task_io_service_operation<reactor> operation;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_OPERATION_HPP
Modified: trunk/boost/asio/detail/posix_event.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_event.hpp	(original)
+++ trunk/boost/asio/detail/posix_event.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -72,6 +72,16 @@
     ::pthread_cond_signal(&cond_); // Ignore EINVAL.
   }
 
+  // Signal the event and unlock the mutex.
+  template <typename Lock>
+  void signal_and_unlock(Lock& lock)
+  {
+    BOOST_ASSERT(lock.locked());
+    signalled_ = true;
+    lock.unlock();
+    ::pthread_cond_signal(&cond_); // Ignore EINVAL.
+  }
+
   // Reset the event.
   template <typename Lock>
   void clear(Lock& lock)
Modified: trunk/boost/asio/detail/posix_mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_mutex.hpp	(original)
+++ trunk/boost/asio/detail/posix_mutex.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -62,35 +62,19 @@
   // Destructor.
   ~posix_mutex()
   {
-    ::pthread_mutex_destroy(&mutex_);
+    ::pthread_mutex_destroy(&mutex_); // Ignore EBUSY.
   }
 
   // Lock the mutex.
   void lock()
   {
-    int error = ::pthread_mutex_lock(&mutex_);
-    if (error != 0)
-    {
-      boost::system::system_error e(
-          boost::system::error_code(error,
-            boost::asio::error::get_system_category()),
-          "mutex");
-      boost::throw_exception(e);
-    }
+    (void)::pthread_mutex_lock(&mutex_); // Ignore EINVAL.
   }
 
   // Unlock the mutex.
   void unlock()
   {
-    int error = ::pthread_mutex_unlock(&mutex_);
-    if (error != 0)
-    {
-      boost::system::system_error e(
-          boost::system::error_code(error,
-            boost::asio::error::get_system_category()),
-          "mutex");
-      boost::throw_exception(e);
-    }
+    (void)::pthread_mutex_unlock(&mutex_); // Ignore EINVAL.
   }
 
 private:
Modified: trunk/boost/asio/detail/reactive_descriptor_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_descriptor_service.hpp	(original)
+++ trunk/boost/asio/detail/reactive_descriptor_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -21,10 +21,13 @@
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/handler_base_from_member.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/service_base.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
 #include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/null_buffers_op.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 
 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
@@ -32,10 +35,7 @@
 namespace asio {
 namespace detail {
 
-template <typename Reactor>
 class reactive_descriptor_service
-  : public boost::asio::detail::service_base<
-      reactive_descriptor_service<Reactor> >
 {
 public:
   // The native type of a descriptor.
@@ -55,22 +55,28 @@
 
   private:
     // Only this service will have access to the internal values.
-    friend class reactive_descriptor_service<Reactor>;
+    friend class reactive_descriptor_service;
 
     // The native descriptor representation.
     int descriptor_;
 
     enum
     {
-      user_set_non_blocking = 1, // The user wants a non-blocking descriptor.
-      internal_non_blocking = 2  // The descriptor has been set non-blocking.
+      // The user wants a non-blocking descriptor.
+      user_set_non_blocking = 1,
+
+      // The descriptor has been set non-blocking.
+      internal_non_blocking = 2,
+
+      // Helper "flag" used to determine whether the socket is non-blocking.
+      non_blocking = user_set_non_blocking | internal_non_blocking
     };
 
     // Flags indicating the current state of the descriptor.
     unsigned char flags_;
 
     // Per-descriptor data used by the reactor.
-    typename Reactor::per_descriptor_data reactor_data_;
+    reactor::per_descriptor_data reactor_data_;
   };
 
   // The maximum number of buffers to support in a single operation.
@@ -78,9 +84,8 @@
 
   // Constructor.
   reactive_descriptor_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        reactive_descriptor_service<Reactor> >(io_service),
-      reactor_(boost::asio::use_service<Reactor>(io_service))
+    : io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)),
+      reactor_(boost::asio::use_service<reactor>(io_service))
   {
     reactor_.init_task();
   }
@@ -236,47 +241,22 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    descriptor_ops::buf bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      descriptor_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<const void*>(buffer),
-          boost::asio::buffer_size(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
     // A request to read_some 0 bytes on a stream is a no-op.
-    if (total_buffer_size == 0)
+    if (bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
     }
 
-    // Make descriptor non-blocking if user wants non-blocking.
-    if (impl.flags_ & implementation_type::user_set_non_blocking)
-    {
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        ioctl_arg_type non_blocking = 1;
-        if (descriptor_ops::ioctl(impl.descriptor_,
-              FIONBIO, &non_blocking, ec))
-          return 0;
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
-    }
-
     // Send the data.
     for (;;)
     {
       // Try to complete the operation without blocking.
       int bytes_sent = descriptor_ops::gather_write(
-          impl.descriptor_, bufs, i, ec);
+          impl.descriptor_, bufs.buffers(), bufs.count(), ec);
 
       // Check if operation succeeded.
       if (bytes_sent >= 0)
@@ -310,48 +290,31 @@
     return 0;
   }
 
-  template <typename ConstBufferSequence, typename Handler>
-  class write_operation :
-    public handler_base_from_member<Handler>
+  template <typename ConstBufferSequence>
+  class write_op_base : public reactor_op
   {
   public:
-    write_operation(int descriptor, boost::asio::io_service& io_service,
-        const ConstBufferSequence& buffers, Handler handler)
-      : handler_base_from_member<Handler>(handler),
+    write_op_base(int descriptor,
+        const ConstBufferSequence& buffers, func_type complete_func)
+      : reactor_op(&write_op_base::do_perform, complete_func),
         descriptor_(descriptor),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      write_op_base* o(static_cast<write_op_base*>(base));
 
-      // Copy buffers into array.
-      descriptor_ops::buf bufs[max_buffers];
-      typename ConstBufferSequence::const_iterator iter = buffers_.begin();
-      typename ConstBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        descriptor_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<const void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::const_buffer,
+          ConstBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Write the data.
-        int bytes = descriptor_ops::gather_write(descriptor_, bufs, i, ec);
+        boost::system::error_code ec;
+        int bytes = descriptor_ops::gather_write(
+            o->descriptor_, bufs.buffers(), bufs.count(), ec);
 
         // Retry operation if interrupted by signal.
         if (ec == boost::asio::error::interrupted)
@@ -362,120 +325,89 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
-    }
-
   private:
     int descriptor_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     ConstBufferSequence buffers_;
   };
 
-  // Start an asynchronous write. The data being sent must be valid for the
-  // lifetime of the asynchronous operation.
   template <typename ConstBufferSequence, typename Handler>
-  void async_write_some(implementation_type& impl,
-      const ConstBufferSequence& buffers, Handler handler)
-  {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Determine total size of buffers.
-      typename ConstBufferSequence::const_iterator iter = buffers.begin();
-      typename ConstBufferSequence::const_iterator end = buffers.end();
-      size_t i = 0;
-      size_t total_buffer_size = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        total_buffer_size += boost::asio::buffer_size(buffer);
-      }
-
-      // A request to read_some 0 bytes on a stream is a no-op.
-      if (total_buffer_size == 0)
-      {
-        this->get_io_service().post(bind_handler(handler,
-              boost::system::error_code(), 0));
-        return;
-      }
-
-      // Make descriptor non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        ioctl_arg_type non_blocking = 1;
-        boost::system::error_code ec;
-        if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec))
-        {
-          this->get_io_service().post(bind_handler(handler, ec, 0));
-          return;
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
-
-      reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
-          write_operation<ConstBufferSequence, Handler>(
-            impl.descriptor_, this->get_io_service(), buffers, handler));
-    }
-  }
-
-  template <typename Handler>
-  class null_buffers_operation :
-    public handler_base_from_member<Handler>
+  class write_op : public write_op_base<ConstBufferSequence>
   {
   public:
-    null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
-      : handler_base_from_member<Handler>(handler),
-        work_(io_service)
-    {
-    }
-
-    bool perform(boost::system::error_code&,
-        std::size_t& bytes_transferred)
+    write_op(int descriptor,
+        const ConstBufferSequence& buffers, Handler handler)
+      : write_op_base<ConstBufferSequence>(
+          descriptor, buffers, &write_op::do_complete),
+        handler_(handler)
     {
-      bytes_transferred = 0;
-      return true;
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      work_.get_io_service().post(bind_handler(
-            this->handler_, ec, bytes_transferred));
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      write_op* o(static_cast<write_op*>(base));
+      typedef handler_alloc_traits<Handler, write_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    boost::asio::io_service::work work_;
+    Handler handler_;
   };
 
+  // Start an asynchronous write. The data being sent must be valid for the
+  // lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename Handler>
+  void async_write_some(implementation_type& impl,
+      const ConstBufferSequence& buffers, Handler handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef write_op<ConstBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.descriptor_, buffers, handler);
+
+    start_op(impl, reactor::write_op, ptr.get(), true,
+        buffer_sequence_adapter<boost::asio::const_buffer,
+          ConstBufferSequence>::all_empty(buffers));
+    ptr.release();
+  }
+
   // Start an asynchronous wait until data can be written without blocking.
   template <typename Handler>
   void async_write_some(implementation_type& impl,
       const null_buffers&, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    start_op(impl, reactor::write_op, ptr.get(), false, false);
+    ptr.release();
   }
 
   // Read some data from the stream. Returns the number of bytes read.
@@ -489,46 +421,22 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    descriptor_ops::buf bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      descriptor_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<void*>(buffer),
-          boost::asio::buffer_size(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
     // A request to read_some 0 bytes on a stream is a no-op.
-    if (total_buffer_size == 0)
+    if (bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
     }
 
-    // Make descriptor non-blocking if user wants non-blocking.
-    if (impl.flags_ & implementation_type::user_set_non_blocking)
-    {
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        ioctl_arg_type non_blocking = 1;
-        if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec))
-          return 0;
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
-    }
-
     // Read some data.
     for (;;)
     {
       // Try to complete the operation without blocking.
       int bytes_read = descriptor_ops::scatter_read(
-          impl.descriptor_, bufs, i, ec);
+          impl.descriptor_, bufs.buffers(), bufs.count(), ec);
 
       // Check if operation succeeded.
       if (bytes_read > 0)
@@ -569,48 +477,31 @@
     return 0;
   }
 
-  template <typename MutableBufferSequence, typename Handler>
-  class read_operation :
-    public handler_base_from_member<Handler>
+  template <typename MutableBufferSequence>
+  class read_op_base : public reactor_op
   {
   public:
-    read_operation(int descriptor, boost::asio::io_service& io_service,
-        const MutableBufferSequence& buffers, Handler handler)
-      : handler_base_from_member<Handler>(handler),
+    read_op_base(int descriptor,
+        const MutableBufferSequence& buffers, func_type complete_func)
+      : reactor_op(&read_op_base::do_perform, complete_func),
         descriptor_(descriptor),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      read_op_base* o(static_cast<read_op_base*>(base));
 
-      // Copy buffers into array.
-      descriptor_ops::buf bufs[max_buffers];
-      typename MutableBufferSequence::const_iterator iter = buffers_.begin();
-      typename MutableBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        descriptor_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::mutable_buffer,
+          MutableBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Read some data.
-        int bytes = descriptor_ops::scatter_read(descriptor_, bufs, i, ec);
+        boost::system::error_code ec;
+        int bytes = descriptor_ops::scatter_read(
+            o->descriptor_, bufs.buffers(), bufs.count(), ec);
         if (bytes == 0)
           ec = boost::asio::error::eof;
 
@@ -623,22 +514,56 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
+  private:
+    int descriptor_;
+    MutableBufferSequence buffers_;
+  };
+
+  template <typename MutableBufferSequence, typename Handler>
+  class read_op : public read_op_base<MutableBufferSequence>
+  {
+  public:
+    read_op(int descriptor,
+        const MutableBufferSequence& buffers, Handler handler)
+      : read_op_base<MutableBufferSequence>(
+          descriptor, buffers, &read_op::do_complete),
+        handler_(handler)
     {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      read_op* o(static_cast<read_op*>(base));
+      typedef handler_alloc_traits<Handler, read_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    int descriptor_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
-    MutableBufferSequence buffers_;
+    Handler handler_;
   };
 
   // Start an asynchronous read. The buffer for the data being read must be
@@ -647,72 +572,79 @@
   void async_read_some(implementation_type& impl,
       const MutableBufferSequence& buffers, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Determine total size of buffers.
-      typename MutableBufferSequence::const_iterator iter = buffers.begin();
-      typename MutableBufferSequence::const_iterator end = buffers.end();
-      size_t i = 0;
-      size_t total_buffer_size = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        total_buffer_size += boost::asio::buffer_size(buffer);
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef read_op<MutableBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        impl.descriptor_, buffers, handler);
+
+    start_op(impl, reactor::read_op, ptr.get(), true,
+        buffer_sequence_adapter<boost::asio::mutable_buffer,
+          MutableBufferSequence>::all_empty(buffers));
+    ptr.release();
+  }
 
-      // A request to read_some 0 bytes on a stream is a no-op.
-      if (total_buffer_size == 0)
-      {
-        this->get_io_service().post(bind_handler(handler,
-              boost::system::error_code(), 0));
-        return;
-      }
+  // Wait until data can be read without blocking.
+  template <typename Handler>
+  void async_read_some(implementation_type& impl,
+      const null_buffers&, Handler handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      // Make descriptor non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
+    start_op(impl, reactor::read_op, ptr.get(), false, false);
+    ptr.release();
+  }
+
+private:
+  // Start the asynchronous operation.
+  void start_op(implementation_type& impl, int op_type,
+      reactor_op* op, bool non_blocking, bool noop)
+  {
+    if (!noop)
+    {
+      if (is_open(impl))
       {
-        ioctl_arg_type non_blocking = 1;
-        boost::system::error_code ec;
-        if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec))
+        if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_))
         {
-          this->get_io_service().post(bind_handler(handler, ec, 0));
+          reactor_.start_op(op_type, impl.descriptor_,
+              impl.reactor_data_, op, non_blocking);
           return;
         }
-        impl.flags_ |= implementation_type::internal_non_blocking;
       }
-
-      reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
-          read_operation<MutableBufferSequence, Handler>(
-            impl.descriptor_, this->get_io_service(), buffers, handler));
+      else
+        op->ec_ = boost::asio::error::bad_descriptor;
     }
+
+    io_service_impl_.post_immediate_completion(op);
   }
 
-  // Wait until data can be read without blocking.
-  template <typename Handler>
-  void async_read_some(implementation_type& impl,
-      const null_buffers&, Handler handler)
+  // Determine whether the descriptor has been set non-blocking.
+  bool is_non_blocking(implementation_type& impl) const
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    return (impl.flags_ & implementation_type::non_blocking);
   }
 
-private:
+  // Set the internal non-blocking flag.
+  bool set_non_blocking(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    ioctl_arg_type non_blocking = 1;
+    if (descriptor_ops::ioctl(impl.descriptor_, FIONBIO, &non_blocking, ec))
+      return false;
+    impl.flags_ |= implementation_type::internal_non_blocking;
+    return true;
+  }
+
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_impl_;
+
   // The selector that performs event demultiplexing for the service.
-  Reactor& reactor_;
+  reactor& reactor_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/reactive_serial_port_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_serial_port_service.hpp	(original)
+++ trunk/boost/asio/detail/reactive_serial_port_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -38,31 +38,24 @@
 namespace detail {
 
 // Extend reactive_descriptor_service to provide serial port support.
-template <typename Reactor>
 class reactive_serial_port_service
-  : public boost::asio::detail::service_base<
-      reactive_serial_port_service<Reactor> >
 {
 public:
-  // The native type of a stream handle.
-  typedef typename reactive_descriptor_service<Reactor>::native_type
-    native_type;
-
-  // The implementation type of the stream handle.
-  typedef typename reactive_descriptor_service<Reactor>::implementation_type
-    implementation_type;
+  // The native type of a serial port.
+  typedef reactive_descriptor_service::native_type native_type;
+
+  // The implementation type of the serial port.
+  typedef reactive_descriptor_service::implementation_type implementation_type;
 
   reactive_serial_port_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        reactive_serial_port_service>(io_service),
-      descriptor_service_(boost::asio::use_service<
-          reactive_descriptor_service<Reactor> >(io_service))
+    : descriptor_service_(io_service)
   {
   }
 
   // Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    descriptor_service_.shutdown_service();
   }
 
   // Construct a new handle implementation.
@@ -254,8 +247,8 @@
   }
 
 private:
-  // The handle service used for initiating asynchronous operations.
-  reactive_descriptor_service<Reactor>& descriptor_service_;
+  // The implementation used for initiating asynchronous operations.
+  reactive_descriptor_service descriptor_service_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/reactive_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/reactive_socket_service.hpp	(original)
+++ trunk/boost/asio/detail/reactive_socket_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -17,18 +17,17 @@
 
 #include <boost/asio/detail/push_options.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/socket_base.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/handler_base_from_member.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/service_base.hpp>
+#include <boost/asio/detail/null_buffers_op.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/socket_holder.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
@@ -37,10 +36,8 @@
 namespace asio {
 namespace detail {
 
-template <typename Protocol, typename Reactor>
+template <typename Protocol>
 class reactive_socket_service
-  : public boost::asio::detail::service_base<
-      reactive_socket_service<Protocol, Reactor> >
 {
 public:
   // The protocol type.
@@ -67,7 +64,7 @@
 
   private:
     // Only this service will have access to the internal values.
-    friend class reactive_socket_service<Protocol, Reactor>;
+    friend class reactive_socket_service<Protocol>;
 
     // The native socket representation.
     socket_type socket_;
@@ -87,7 +84,7 @@
       // User wants connection_aborted errors, which are disabled by default.
       enable_connection_aborted = 4,
 
-      // The user set the linger option. Needs to be checked when closing. 
+      // The user set the linger option. Needs to be checked when closing.
       user_set_linger = 8
     };
 
@@ -98,17 +95,13 @@
     protocol_type protocol_;
 
     // Per-descriptor data used by the reactor.
-    typename Reactor::per_descriptor_data reactor_data_;
+    reactor::per_descriptor_data reactor_data_;
   };
 
-  // The maximum number of buffers to support in a single operation.
-  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
-
   // Constructor.
   reactive_socket_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        reactive_socket_service<Protocol, Reactor> >(io_service),
-      reactor_(boost::asio::use_service<Reactor>(io_service))
+    : io_service_impl_(use_service<io_service_impl>(io_service)),
+      reactor_(use_service<reactor>(io_service))
   {
     reactor_.init_task();
   }
@@ -553,23 +546,11 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    socket_ops::buf bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      socket_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<const void*>(buffer),
-          boost::asio::buffer_size(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
     // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
+    if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
@@ -579,7 +560,8 @@
     for (;;)
     {
       // Try to complete the operation without blocking.
-      int bytes_sent = socket_ops::send(impl.socket_, bufs, i, flags, ec);
+      int bytes_sent = socket_ops::send(impl.socket_,
+          bufs.buffers(), bufs.count(), flags, ec);
 
       // Check if operation succeeded.
       if (bytes_sent >= 0)
@@ -613,50 +595,32 @@
     return 0;
   }
 
-  template <typename ConstBufferSequence, typename Handler>
-  class send_operation :
-    public handler_base_from_member<Handler>
+  template <typename ConstBufferSequence>
+  class send_op_base : public reactor_op
   {
   public:
-    send_operation(socket_type socket, boost::asio::io_service& io_service,
-        const ConstBufferSequence& buffers, socket_base::message_flags flags,
-        Handler handler)
-      : handler_base_from_member<Handler>(handler),
+    send_op_base(socket_type socket, const ConstBufferSequence& buffers,
+        socket_base::message_flags flags, func_type complete_func)
+      : reactor_op(&send_op_base::do_perform, complete_func),
         socket_(socket),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers),
         flags_(flags)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      send_op_base* o(static_cast<send_op_base*>(base));
 
-      // Copy buffers into array.
-      socket_ops::buf bufs[max_buffers];
-      typename ConstBufferSequence::const_iterator iter = buffers_.begin();
-      typename ConstBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        socket_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<const void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::const_buffer,
+          ConstBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Send the data.
-        int bytes = socket_ops::send(socket_, bufs, i, flags_, ec);
+        boost::system::error_code ec;
+        int bytes = socket_ops::send(o->socket_,
+            bufs.buffers(), bufs.count(), o->flags_, ec);
 
         // Retry operation if interrupted by signal.
         if (ec == boost::asio::error::interrupted)
@@ -667,127 +631,92 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
-    }
-
   private:
     socket_type socket_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     ConstBufferSequence buffers_;
     socket_base::message_flags flags_;
   };
 
-  // Start an asynchronous send. The data being sent must be valid for the
-  // lifetime of the asynchronous operation.
   template <typename ConstBufferSequence, typename Handler>
-  void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
-      socket_base::message_flags flags, Handler handler)
-  {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      if (impl.protocol_.type() == SOCK_STREAM)
-      {
-        // Determine total size of buffers.
-        typename ConstBufferSequence::const_iterator iter = buffers.begin();
-        typename ConstBufferSequence::const_iterator end = buffers.end();
-        size_t i = 0;
-        size_t total_buffer_size = 0;
-        for (; iter != end && i < max_buffers; ++iter, ++i)
-        {
-          boost::asio::const_buffer buffer(*iter);
-          total_buffer_size += boost::asio::buffer_size(buffer);
-        }
-
-        // A request to receive 0 bytes on a stream socket is a no-op.
-        if (total_buffer_size == 0)
-        {
-          this->get_io_service().post(bind_handler(handler,
-                boost::system::error_code(), 0));
-          return;
-        }
-      }
-
-      // Make socket non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        if (!(impl.flags_ & implementation_type::non_blocking))
-        {
-          ioctl_arg_type non_blocking = 1;
-          boost::system::error_code ec;
-          if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
-          {
-            this->get_io_service().post(bind_handler(handler, ec, 0));
-            return;
-          }
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
-
-      reactor_.start_write_op(impl.socket_, impl.reactor_data_,
-          send_operation<ConstBufferSequence, Handler>(
-            impl.socket_, this->get_io_service(), buffers, flags, handler));
-    }
-  }
-
-  template <typename Handler>
-  class null_buffers_operation :
-    public handler_base_from_member<Handler>
+  class send_op : public send_op_base<ConstBufferSequence>
   {
   public:
-    null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
-      : handler_base_from_member<Handler>(handler),
-        work_(io_service)
-    {
-    }
-
-    bool perform(boost::system::error_code&,
-        std::size_t& bytes_transferred)
+    send_op(socket_type socket, const ConstBufferSequence& buffers,
+        socket_base::message_flags flags, Handler handler)
+      : send_op_base<ConstBufferSequence>(socket,
+          buffers, flags, &send_op::do_complete),
+        handler_(handler)
     {
-      bytes_transferred = 0;
-      return true;
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      work_.get_io_service().post(bind_handler(
-            this->handler_, ec, bytes_transferred));
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      send_op* o(static_cast<send_op*>(base));
+      typedef handler_alloc_traits<Handler, send_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    boost::asio::io_service::work work_;
+    Handler handler_;
   };
 
+  // Start an asynchronous send. The data being sent must be valid for the
+  // lifetime of the asynchronous operation.
+  template <typename ConstBufferSequence, typename Handler>
+  void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
+      socket_base::message_flags flags, Handler handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef send_op<ConstBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        impl.socket_, buffers, flags, handler);
+
+    start_op(impl, reactor::write_op, ptr.get(), true,
+        (impl.protocol_.type() == SOCK_STREAM
+          && buffer_sequence_adapter<boost::asio::const_buffer,
+            ConstBufferSequence>::all_empty(buffers)));
+    ptr.release();
+  }
+
   // Start an asynchronous wait until data can be sent without blocking.
   template <typename Handler>
   void async_send(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      reactor_.start_write_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    start_op(impl, reactor::write_op, ptr.get(), false, false);
+    ptr.release();
   }
 
   // Send a datagram to the specified endpoint. Returns the number of bytes
@@ -803,25 +732,15 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    socket_ops::buf bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      socket_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<const void*>(buffer),
-          boost::asio::buffer_size(buffer));
-    }
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
     // Send the data.
     for (;;)
     {
       // Try to complete the operation without blocking.
-      int bytes_sent = socket_ops::sendto(impl.socket_, bufs, i, flags,
-          destination.data(), destination.size(), ec);
+      int bytes_sent = socket_ops::sendto(impl.socket_, bufs.buffers(),
+          bufs.count(), flags, destination.data(), destination.size(), ec);
 
       // Check if operation succeeded.
       if (bytes_sent >= 0)
@@ -856,52 +775,34 @@
     return 0;
   }
 
-  template <typename ConstBufferSequence, typename Handler>
-  class send_to_operation :
-    public handler_base_from_member<Handler>
+  template <typename ConstBufferSequence>
+  class send_to_op_base : public reactor_op
   {
   public:
-    send_to_operation(socket_type socket, boost::asio::io_service& io_service,
-        const ConstBufferSequence& buffers, const endpoint_type& endpoint,
-        socket_base::message_flags flags, Handler handler)
-      : handler_base_from_member<Handler>(handler),
+    send_to_op_base(socket_type socket, const ConstBufferSequence& buffers,
+        const endpoint_type& endpoint, socket_base::message_flags flags,
+        func_type complete_func)
+      : reactor_op(&send_to_op_base::do_perform, complete_func),
         socket_(socket),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers),
         destination_(endpoint),
         flags_(flags)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      send_to_op_base* o(static_cast<send_to_op_base*>(base));
 
-      // Copy buffers into array.
-      socket_ops::buf bufs[max_buffers];
-      typename ConstBufferSequence::const_iterator iter = buffers_.begin();
-      typename ConstBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        socket_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<const void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::const_buffer,
+          ConstBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Send the data.
-        int bytes = socket_ops::sendto(socket_, bufs, i, flags_,
-            destination_.data(), destination_.size(), ec);
+        boost::system::error_code ec;
+        int bytes = socket_ops::sendto(o->socket_, bufs.buffers(), bufs.count(),
+            o->flags_, o->destination_.data(), o->destination_.size(), ec);
 
         // Retry operation if interrupted by signal.
         if (ec == boost::asio::error::interrupted)
@@ -912,26 +813,61 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
-    }
-
   private:
     socket_type socket_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     ConstBufferSequence buffers_;
     endpoint_type destination_;
     socket_base::message_flags flags_;
   };
 
+  template <typename ConstBufferSequence, typename Handler>
+  class send_to_op : public send_to_op_base<ConstBufferSequence>
+  {
+  public:
+    send_to_op(socket_type socket, const ConstBufferSequence& buffers,
+        const endpoint_type& endpoint, socket_base::message_flags flags,
+        Handler handler)
+      : send_to_op_base<ConstBufferSequence>(socket,
+          buffers, endpoint, flags, &send_to_op::do_complete),
+        handler_(handler)
+    {
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      send_to_op* o(static_cast<send_to_op*>(base));
+      typedef handler_alloc_traits<Handler, send_to_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
+    }
+
+  private:
+    Handler handler_;
+  };
+
   // Start an asynchronous send. The data being sent must be valid for the
   // lifetime of the asynchronous operation.
   template <typename ConstBufferSequence, typename Handler>
@@ -940,34 +876,15 @@
       const endpoint_type& destination, socket_base::message_flags flags,
       Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Make socket non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        if (!(impl.flags_ & implementation_type::non_blocking))
-        {
-          ioctl_arg_type non_blocking = 1;
-          boost::system::error_code ec;
-          if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
-          {
-            this->get_io_service().post(bind_handler(handler, ec, 0));
-            return;
-          }
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef send_to_op<ConstBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_,
+        buffers, destination, flags, handler);
 
-      reactor_.start_write_op(impl.socket_, impl.reactor_data_,
-          send_to_operation<ConstBufferSequence, Handler>(
-            impl.socket_, this->get_io_service(), buffers,
-            destination, flags, handler));
-    }
+    start_op(impl, reactor::write_op, ptr.get(), true, false);
+    ptr.release();
   }
 
   // Start an asynchronous wait until data can be sent without blocking.
@@ -975,17 +892,14 @@
   void async_send_to(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, const endpoint_type&, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      reactor_.start_write_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    start_op(impl, reactor::write_op, ptr.get(), false, false);
+    ptr.release();
   }
 
   // Receive some data from the peer. Returns the number of bytes received.
@@ -1000,23 +914,11 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    socket_ops::buf bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      socket_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<void*>(buffer),
-          boost::asio::buffer_size(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
     // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
+    if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
@@ -1026,7 +928,8 @@
     for (;;)
     {
       // Try to complete the operation without blocking.
-      int bytes_recvd = socket_ops::recv(impl.socket_, bufs, i, flags, ec);
+      int bytes_recvd = socket_ops::recv(impl.socket_,
+          bufs.buffers(), bufs.count(), flags, ec);
 
       // Check if operation succeeded.
       if (bytes_recvd > 0)
@@ -1067,53 +970,35 @@
     return 0;
   }
 
-  template <typename MutableBufferSequence, typename Handler>
-  class receive_operation :
-    public handler_base_from_member<Handler>
+  template <typename MutableBufferSequence>
+  class receive_op_base : public reactor_op
   {
   public:
-    receive_operation(socket_type socket, int protocol_type,
-        boost::asio::io_service& io_service,
+    receive_op_base(socket_type socket, int protocol_type,
         const MutableBufferSequence& buffers,
-        socket_base::message_flags flags, Handler handler)
-      : handler_base_from_member<Handler>(handler),
+        socket_base::message_flags flags, func_type complete_func)
+      : reactor_op(&receive_op_base::do_perform, complete_func),
         socket_(socket),
         protocol_type_(protocol_type),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers),
         flags_(flags)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      receive_op_base* o(static_cast<receive_op_base*>(base));
 
-      // Copy buffers into array.
-      socket_ops::buf bufs[max_buffers];
-      typename MutableBufferSequence::const_iterator iter = buffers_.begin();
-      typename MutableBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        socket_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::mutable_buffer,
+          MutableBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Receive some data.
-        int bytes = socket_ops::recv(socket_, bufs, i, flags_, ec);
-        if (bytes == 0 && protocol_type_ == SOCK_STREAM)
+        boost::system::error_code ec;
+        int bytes = socket_ops::recv(o->socket_,
+            bufs.buffers(), bufs.count(), o->flags_, ec);
+        if (bytes == 0 && o->protocol_type_ == SOCK_STREAM)
           ec = boost::asio::error::eof;
 
         // Retry operation if interrupted by signal.
@@ -1125,93 +1010,84 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
-    }
-
   private:
     socket_type socket_;
     int protocol_type_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     MutableBufferSequence buffers_;
     socket_base::message_flags flags_;
   };
 
-  // Start an asynchronous receive. The buffer for the data being received
-  // must be valid for the lifetime of the asynchronous operation.
   template <typename MutableBufferSequence, typename Handler>
-  void async_receive(implementation_type& impl,
-      const MutableBufferSequence& buffers,
-      socket_base::message_flags flags, Handler handler)
+  class receive_op : public receive_op_base<MutableBufferSequence>
   {
-    if (!is_open(impl))
+  public:
+    receive_op(socket_type socket, int protocol_type,
+        const MutableBufferSequence& buffers,
+        socket_base::message_flags flags, Handler handler)
+      : receive_op_base<MutableBufferSequence>(socket,
+          protocol_type, buffers, flags, &receive_op::do_complete),
+        handler_(handler)
     {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
     }
-    else
-    {
-      if (impl.protocol_.type() == SOCK_STREAM)
-      {
-        // Determine total size of buffers.
-        typename MutableBufferSequence::const_iterator iter = buffers.begin();
-        typename MutableBufferSequence::const_iterator end = buffers.end();
-        size_t i = 0;
-        size_t total_buffer_size = 0;
-        for (; iter != end && i < max_buffers; ++iter, ++i)
-        {
-          boost::asio::mutable_buffer buffer(*iter);
-          total_buffer_size += boost::asio::buffer_size(buffer);
-        }
 
-        // A request to receive 0 bytes on a stream socket is a no-op.
-        if (total_buffer_size == 0)
-        {
-          this->get_io_service().post(bind_handler(handler,
-                boost::system::error_code(), 0));
-          return;
-        }
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      receive_op* o(static_cast<receive_op*>(base));
+      typedef handler_alloc_traits<Handler, receive_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
       }
+    }
 
-      // Make socket non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        if (!(impl.flags_ & implementation_type::non_blocking))
-        {
-          ioctl_arg_type non_blocking = 1;
-          boost::system::error_code ec;
-          if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
-          {
-            this->get_io_service().post(bind_handler(handler, ec, 0));
-            return;
-          }
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
+  private:
+    Handler handler_;
+  };
 
-      if (flags & socket_base::message_out_of_band)
-      {
-        reactor_.start_except_op(impl.socket_, impl.reactor_data_,
-            receive_operation<MutableBufferSequence, Handler>(
-              impl.socket_, impl.protocol_.type(),
-              this->get_io_service(), buffers, flags, handler));
-      }
-      else
-      {
-        reactor_.start_read_op(impl.socket_, impl.reactor_data_,
-            receive_operation<MutableBufferSequence, Handler>(
-              impl.socket_, impl.protocol_.type(),
-              this->get_io_service(), buffers, flags, handler));
-      }
-    }
+  // Start an asynchronous receive. The buffer for the data being received
+  // must be valid for the lifetime of the asynchronous operation.
+  template <typename MutableBufferSequence, typename Handler>
+  void async_receive(implementation_type& impl,
+      const MutableBufferSequence& buffers,
+      socket_base::message_flags flags, Handler handler)
+  {
+    // Allocate and construct an operation to wrap the handler.
+    typedef receive_op<MutableBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    int protocol_type = impl.protocol_.type();
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_,
+        protocol_type, buffers, flags, handler);
+
+    start_op(impl,
+        (flags & socket_base::message_out_of_band)
+          ? reactor::except_op : reactor::read_op,
+        ptr.get(), true,
+        (impl.protocol_.type() == SOCK_STREAM
+          && buffer_sequence_adapter<boost::asio::mutable_buffer,
+            MutableBufferSequence>::all_empty(buffers)));
+    ptr.release();
   }
 
   // Wait until data can be received without blocking.
@@ -1219,22 +1095,17 @@
   void async_receive(implementation_type& impl, const null_buffers&,
       socket_base::message_flags flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else if (flags & socket_base::message_out_of_band)
-    {
-      reactor_.start_except_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler));
-    }
-    else
-    {
-      reactor_.start_read_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    start_op(impl,
+        (flags & socket_base::message_out_of_band)
+          ? reactor::except_op : reactor::read_op,
+        ptr.get(), false, false);
+    ptr.release();
   }
 
   // Receive a datagram with the endpoint of the sender. Returns the number of
@@ -1251,26 +1122,16 @@
       return 0;
     }
 
-    // Copy buffers into array.
-    socket_ops::buf bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    size_t i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      socket_ops::init_buf(bufs[i],
-          boost::asio::buffer_cast<void*>(buffer),
-          boost::asio::buffer_size(buffer));
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
     // Receive some data.
     for (;;)
     {
       // Try to complete the operation without blocking.
       std::size_t addr_len = sender_endpoint.capacity();
-      int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags,
-          sender_endpoint.data(), &addr_len, ec);
+      int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs.buffers(),
+          bufs.count(), flags, sender_endpoint.data(), &addr_len, ec);
 
       // Check if operation succeeded.
       if (bytes_recvd > 0)
@@ -1318,56 +1179,37 @@
     return 0;
   }
 
-  template <typename MutableBufferSequence, typename Handler>
-  class receive_from_operation :
-    public handler_base_from_member<Handler>
+  template <typename MutableBufferSequence>
+  class receive_from_op_base : public reactor_op
   {
   public:
-    receive_from_operation(socket_type socket, int protocol_type,
-        boost::asio::io_service& io_service,
+    receive_from_op_base(socket_type socket, int protocol_type,
         const MutableBufferSequence& buffers, endpoint_type& endpoint,
-        socket_base::message_flags flags, Handler handler)
-      : handler_base_from_member<Handler>(handler),
+        socket_base::message_flags flags, func_type complete_func)
+      : reactor_op(&receive_from_op_base::do_perform, complete_func),
         socket_(socket),
         protocol_type_(protocol_type),
-        io_service_(io_service),
-        work_(io_service),
         buffers_(buffers),
         sender_endpoint_(endpoint),
         flags_(flags)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-      {
-        bytes_transferred = 0;
-        return true;
-      }
+      receive_from_op_base* o(static_cast<receive_from_op_base*>(base));
 
-      // Copy buffers into array.
-      socket_ops::buf bufs[max_buffers];
-      typename MutableBufferSequence::const_iterator iter = buffers_.begin();
-      typename MutableBufferSequence::const_iterator end = buffers_.end();
-      size_t i = 0;
-      for (; iter != end && i < max_buffers; ++iter, ++i)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        socket_ops::init_buf(bufs[i],
-            boost::asio::buffer_cast<void*>(buffer),
-            boost::asio::buffer_size(buffer));
-      }
+      buffer_sequence_adapter<boost::asio::mutable_buffer,
+          MutableBufferSequence> bufs(o->buffers_);
 
       for (;;)
       {
         // Receive some data.
-        std::size_t addr_len = sender_endpoint_.capacity();
-        int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
-            sender_endpoint_.data(), &addr_len, ec);
-        if (bytes == 0 && protocol_type_ == SOCK_STREAM)
+        boost::system::error_code ec;
+        std::size_t addr_len = o->sender_endpoint_.capacity();
+        int bytes = socket_ops::recvfrom(o->socket_, bufs.buffers(),
+            bufs.count(), o->flags_, o->sender_endpoint_.data(), &addr_len, ec);
+        if (bytes == 0 && o->protocol_type_ == SOCK_STREAM)
           ec = boost::asio::error::eof;
 
         // Retry operation if interrupted by signal.
@@ -1379,28 +1221,63 @@
             || ec == boost::asio::error::try_again)
           return false;
 
-        sender_endpoint_.resize(addr_len);
-        bytes_transferred = (bytes < 0 ? 0 : bytes);
+        o->sender_endpoint_.resize(addr_len);
+        o->ec_ = ec;
+        o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      io_service_.post(bind_handler(this->handler_, ec, bytes_transferred));
-    }
-
   private:
     socket_type socket_;
     int protocol_type_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     MutableBufferSequence buffers_;
     endpoint_type& sender_endpoint_;
     socket_base::message_flags flags_;
   };
 
+  template <typename MutableBufferSequence, typename Handler>
+  class receive_from_op : public receive_from_op_base<MutableBufferSequence>
+  {
+  public:
+    receive_from_op(socket_type socket, int protocol_type,
+        const MutableBufferSequence& buffers, endpoint_type& endpoint,
+        socket_base::message_flags flags, Handler handler)
+      : receive_from_op_base<MutableBufferSequence>(socket, protocol_type,
+          buffers, endpoint, flags, &receive_from_op::do_complete),
+        handler_(handler)
+    {
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      receive_from_op* o(static_cast<receive_from_op*>(base));
+      typedef handler_alloc_traits<Handler, receive_from_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, o->ec_, o->bytes_transferred_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
+    }
+
+  private:
+    Handler handler_;
+  };
+
   // Start an asynchronous receive. The buffer for the data being received and
   // the sender_endpoint object must both be valid for the lifetime of the
   // asynchronous operation.
@@ -1409,34 +1286,19 @@
       const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
       socket_base::message_flags flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Make socket non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        if (!(impl.flags_ & implementation_type::non_blocking))
-        {
-          ioctl_arg_type non_blocking = 1;
-          boost::system::error_code ec;
-          if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
-          {
-            this->get_io_service().post(bind_handler(handler, ec, 0));
-            return;
-          }
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
-
-      reactor_.start_read_op(impl.socket_, impl.reactor_data_,
-          receive_from_operation<MutableBufferSequence, Handler>(
-            impl.socket_, impl.protocol_.type(), this->get_io_service(),
-            buffers, sender_endpoint, flags, handler));
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef receive_from_op<MutableBufferSequence, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    int protocol_type = impl.protocol_.type();
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_,
+        protocol_type, buffers, sender_endpoint, flags, handler);
+
+    start_op(impl,
+        (flags & socket_base::message_out_of_band)
+          ? reactor::except_op : reactor::read_op,
+        ptr.get(), true, false);
+    ptr.release();
   }
 
   // Wait until data can be received without blocking.
@@ -1445,28 +1307,20 @@
       const null_buffers&, endpoint_type& sender_endpoint,
       socket_base::message_flags flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Reset endpoint since it can be given no sensible value at this time.
-      sender_endpoint = endpoint_type();
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      if (flags & socket_base::message_out_of_band)
-      {
-        reactor_.start_except_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler));
-      }
-      else
-      {
-        reactor_.start_read_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler),
-            false);
-      }
-    }
+    // Reset endpoint since it can be given no sensible value at this time.
+    sender_endpoint = endpoint_type();
+
+    start_op(impl,
+        (flags & socket_base::message_out_of_band)
+          ? reactor::except_op : reactor::read_op,
+        ptr.get(), false, false);
+    ptr.release();
   }
 
   // Accept a new connection.
@@ -1546,19 +1400,15 @@
     }
   }
 
-  template <typename Socket, typename Handler>
-  class accept_operation :
-    public handler_base_from_member<Handler>
+  template <typename Socket>
+  class accept_op_base : public reactor_op
   {
   public:
-    accept_operation(socket_type socket, boost::asio::io_service& io_service,
-        Socket& peer, const protocol_type& protocol,
-        endpoint_type* peer_endpoint, bool enable_connection_aborted,
-        Handler handler)
-      : handler_base_from_member<Handler>(handler),
+    accept_op_base(socket_type socket, Socket& peer,
+        const protocol_type& protocol, endpoint_type* peer_endpoint,
+        bool enable_connection_aborted, func_type complete_func)
+      : reactor_op(&accept_op_base::do_perform, complete_func),
         socket_(socket),
-        io_service_(io_service),
-        work_(io_service),
         peer_(peer),
         protocol_(protocol),
         peer_endpoint_(peer_endpoint),
@@ -1566,27 +1416,25 @@
     {
     }
 
-    bool perform(boost::system::error_code& ec, std::size_t&)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-        return true;
+      accept_op_base* o(static_cast<accept_op_base*>(base));
 
       for (;;)
       {
         // Accept the waiting connection.
+        boost::system::error_code ec;
         socket_holder new_socket;
         std::size_t addr_len = 0;
-        if (peer_endpoint_)
+        std::size_t* addr_len_p = 0;
+        socket_addr_type* addr = 0;
+        if (o->peer_endpoint_)
         {
-          addr_len = peer_endpoint_->capacity();
-          new_socket.reset(socket_ops::accept(socket_,
-                peer_endpoint_->data(), &addr_len, ec));
-        }
-        else
-        {
-          new_socket.reset(socket_ops::accept(socket_, 0, 0, ec));
+          addr_len = o->peer_endpoint_->capacity();
+          addr_len_p = &addr_len;
+          addr = o->peer_endpoint_->data();
         }
+        new_socket.reset(socket_ops::accept(o->socket_, addr, addr_len_p, ec));
 
         // Retry operation if interrupted by signal.
         if (ec == boost::asio::error::interrupted)
@@ -1597,83 +1445,95 @@
             || ec == boost::asio::error::try_again)
           return false;
         if (ec == boost::asio::error::connection_aborted
-            && !enable_connection_aborted_)
+            && !o->enable_connection_aborted_)
           return false;
 #if defined(EPROTO)
-        if (ec.value() == EPROTO && !enable_connection_aborted_)
+        if (ec.value() == EPROTO && !o->enable_connection_aborted_)
           return false;
 #endif // defined(EPROTO)
 
         // Transfer ownership of the new socket to the peer object.
         if (!ec)
         {
-          if (peer_endpoint_)
-            peer_endpoint_->resize(addr_len);
-          peer_.assign(protocol_, new_socket.get(), ec);
+          if (o->peer_endpoint_)
+            o->peer_endpoint_->resize(addr_len);
+          o->peer_.assign(o->protocol_, new_socket.get(), ec);
           if (!ec)
             new_socket.release();
         }
 
+        o->ec_ = ec;
         return true;
       }
     }
 
-    void complete(const boost::system::error_code& ec, std::size_t)
-    {
-      io_service_.post(bind_handler(this->handler_, ec));
-    }
-
   private:
     socket_type socket_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     Socket& peer_;
     protocol_type protocol_;
     endpoint_type* peer_endpoint_;
     bool enable_connection_aborted_;
   };
 
+  template <typename Socket, typename Handler>
+  class accept_op : public accept_op_base<Socket>
+  {
+  public:
+    accept_op(socket_type socket, Socket& peer, const protocol_type& protocol,
+        endpoint_type* peer_endpoint, bool enable_connection_aborted,
+        Handler handler)
+      : accept_op_base<Socket>(socket, peer, protocol, peer_endpoint,
+          enable_connection_aborted, &accept_op::do_complete),
+        handler_(handler)
+    {
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      accept_op* o(static_cast<accept_op*>(base));
+      typedef handler_alloc_traits<Handler, accept_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder1<Handler, boost::system::error_code>
+          handler(o->handler_, o->ec_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
+    }
+
+  private:
+    Handler handler_;
+  };
+
   // Start an asynchronous accept. The peer and peer_endpoint objects
   // must be valid until the accept's handler is invoked.
   template <typename Socket, typename Handler>
   void async_accept(implementation_type& impl, Socket& peer,
       endpoint_type* peer_endpoint, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor));
-    }
-    else if (peer.is_open())
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::already_open));
-    }
-    else
-    {
-      // Make socket non-blocking.
-      if (!(impl.flags_ & implementation_type::internal_non_blocking))
-      {
-        if (!(impl.flags_ & implementation_type::non_blocking))
-        {
-          ioctl_arg_type non_blocking = 1;
-          boost::system::error_code ec;
-          if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
-          {
-            this->get_io_service().post(bind_handler(handler, ec));
-            return;
-          }
-        }
-        impl.flags_ |= implementation_type::internal_non_blocking;
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef accept_op<Socket, Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    bool enable_connection_aborted =
+      (impl.flags_ & implementation_type::enable_connection_aborted) != 0;
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, peer,
+        impl.protocol_, peer_endpoint, enable_connection_aborted, handler);
 
-      reactor_.start_read_op(impl.socket_, impl.reactor_data_,
-          accept_operation<Socket, Handler>(
-            impl.socket_, this->get_io_service(),
-            peer, impl.protocol_, peer_endpoint,
-            (impl.flags_ & implementation_type::enable_connection_aborted) != 0,
-            handler));
-    }
+    start_accept_op(impl, ptr.get(), peer.is_open());
+    ptr.release();
   }
 
   // Connect the socket to the specified endpoint.
@@ -1713,53 +1573,77 @@
     return ec;
   }
 
-  template <typename Handler>
-  class connect_operation :
-    public handler_base_from_member<Handler>
+  class connect_op_base : public reactor_op
   {
   public:
-    connect_operation(socket_type socket,
-        boost::asio::io_service& io_service, Handler handler)
-      : handler_base_from_member<Handler>(handler),
-        socket_(socket),
-        io_service_(io_service),
-        work_(io_service)
+    connect_op_base(socket_type socket, func_type complete_func)
+      : reactor_op(&connect_op_base::do_perform, complete_func),
+        socket_(socket)
     {
     }
 
-    bool perform(boost::system::error_code& ec, std::size_t&)
+    static bool do_perform(reactor_op* base)
     {
-      // Check whether the operation was successful.
-      if (ec)
-        return true;
+      connect_op_base* o(static_cast<connect_op_base*>(base));
 
       // Get the error code from the connect operation.
       int connect_error = 0;
       size_t connect_error_len = sizeof(connect_error);
-      if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR,
-            &connect_error, &connect_error_len, ec) == socket_error_retval)
+      if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR,
+            &connect_error, &connect_error_len, o->ec_) == socket_error_retval)
         return true;
 
       // The connection failed so the handler will be posted with an error code.
       if (connect_error)
       {
-        ec = boost::system::error_code(connect_error,
+        o->ec_ = boost::system::error_code(connect_error,
             boost::asio::error::get_system_category());
-        return true;
       }
 
       return true;
     }
 
-    void complete(const boost::system::error_code& ec, std::size_t)
+  private:
+    socket_type socket_;
+  };
+
+  template <typename Handler>
+  class connect_op : public connect_op_base
+  {
+  public:
+    connect_op(socket_type socket, Handler handler)
+      : connect_op_base(socket, &connect_op::do_complete),
+        handler_(handler)
     {
-      io_service_.post(bind_handler(this->handler_, ec));
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      connect_op* o(static_cast<connect_op*>(base));
+      typedef handler_alloc_traits<Handler, connect_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder1<Handler, boost::system::error_code>
+          handler(o->handler_, o->ec_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    socket_type socket_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
+    Handler handler_;
   };
 
   // Start an asynchronous connect.
@@ -1767,59 +1651,103 @@
   void async_connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor));
-      return;
-    }
+    // Allocate and construct an operation to wrap the handler.
+    typedef connect_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, handler);
+
+    start_connect_op(impl, ptr.get(), peer_endpoint);
+    ptr.release();
+  }
 
-    // Make socket non-blocking.
-    if (!(impl.flags_ & implementation_type::internal_non_blocking))
+private:
+  // Start the asynchronous read or write operation.
+  void start_op(implementation_type& impl, int op_type,
+      reactor_op* op, bool non_blocking, bool noop)
+  {
+    if (!noop)
     {
-      if (!(impl.flags_ & implementation_type::non_blocking))
+      if (is_open(impl))
       {
-        ioctl_arg_type non_blocking = 1;
-        boost::system::error_code ec;
-        if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
+        if (!non_blocking || is_non_blocking(impl)
+            || set_non_blocking(impl, op->ec_))
         {
-          this->get_io_service().post(bind_handler(handler, ec));
+          reactor_.start_op(op_type, impl.socket_,
+              impl.reactor_data_, op, non_blocking);
           return;
         }
       }
-      impl.flags_ |= implementation_type::internal_non_blocking;
+      else
+        op->ec_ = boost::asio::error::bad_descriptor;
     }
 
-    // Start the connect operation. The socket is already marked as non-blocking
-    // so the connection will take place asynchronously.
-    boost::system::error_code ec;
-    if (socket_ops::connect(impl.socket_, peer_endpoint.data(),
-          peer_endpoint.size(), ec) == 0)
-    {
-      // The connect operation has finished successfully so we need to post the
-      // handler immediately.
-      this->get_io_service().post(bind_handler(handler,
-            boost::system::error_code()));
-    }
-    else if (ec == boost::asio::error::in_progress
-        || ec == boost::asio::error::would_block)
-    {
-      // The connection is happening in the background, and we need to wait
-      // until the socket becomes writeable.
-      reactor_.start_connect_op(impl.socket_, impl.reactor_data_,
-          connect_operation<Handler>(impl.socket_,
-            this->get_io_service(), handler));
-    }
+    io_service_impl_.post_immediate_completion(op);
+  }
+
+  // Start the asynchronous accept operation.
+  void start_accept_op(implementation_type& impl,
+      reactor_op* op, bool peer_is_open)
+  {
+    if (!peer_is_open)
+      start_op(impl, reactor::read_op, op, true, false);
     else
     {
-      // The connect operation has failed, so post the handler immediately.
-      this->get_io_service().post(bind_handler(handler, ec));
+      op->ec_ = boost::asio::error::already_open;
+      io_service_impl_.post_immediate_completion(op);
     }
   }
 
-private:
+  // Start the asynchronous connect operation.
+  void start_connect_op(implementation_type& impl,
+      reactor_op* op, const endpoint_type& peer_endpoint)
+  {
+    if (is_open(impl))
+    {
+      if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_))
+      {
+        if (socket_ops::connect(impl.socket_, peer_endpoint.data(),
+              peer_endpoint.size(), op->ec_) != 0)
+        {
+          if (op->ec_ == boost::asio::error::in_progress
+              || op->ec_ == boost::asio::error::would_block)
+          {
+            op->ec_ = boost::system::error_code();
+            reactor_.start_op(reactor::connect_op,
+                impl.socket_, impl.reactor_data_, op, true);
+            return;
+          }
+        }
+      }
+    }
+    else
+      op->ec_ = boost::asio::error::bad_descriptor;
+
+    io_service_impl_.post_immediate_completion(op);
+  }
+
+  // Determine whether the socket has been set non-blocking.
+  bool is_non_blocking(implementation_type& impl) const
+  {
+    return (impl.flags_ & implementation_type::non_blocking);
+  }
+
+  // Set the internal non-blocking flag.
+  bool set_non_blocking(implementation_type& impl,
+      boost::system::error_code& ec)
+  {
+    ioctl_arg_type non_blocking = 1;
+    if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
+      return false;
+    impl.flags_ |= implementation_type::internal_non_blocking;
+    return true;
+  }
+
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_impl_;
+
   // The selector that performs event demultiplexing for the service.
-  Reactor& reactor_;
+  reactor& reactor_;
 };
 
 } // namespace detail
Added: trunk/boost/asio/detail/reactor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactor.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,34 @@
+//
+// reactor.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_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/reactor_fwd.hpp>
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+# include <boost/asio/detail/epoll_reactor.hpp>
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+# include <boost/asio/detail/kqueue_reactor.hpp>
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+# include <boost/asio/detail/dev_poll_reactor.hpp>
+#else
+# include <boost/asio/detail/select_reactor.hpp>
+#endif
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTOR_HPP
Added: trunk/boost/asio/detail/reactor_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactor_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,48 @@
+//
+// reactor_fwd.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_REACTOR_FWD_HPP
+#define BOOST_ASIO_DETAIL_REACTOR_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/dev_poll_reactor_fwd.hpp>
+#include <boost/asio/detail/epoll_reactor_fwd.hpp>
+#include <boost/asio/detail/kqueue_reactor_fwd.hpp>
+#include <boost/asio/detail/select_reactor_fwd.hpp>
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+typedef select_reactor<true> reactor;
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+typedef epoll_reactor reactor;
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+typedef kqueue_reactor reactor;
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+typedef dev_poll_reactor reactor;
+#else
+typedef select_reactor<false> reactor;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTOR_FWD_HPP
Added: trunk/boost/asio/detail/reactor_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactor_op.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,62 @@
+//
+// reactor_op.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_REACTOR_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTOR_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/operation.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactor_op
+  : public operation
+{
+public:
+  // The error code to be passed to the completion handler.
+  boost::system::error_code ec_;
+
+  // The number of bytes transferred, to be passed to the completion handler.
+  std::size_t bytes_transferred_;
+
+  // Perform the operation. Returns true if it is finished.
+  bool perform()
+  {
+    return perform_func_(this);
+  }
+
+protected:
+  typedef bool (*perform_func_type)(reactor_op*);
+
+  reactor_op(perform_func_type perform_func, func_type complete_func)
+    : operation(complete_func),
+      bytes_transferred_(0),
+      perform_func_(perform_func)
+  {
+  }
+
+private:
+  perform_func_type perform_func_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTOR_OP_HPP
Modified: trunk/boost/asio/detail/reactor_op_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/reactor_op_queue.hpp	(original)
+++ trunk/boost/asio/detail/reactor_op_queue.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -17,14 +17,11 @@
 
 #include <boost/asio/detail/push_options.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <memory>
-#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/reactor_op.hpp>
 
 namespace boost {
 namespace asio {
@@ -37,39 +34,21 @@
 public:
   // Constructor.
   reactor_op_queue()
-    : operations_(),
-      cancelled_operations_(0),
-      complete_operations_(0)
+    : operations_()
   {
   }
 
   // Add a new operation to the queue. Returns true if this is the only
   // operation for the given descriptor, in which case the reactor's event
   // demultiplexing function call may need to be interrupted and restarted.
-  template <typename Operation>
-  bool enqueue_operation(Descriptor descriptor, Operation operation)
+  bool enqueue_operation(Descriptor descriptor, reactor_op* op)
   {
-    // Allocate and construct an object to wrap the handler.
-    typedef handler_alloc_traits<Operation, op<Operation> > alloc_traits;
-    raw_handler_ptr<alloc_traits> raw_ptr(operation);
-    handler_ptr<alloc_traits> ptr(raw_ptr, descriptor, operation);
-
-    typedef typename operation_map::iterator iterator;
-    typedef typename operation_map::value_type value_type;
+    typedef typename operations_map::iterator iterator;
+    typedef typename operations_map::value_type value_type;
     std::pair<iterator, bool> entry =
-      operations_.insert(value_type(descriptor, ptr.get()));
-    if (entry.second)
-    {
-      ptr.release();
-      return true;
-    }
-
-    op_base* current_op = entry.first->second;
-    while (current_op->next_)
-      current_op = current_op->next_;
-    current_op->next_ = ptr.release();
-
-    return false;
+      operations_.insert(value_type(descriptor, operations()));
+    entry.first->second.op_queue_.push(op);
+    return entry.second;
   }
 
   // Cancel all operations associated with the descriptor. Any operations
@@ -77,16 +56,19 @@
   // next time perform_cancellations is called. Returns true if any operations
   // were cancelled, in which case the reactor's event demultiplexing function
   // may need to be interrupted and restarted.
-  bool cancel_operations(Descriptor descriptor)
+  bool cancel_operations(Descriptor descriptor, op_queue<operation>& ops,
+      const boost::system::error_code& ec =
+        boost::asio::error::operation_aborted)
   {
-    typename operation_map::iterator i = operations_.find(descriptor);
+    typename operations_map::iterator i = operations_.find(descriptor);
     if (i != operations_.end())
     {
-      op_base* last_op = i->second;
-      while (last_op->next_)
-        last_op = last_op->next_;
-      last_op->next_ = cancelled_operations_;
-      cancelled_operations_ = i->second;
+      while (reactor_op* op = i->second.op_queue_.front())
+      {
+        op->ec_ = ec;
+        i->second.op_queue_.pop();
+        ops.push(op);
+      }
       operations_.erase(i);
       return true;
     }
@@ -106,79 +88,37 @@
     return operations_.find(descriptor) != operations_.end();
   }
 
-  // Perform the first operation corresponding to the descriptor. Returns true
-  // if there are more operations queued for the descriptor.
-  bool perform_operation(Descriptor descriptor,
-      const boost::system::error_code& result)
+  // Perform the operations corresponding to the descriptor. Returns true if
+  // there are still unfinished operations queued for the descriptor.
+  bool perform_operations(Descriptor descriptor, op_queue<operation>& ops)
   {
-    typename operation_map::iterator i = operations_.find(descriptor);
+    typename operations_map::iterator i = operations_.find(descriptor);
     if (i != operations_.end())
     {
-      op_base* this_op = i->second;
-      i->second = this_op->next_;
-      this_op->next_ = complete_operations_;
-      complete_operations_ = this_op;
-      bool done = this_op->perform(result);
-      if (done)
+      while (reactor_op* op = i->second.op_queue_.front())
       {
-        // Operation has finished.
-        if (i->second)
+        if (op->perform())
         {
-          return true;
+          i->second.op_queue_.pop();
+          ops.push(op);
         }
         else
         {
-          operations_.erase(i);
-          return false;
-        }
-      }
-      else
-      {
-        // Operation wants to be called again. Leave it at the front of the
-        // queue for this descriptor, and remove from the completed list.
-        complete_operations_ = this_op->next_;
-        this_op->next_ = i->second;
-        i->second = this_op;
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // Perform all operations corresponding to the descriptor.
-  void perform_all_operations(Descriptor descriptor,
-      const boost::system::error_code& result)
-  {
-    typename operation_map::iterator i = operations_.find(descriptor);
-    if (i != operations_.end())
-    {
-      while (i->second)
-      {
-        op_base* this_op = i->second;
-        i->second = this_op->next_;
-        this_op->next_ = complete_operations_;
-        complete_operations_ = this_op;
-        bool done = this_op->perform(result);
-        if (!done)
-        {
-          // Operation has not finished yet, so leave at front of queue, and
-          // remove from the completed list.
-          complete_operations_ = this_op->next_;
-          this_op->next_ = i->second;
-          i->second = this_op;
-          return;
+          return true;
         }
       }
       operations_.erase(i);
     }
+    return false;
   }
 
   // Fill a descriptor set with the descriptors corresponding to each active
-  // operation.
+  // operation. The op_queue is used only when descriptors fail to be added to
+  // the descriptor set.
   template <typename Descriptor_Set>
-  void get_descriptors(Descriptor_Set& descriptors)
+  void get_descriptors(Descriptor_Set& descriptors, op_queue<operation>& ops)
   {
-    typename operation_map::iterator i = operations_.begin();
+    typename operations_map::iterator i = operations_.begin();
     while (i != operations_.end())
     {
       Descriptor descriptor = i->first;
@@ -186,7 +126,7 @@
       if (!descriptors.set(descriptor))
       {
         boost::system::error_code ec(error::fd_set_failure);
-        perform_all_operations(descriptor, ec);
+        cancel_operations(descriptor, ops, ec);
       }
     }
   }
@@ -194,257 +134,62 @@
   // Perform the operations corresponding to the ready file descriptors
   // contained in the given descriptor set.
   template <typename Descriptor_Set>
-  void perform_operations_for_descriptors(const Descriptor_Set& descriptors,
-      const boost::system::error_code& result)
+  void perform_operations_for_descriptors(
+      const Descriptor_Set& descriptors, op_queue<operation>& ops)
   {
-    typename operation_map::iterator i = operations_.begin();
+    typename operations_map::iterator i = operations_.begin();
     while (i != operations_.end())
     {
-      typename operation_map::iterator op_iter = i++;
+      typename operations_map::iterator op_iter = i++;
       if (descriptors.is_set(op_iter->first))
       {
-        op_base* this_op = op_iter->second;
-        op_iter->second = this_op->next_;
-        this_op->next_ = complete_operations_;
-        complete_operations_ = this_op;
-        bool done = this_op->perform(result);
-        if (done)
-        {
-          if (!op_iter->second)
-            operations_.erase(op_iter);
-        }
-        else
+        while (reactor_op* op = op_iter->second.op_queue_.front())
         {
-          // Operation has not finished yet, so leave at front of queue, and
-          // remove from the completed list.
-          complete_operations_ = this_op->next_;
-          this_op->next_ = op_iter->second;
-          op_iter->second = this_op;
+          if (op->perform())
+          {
+            op_iter->second.op_queue_.pop();
+            ops.push(op);
+          }
+          else
+          {
+            break;
+          }
         }
-      }
-    }
-  }
 
-  // Perform any pending cancels for operations.
-  void perform_cancellations()
-  {
-    while (cancelled_operations_)
-    {
-      op_base* this_op = cancelled_operations_;
-      cancelled_operations_ = this_op->next_;
-      this_op->next_ = complete_operations_;
-      complete_operations_ = this_op;
-      this_op->perform(boost::asio::error::operation_aborted);
-    }
-  }
-
-  // Complete all operations that are waiting to be completed.
-  void complete_operations()
-  {
-    while (complete_operations_)
-    {
-      op_base* next_op = complete_operations_->next_;
-      complete_operations_->next_ = 0;
-      complete_operations_->complete();
-      complete_operations_ = next_op;
+        if (op_iter->second.op_queue_.empty())
+          operations_.erase(op_iter);
+      }
     }
   }
 
-  // Destroy all operations owned by the queue.
-  void destroy_operations()
+  // Get all operations owned by the queue.
+  void get_all_operations(op_queue<operation>& ops)
   {
-    while (cancelled_operations_)
-    {
-      op_base* next_op = cancelled_operations_->next_;
-      cancelled_operations_->next_ = 0;
-      cancelled_operations_->destroy();
-      cancelled_operations_ = next_op;
-    }
-
-    while (complete_operations_)
-    {
-      op_base* next_op = complete_operations_->next_;
-      complete_operations_->next_ = 0;
-      complete_operations_->destroy();
-      complete_operations_ = next_op;
-    }
-
-    typename operation_map::iterator i = operations_.begin();
+    typename operations_map::iterator i = operations_.begin();
     while (i != operations_.end())
     {
-      typename operation_map::iterator op_iter = i++;
-      op_base* curr_op = op_iter->second;
+      typename operations_map::iterator op_iter = i++;
+      ops.push(op_iter->second.op_queue_);
       operations_.erase(op_iter);
-      while (curr_op)
-      {
-        op_base* next_op = curr_op->next_;
-        curr_op->next_ = 0;
-        curr_op->destroy();
-        curr_op = next_op;
-      }
     }
   }
 
 private:
-  // Base class for reactor operations. A function pointer is used instead of
-  // virtual functions to avoid the associated overhead.
-  class op_base
+  struct operations
   {
-  public:
-    // Get the descriptor associated with the operation.
-    Descriptor descriptor() const
-    {
-      return descriptor_;
-    }
-
-    // Perform the operation.
-    bool perform(const boost::system::error_code& result)
-    {
-      result_ = result;
-      return perform_func_(this, result_, bytes_transferred_);
-    }
-
-    // Destroy the operation and post the handler.
-    void complete()
-    {
-      complete_func_(this, result_, bytes_transferred_);
-    }
-
-    // Destroy the operation.
-    void destroy()
-    {
-      destroy_func_(this);
-    }
-
-  protected:
-    typedef bool (*perform_func_type)(op_base*,
-        boost::system::error_code&, std::size_t&);
-    typedef void (*complete_func_type)(op_base*,
-        const boost::system::error_code&, std::size_t);
-    typedef void (*destroy_func_type)(op_base*);
-
-    // Construct an operation for the given descriptor.
-    op_base(perform_func_type perform_func, complete_func_type complete_func,
-        destroy_func_type destroy_func, Descriptor descriptor)
-      : perform_func_(perform_func),
-        complete_func_(complete_func),
-        destroy_func_(destroy_func),
-        descriptor_(descriptor),
-        result_(),
-        bytes_transferred_(0),
-        next_(0)
-    {
-    }
-
-    // Prevent deletion through this type.
-    ~op_base()
-    {
-    }
-
-  private:
-    friend class reactor_op_queue<Descriptor>;
-
-    // The function to be called to perform the operation.
-    perform_func_type perform_func_;
-
-    // The function to be called to delete the operation and post the handler.
-    complete_func_type complete_func_;
-
-    // The function to be called to delete the operation.
-    destroy_func_type destroy_func_;
+    operations() {}
+    operations(const operations&) {}
+    void operator=(const operations&) {}
 
-    // The descriptor associated with the operation.
-    Descriptor descriptor_;
-
-    // The result of the operation.
-    boost::system::error_code result_;
-
-    // The number of bytes transferred in the operation.
-    std::size_t bytes_transferred_;
-
-    // The next operation for the same file descriptor.
-    op_base* next_;
-  };
-
-  // Adaptor class template for operations.
-  template <typename Operation>
-  class op
-    : public op_base
-  {
-  public:
-    // Constructor.
-    op(Descriptor descriptor, Operation operation)
-      : op_base(&op<Operation>::do_perform, &op<Operation>::do_complete,
-          &op<Operation>::do_destroy, descriptor),
-        operation_(operation)
-    {
-    }
-
-    // Perform the operation.
-    static bool do_perform(op_base* base,
-        boost::system::error_code& result, std::size_t& bytes_transferred)
-    {
-      return static_cast<op<Operation>*>(base)->operation_.perform(
-          result, bytes_transferred);
-    }
-
-    // Destroy the operation and post the handler.
-    static void do_complete(op_base* base,
-        const boost::system::error_code& result, std::size_t bytes_transferred)
-    {
-      // Take ownership of the operation object.
-      typedef op<Operation> this_type;
-      this_type* this_op(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Operation, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(this_op->operation_, this_op);
-
-      // Make a copy of the error_code and the operation so that the memory can
-      // be deallocated before the upcall is made.
-      boost::system::error_code ec(result);
-      Operation operation(this_op->operation_);
-
-      // Free the memory associated with the operation.
-      ptr.reset();
-
-      // Make the upcall.
-      operation.complete(ec, bytes_transferred);
-    }
-
-    // Destroy the operation.
-    static void do_destroy(op_base* base)
-    {
-      // Take ownership of the operation object.
-      typedef op<Operation> this_type;
-      this_type* this_op(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Operation, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(this_op->operation_, this_op);
-
-      // A sub-object of the operation may be the true owner of the memory
-      // associated with the operation. Consequently, a local copy of the
-      // operation is required to ensure that any owning sub-object remains
-      // valid until after we have deallocated the memory here.
-      Operation operation(this_op->operation_);
-      (void)operation;
-
-      // Free the memory associated with the operation.
-      ptr.reset();
-    }
-
-  private:
-    Operation operation_;
+    // The operations waiting on the desccriptor.
+    op_queue<reactor_op> op_queue_;
   };
 
   // The type for a map of operations.
-  typedef hash_map<Descriptor, op_base*> operation_map;
+  typedef hash_map<Descriptor, operations> operations_map;
 
   // The operations that are currently executing asynchronously.
-  operation_map operations_;
-
-  // The list of operations that have been cancelled.
-  op_base* cancelled_operations_;
-
-  // The list of operations waiting to be completed.
-  op_base* complete_operations_;
+  operations_map operations_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/resolver_service.hpp
==============================================================================
--- trunk/boost/asio/detail/resolver_service.hpp	(original)
+++ trunk/boost/asio/detail/resolver_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -27,8 +27,10 @@
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/mutex.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/operation.hpp>
 #include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
@@ -89,7 +91,10 @@
     : boost::asio::detail::service_base<
         resolver_service<Protocol> >(io_service),
       mutex_(),
+      io_service_impl_(boost::asio::use_service<io_service_impl>(io_service)),
       work_io_service_(new boost::asio::io_service),
+      work_io_service_impl_(boost::asio::use_service<
+          io_service_impl>(*work_io_service_)),
       work_(new boost::asio::io_service::work(*work_io_service_)),
       work_thread_(0)
   {
@@ -143,7 +148,7 @@
     std::string service_name = query.service_name();
     boost::asio::detail::addrinfo_type hints = query.hints();
 
-    socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
+    socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0,
         service_name.c_str(), &hints, &address_info, ec);
     auto_addrinfo auto_address_info(address_info);
 
@@ -154,54 +159,84 @@
   }
 
   template <typename Handler>
-  class resolve_query_handler
+  class resolve_op
+    : public operation
   {
   public:
-    resolve_query_handler(implementation_type impl, const query_type& query,
-        boost::asio::io_service& io_service, Handler handler)
-      : impl_(impl),
+    resolve_op(implementation_type impl, const query_type& query,
+        io_service_impl& io_service_impl, Handler handler)
+      : operation(&resolve_op::do_complete),
+        impl_(impl),
         query_(query),
-        io_service_(io_service),
-        work_(io_service),
+        io_service_impl_(io_service_impl),
         handler_(handler)
     {
     }
 
-    void operator()()
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
     {
-      // Check if the operation has been cancelled.
-      if (impl_.expired())
+      // Take ownership of the operation object.
+      resolve_op* o(static_cast<resolve_op*>(base));
+      typedef handler_alloc_traits<Handler, resolve_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      if (owner)
       {
-        iterator_type iterator;
-        io_service_.post(boost::asio::detail::bind_handler(handler_,
-              boost::asio::error::operation_aborted, iterator));
-        return;
+        if (owner != &o->io_service_impl_)
+        {
+          // The operation is being run on the worker io_service. Time to
+          // perform the resolver operation.
+        
+          if (o->impl_.expired())
+          {
+            // THe operation has been cancelled.
+            o->ec_ = boost::asio::error::operation_aborted;
+          }
+          else
+          {
+            // Perform the blocking host resolution operation.
+            boost::asio::detail::addrinfo_type* address_info = 0;
+            std::string host_name = o->query_.host_name();
+            std::string service_name = o->query_.service_name();
+            boost::asio::detail::addrinfo_type hints = o->query_.hints();
+            socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0,
+                service_name.c_str(), &hints, &address_info, o->ec_);
+            auto_addrinfo auto_address_info(address_info);
+            o->iter_ = iterator_type::create(
+              address_info, host_name, service_name);
+          }
+
+          o->io_service_impl_.post_deferred_completion(o);
+          ptr.release();
+        }
+        else
+        {
+          // The operation has been returned to the main io_serice. The
+          // completion handler is ready to be delivered.
+
+          // Make a copy of the handler so that the memory can be deallocated
+          // before the upcall is made. Even if we're not about to make an
+          // upcall, 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.
+          detail::binder2<Handler, boost::system::error_code, iterator_type>
+            handler(o->handler_, o->ec_, o->iter_);
+          ptr.reset();
+          boost::asio::detail::fenced_block b;
+          boost_asio_handler_invoke_helpers::invoke(handler, handler);
+        }
       }
-
-      // Perform the blocking host resolution operation.
-      boost::asio::detail::addrinfo_type* address_info = 0;
-      std::string host_name = query_.host_name();
-      std::string service_name = query_.service_name();
-      boost::asio::detail::addrinfo_type hints = query_.hints();
-      boost::system::error_code ec;
-      socket_ops::getaddrinfo(host_name.length() ? host_name.c_str() : 0,
-          service_name.c_str(), &hints, &address_info, ec);
-      auto_addrinfo auto_address_info(address_info);
-
-      // Invoke the handler and pass the result.
-      iterator_type iterator;
-      if (!ec)
-        iterator = iterator_type::create(address_info, host_name, service_name);
-      io_service_.post(boost::asio::detail::bind_handler(
-            handler_, ec, iterator));
     }
 
   private:
     boost::weak_ptr<void> impl_;
     query_type query_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
+    io_service_impl& io_service_impl_;
     Handler handler_;
+    boost::system::error_code ec_;
+    iterator_type iter_;
   };
 
   // Asynchronously resolve a query to a list of entries.
@@ -209,12 +244,19 @@
   void async_resolve(implementation_type& impl, const query_type& query,
       Handler handler)
   {
+    // Allocate and construct an operation to wrap the handler.
+    typedef resolve_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        impl, query, io_service_impl_, handler);
+
     if (work_io_service_)
     {
       start_work_thread();
-      work_io_service_->post(
-          resolve_query_handler<Handler>(
-            impl, query, this->get_io_service(), handler));
+      io_service_impl_.work_started();
+      work_io_service_impl_.post_immediate_completion(ptr.get());
+      ptr.release();
     }
   }
 
@@ -243,61 +285,89 @@
   }
 
   template <typename Handler>
-  class resolve_endpoint_handler
+  class resolve_endpoint_op
+    : public operation
   {
   public:
-    resolve_endpoint_handler(implementation_type impl,
-        const endpoint_type& endpoint, boost::asio::io_service& io_service,
-        Handler handler)
-      : impl_(impl),
-        endpoint_(endpoint),
-        io_service_(io_service),
-        work_(io_service),
+    resolve_endpoint_op(implementation_type impl, const endpoint_type& ep,
+        io_service_impl& io_service_impl, Handler handler)
+      : operation(&resolve_endpoint_op::do_complete),
+        impl_(impl),
+        ep_(ep),
+        io_service_impl_(io_service_impl),
         handler_(handler)
     {
     }
 
-    void operator()()
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
     {
-      // Check if the operation has been cancelled.
-      if (impl_.expired())
-      {
-        iterator_type iterator;
-        io_service_.post(boost::asio::detail::bind_handler(handler_,
-              boost::asio::error::operation_aborted, iterator));
-        return;
-      }
-
+      // Take ownership of the operation object.
+      resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base));
+      typedef handler_alloc_traits<Handler, resolve_endpoint_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
-      // First try resolving with the service name. If that fails try resolving
-      // but allow the service to be returned as a number.
-      char host_name[NI_MAXHOST];
-      char service_name[NI_MAXSERV];
-      int flags = endpoint_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
-      boost::system::error_code ec;
-      socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
-          host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
-      if (ec)
+      if (owner)
       {
-        flags |= NI_NUMERICSERV;
-        socket_ops::getnameinfo(endpoint_.data(), endpoint_.size(),
-            host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
+        if (owner != &o->io_service_impl_)
+        {
+          // The operation is being run on the worker io_service. Time to
+          // perform the resolver operation.
+        
+          if (o->impl_.expired())
+          {
+            // THe operation has been cancelled.
+            o->ec_ = boost::asio::error::operation_aborted;
+          }
+          else
+          {
+            // Perform the blocking endoint resolution operation.
+            char host_name[NI_MAXHOST];
+            char service_name[NI_MAXSERV];
+            int flags = o->ep_.protocol().type() == SOCK_DGRAM ? NI_DGRAM : 0;
+            socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(),
+                host_name, NI_MAXHOST, service_name,
+                NI_MAXSERV, flags, o->ec_);
+            if (o->ec_)
+            {
+              flags |= NI_NUMERICSERV;
+              socket_ops::getnameinfo(o->ep_.data(), o->ep_.size(),
+                  host_name, NI_MAXHOST, service_name,
+                  NI_MAXSERV, flags, o->ec_);
+            }
+            o->iter_ = iterator_type::create(o->ep_, host_name, service_name);
+          }
+
+          o->io_service_impl_.post_deferred_completion(o);
+          ptr.release();
+        }
+        else
+        {
+          // The operation has been returned to the main io_serice. The
+          // completion handler is ready to be delivered.
+
+          // Make a copy of the handler so that the memory can be deallocated
+          // before the upcall is made. Even if we're not about to make an
+          // upcall, 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.
+          detail::binder2<Handler, boost::system::error_code, iterator_type>
+            handler(o->handler_, o->ec_, o->iter_);
+          ptr.reset();
+          boost::asio::detail::fenced_block b;
+          boost_asio_handler_invoke_helpers::invoke(handler, handler);
+        }
       }
-
-      // Invoke the handler and pass the result.
-      iterator_type iterator;
-      if (!ec)
-        iterator = iterator_type::create(endpoint_, host_name, service_name);
-      io_service_.post(boost::asio::detail::bind_handler(
-            handler_, ec, iterator));
     }
 
   private:
     boost::weak_ptr<void> impl_;
-    endpoint_type endpoint_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
+    endpoint_type ep_;
+    io_service_impl& io_service_impl_;
     Handler handler_;
+    boost::system::error_code ec_;
+    iterator_type iter_;
   };
 
   // Asynchronously resolve an endpoint to a list of entries.
@@ -305,12 +375,19 @@
   void async_resolve(implementation_type& impl, const endpoint_type& endpoint,
       Handler handler)
   {
+    // Allocate and construct an operation to wrap the handler.
+    typedef resolve_endpoint_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        impl, endpoint, io_service_impl_, handler);
+
     if (work_io_service_)
     {
       start_work_thread();
-      work_io_service_->post(
-          resolve_endpoint_handler<Handler>(
-            impl, endpoint, this->get_io_service(), handler));
+      io_service_impl_.work_started();
+      work_io_service_impl_.post_immediate_completion(ptr.get());
+      ptr.release();
     }
   }
 
@@ -340,9 +417,15 @@
   // Mutex to protect access to internal data.
   boost::asio::detail::mutex mutex_;
 
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_impl_;
+
   // Private io_service used for performing asynchronous host resolution.
   boost::scoped_ptr<boost::asio::io_service> work_io_service_;
 
+  // The work io_service implementation used to post completions.
+  io_service_impl& work_io_service_impl_;
+
   // Work for the private io_service to perform.
   boost::scoped_ptr<boost::asio::io_service::work> work_;
 
Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp	(original)
+++ trunk/boost/asio/detail/select_reactor.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -22,9 +22,6 @@
 #include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
 #include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/shared_ptr.hpp>
-#include <vector>
 #include <boost/asio/detail/pop_options.hpp>
 
 #include <boost/asio/io_service.hpp>
@@ -32,6 +29,8 @@
 #include <boost/asio/detail/fd_set_adapter.hpp>
 #include <boost/asio/detail/mutex.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/reactor_op_queue.hpp>
 #include <boost/asio/detail/select_interrupter.hpp>
 #include <boost/asio/detail/select_reactor_fwd.hpp>
@@ -39,9 +38,11 @@
 #include <boost/asio/detail/signal_blocker.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/task_io_service.hpp>
 #include <boost/asio/detail/thread.hpp>
-#include <boost/asio/detail/timer_queue.hpp>
+#include <boost/asio/detail/timer_op.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_fwd.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
 
 namespace boost {
 namespace asio {
@@ -52,6 +53,14 @@
   : public boost::asio::detail::service_base<select_reactor<Own_Thread> >
 {
 public:
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  enum { read_op = 0, write_op = 1, except_op = 2,
+    max_select_ops = 3, connect_op = 3, max_ops = 4 };
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+  enum { read_op = 0, write_op = 1, except_op = 2,
+    max_select_ops = 3, connect_op = 1, max_ops = 3 };
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
   // Per-descriptor data.
   struct per_descriptor_data
   {
@@ -61,13 +70,9 @@
   select_reactor(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         select_reactor<Own_Thread> >(io_service),
+      io_service_(use_service<io_service_impl>(io_service)),
       mutex_(),
-      select_in_progress_(false),
       interrupter_(),
-      read_op_queue_(),
-      write_op_queue_(),
-      except_op_queue_(),
-      pending_cancellations_(),
       stop_thread_(false),
       thread_(0),
       shutdown_(false)
@@ -94,31 +99,29 @@
     stop_thread_ = true;
     lock.unlock();
 
-    if (thread_)
+    if (Own_Thread)
     {
-      interrupter_.interrupt();
-      thread_->join();
-      delete thread_;
-      thread_ = 0;
+      if (thread_)
+      {
+        interrupter_.interrupt();
+        thread_->join();
+        delete thread_;
+        thread_ = 0;
+      }
     }
 
-    read_op_queue_.destroy_operations();
-    write_op_queue_.destroy_operations();
-    except_op_queue_.destroy_operations();
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->destroy_timers();
-    timer_queues_.clear();
+    op_queue<operation> ops;
+
+    for (int i = 0; i < max_ops; ++i)
+      op_queue_[i].get_all_operations(ops);
+
+    timer_queues_.get_all_timers(ops);
   }
 
   // Initialise the task, but only if the reactor is not in its own thread.
   void init_task()
   {
-    if (!Own_Thread)
-    {
-      typedef task_io_service<select_reactor<Own_Thread> > task_io_service_type;
-      use_service<task_io_service_type>(this->get_io_service()).init_task();
-    }
+    io_service_.init_task();
   }
 
   // Register a socket with the reactor. Returns 0 on success, system error
@@ -128,111 +131,17 @@
     return 0;
   }
 
-  // Start a new read operation. The handler object will be invoked when the
-  // given descriptor is ready to be read, or an error has occurred.
-  template <typename Handler>
-  void start_read_op(socket_type descriptor, per_descriptor_data&,
-      Handler handler, bool /*allow_speculative_read*/ = true)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    if (!shutdown_)
-      if (read_op_queue_.enqueue_operation(descriptor, handler))
-        interrupter_.interrupt();
-  }
-
-  // Start a new write operation. The handler object will be invoked when the
-  // given descriptor is ready to be written, or an error has occurred.
-  template <typename Handler>
-  void start_write_op(socket_type descriptor, per_descriptor_data&,
-      Handler handler, bool /*allow_speculative_write*/ = true)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    if (!shutdown_)
-      if (write_op_queue_.enqueue_operation(descriptor, handler))
-        interrupter_.interrupt();
-  }
-
-  // Start a new exception operation. The handler object will be invoked when
-  // the given descriptor has exception information, or an error has occurred.
-  template <typename Handler>
-  void start_except_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
-  {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    if (!shutdown_)
-      if (except_op_queue_.enqueue_operation(descriptor, handler))
-        interrupter_.interrupt();
-  }
-
-  // Wrapper for connect handlers to enable the handler object to be placed
-  // in both the write and the except operation queues, but ensure that only
-  // one of the handlers is called.
-  template <typename Handler>
-  class connect_handler_wrapper
-  {
-  public:
-    connect_handler_wrapper(socket_type descriptor,
-        boost::shared_ptr<bool> completed,
-        select_reactor<Own_Thread>& reactor, Handler handler)
-      : descriptor_(descriptor),
-        completed_(completed),
-        reactor_(reactor),
-        handler_(handler)
-    {
-    }
-
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
-    {
-      // Check whether one of the handlers has already been called. If it has,
-      // then we don't want to do anything in this handler.
-      if (*completed_)
-      {
-        completed_.reset(); // Indicate that this handler should not complete.
-        return true;
-      }
-
-      // Cancel the other reactor operation for the connection.
-      *completed_ = true;
-      reactor_.enqueue_cancel_ops_unlocked(descriptor_);
-
-      // Call the contained handler.
-      return handler_.perform(ec, bytes_transferred);
-    }
-
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      if (completed_.get())
-        handler_.complete(ec, bytes_transferred);
-    }
-
-  private:
-    socket_type descriptor_;
-    boost::shared_ptr<bool> completed_;
-    select_reactor<Own_Thread>& reactor_;
-    Handler handler_;
-  };
-
-  // Start new write and exception operations. The handler object will be
-  // invoked when the given descriptor is ready for writing or has exception
-  // information available, or an error has occurred. The handler will be called
-  // only once.
-  template <typename Handler>
-  void start_connect_op(socket_type descriptor,
-      per_descriptor_data&, Handler handler)
+  // Start a new operation. The reactor operation will be performed when the
+  // given descriptor is flagged as ready, or an error has occurred.
+  void start_op(int op_type, socket_type descriptor,
+      per_descriptor_data&, reactor_op* op, bool)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
     {
-      boost::shared_ptr<bool> completed(new bool(false));
-      connect_handler_wrapper<Handler> wrapped_handler(
-          descriptor, completed, *this, handler);
-      bool interrupt = write_op_queue_.enqueue_operation(
-          descriptor, wrapped_handler);
-      interrupt = except_op_queue_.enqueue_operation(
-          descriptor, wrapped_handler) || interrupt;
-      if (interrupt)
+      bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+      io_service_.work_started();
+      if (first)
         interrupter_.interrupt();
     }
   }
@@ -243,17 +152,7 @@
   void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    cancel_ops_unlocked(descriptor);
-  }
-
-  // Enqueue cancellation of all operations associated with the given
-  // descriptor. The handlers associated with the descriptor will be invoked
-  // with the operation_aborted error. This function does not acquire the
-  // select_reactor's mutex, and so should only be used when the reactor lock is
-  // already held.
-  void enqueue_cancel_ops_unlocked(socket_type descriptor)
-  {
-    pending_cancellations_.push_back(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Cancel any operations that are running against the descriptor and remove
@@ -261,7 +160,7 @@
   void close_descriptor(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    cancel_ops_unlocked(descriptor);
+    cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
   }
 
   // Add a new timer queue to the reactor.
@@ -269,7 +168,7 @@
   void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    timer_queues_.push_back(&timer_queue);
+    timer_queues_.insert(&timer_queue);
   }
 
   // Remove a timer queue from the reactor.
@@ -277,252 +176,186 @@
   void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      if (timer_queues_[i] == &timer_queue)
-      {
-        timer_queues_.erase(timer_queues_.begin() + i);
-        return;
-      }
-    }
+    timer_queues_.erase(&timer_queue);
   }
 
-  // Schedule a timer in the given timer queue to expire at the specified
-  // absolute time. The handler object will be invoked when the timer expires.
-  template <typename Time_Traits, typename Handler>
+  // 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, Handler handler, void* token)
+      const typename Time_Traits::time_type& time, timer_op* op, void* token)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
-      if (timer_queue.enqueue_timer(time, handler, token))
+    {
+      bool earliest = timer_queue.enqueue_timer(time, op, token);
+      io_service_.work_started();
+      if (earliest)
         interrupter_.interrupt();
+    }
   }
 
-  // Cancel the timer associated with the given token. Returns the number of
-  // handlers that have been posted or dispatched.
+  // 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)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    std::size_t n = timer_queue.cancel_timer(token);
-    if (n > 0)
-      interrupter_.interrupt();
+    op_queue<operation> ops;
+    std::size_t n = timer_queue.cancel_timer(token, ops);
+    lock.unlock();
+    io_service_.post_deferred_completions(ops);
     return n;
   }
 
-private:
-  friend class task_io_service<select_reactor<Own_Thread> >;
-
   // Run select once until interrupted or events are ready to be dispatched.
-  void run(bool block)
+  void run(bool block, op_queue<operation>& ops)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    // Dispatch any operation cancellations that were made while the select
-    // loop was not running.
-    read_op_queue_.perform_cancellations();
-    write_op_queue_.perform_cancellations();
-    except_op_queue_.perform_cancellations();
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->dispatch_cancellations();
-
     // Check if the thread is supposed to stop.
-    if (stop_thread_)
-    {
-      complete_operations_and_timers(lock);
-      return;
-    }
+    if (Own_Thread)
+      if (stop_thread_)
+        return;
+
+    // Set up the descriptor sets.
+    fd_set_adapter fds[max_select_ops];
+    fds[read_op].set(interrupter_.read_descriptor());
+    socket_type max_fd = 0;
+    bool have_work_to_do = !timer_queues_.all_empty();
+    for (int i = 0; i < max_select_ops; ++i)
+    {
+      have_work_to_do = have_work_to_do || !op_queue_[i].empty();
+      op_queue_[i].get_descriptors(fds[i], ops);
+      if (fds[i].max_descriptor() > max_fd)
+        max_fd = fds[i].max_descriptor();
+    }
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+    // Connection operations on Windows use both except and write fd_sets.
+    have_work_to_do = have_work_to_do || !op_queue_[connect_op].empty();
+    op_queue_[connect_op].get_descriptors(fds[write_op], ops);
+    if (fds[write_op].max_descriptor() > max_fd)
+      max_fd = fds[write_op].max_descriptor();
+    op_queue_[connect_op].get_descriptors(fds[except_op], ops);
+    if (fds[except_op].max_descriptor() > max_fd)
+      max_fd = fds[except_op].max_descriptor();
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
     // We can return immediately if there's no work to do and the reactor is
     // not supposed to block.
-    if (!block && read_op_queue_.empty() && write_op_queue_.empty()
-        && except_op_queue_.empty() && all_timer_queues_are_empty())
-    {
-      complete_operations_and_timers(lock);
+    if (!block && !have_work_to_do)
       return;
-    }
 
-    // Set up the descriptor sets.
-    fd_set_adapter read_fds;
-    read_fds.set(interrupter_.read_descriptor());
-    read_op_queue_.get_descriptors(read_fds);
-    fd_set_adapter write_fds;
-    write_op_queue_.get_descriptors(write_fds);
-    fd_set_adapter except_fds;
-    except_op_queue_.get_descriptors(except_fds);
-    socket_type max_fd = read_fds.max_descriptor();
-    if (write_fds.max_descriptor() > max_fd)
-      max_fd = write_fds.max_descriptor();
-    if (except_fds.max_descriptor() > max_fd)
-      max_fd = except_fds.max_descriptor();
-
-    // Block on the select call without holding the lock so that new
-    // operations can be started while the call is executing.
+    // Determine how long to block while waiting for events.
     timeval tv_buf = { 0, 0 };
     timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
-    select_in_progress_ = true;
+
     lock.unlock();
+
+    // Block on the select call until descriptors become ready.
     boost::system::error_code ec;
     int retval = socket_ops::select(static_cast<int>(max_fd + 1),
-        read_fds, write_fds, except_fds, tv, ec);
-    lock.lock();
-    select_in_progress_ = false;
+        fds[read_op], fds[write_op], fds[except_op], tv, ec);
 
     // Reset the interrupter.
-    if (retval > 0 && read_fds.is_set(interrupter_.read_descriptor()))
+    if (retval > 0 && fds[read_op].is_set(interrupter_.read_descriptor()))
       interrupter_.reset();
 
+    lock.lock();
+
     // Dispatch all ready operations.
     if (retval > 0)
     {
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+      // Connection operations on Windows use both except and write fd_sets.
+      op_queue_[connect_op].perform_operations_for_descriptors(
+          fds[except_op], ops);
+      op_queue_[connect_op].perform_operations_for_descriptors(
+          fds[write_op], ops);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
       // Exception operations must be processed first to ensure that any
       // out-of-band data is read before normal data.
-      except_op_queue_.perform_operations_for_descriptors(
-          except_fds, boost::system::error_code());
-      read_op_queue_.perform_operations_for_descriptors(
-          read_fds, boost::system::error_code());
-      write_op_queue_.perform_operations_for_descriptors(
-          write_fds, boost::system::error_code());
-      except_op_queue_.perform_cancellations();
-      read_op_queue_.perform_cancellations();
-      write_op_queue_.perform_cancellations();
-    }
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      timer_queues_[i]->dispatch_timers();
-      timer_queues_[i]->dispatch_cancellations();
+      for (int i = max_select_ops - 1; i >= 0; --i)
+        op_queue_[i].perform_operations_for_descriptors(fds[i], ops);
     }
+    timer_queues_.get_ready_timers(ops);
+  }
 
-    // Issue any pending cancellations.
-    for (size_t i = 0; i < pending_cancellations_.size(); ++i)
-      cancel_ops_unlocked(pending_cancellations_[i]);
-    pending_cancellations_.clear();
-
-    complete_operations_and_timers(lock);
+  // Interrupt the select loop.
+  void interrupt()
+  {
+    interrupter_.interrupt();
   }
 
+private:
   // Run the select loop in the thread.
   void run_thread()
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    while (!stop_thread_)
+    if (Own_Thread)
     {
-      lock.unlock();
-      run(true);
-      lock.lock();
+      boost::asio::detail::mutex::scoped_lock lock(mutex_);
+      while (!stop_thread_)
+      {
+        lock.unlock();
+        op_queue<operation> ops;
+        run(true, ops);
+        io_service_.post_deferred_completions(ops);
+        lock.lock();
+      }
     }
   }
 
   // Entry point for the select loop thread.
   static void call_run_thread(select_reactor* reactor)
   {
-    reactor->run_thread();
-  }
-
-  // Interrupt the select loop.
-  void interrupt()
-  {
-    interrupter_.interrupt();
-  }
-
-  // Check if all timer queues are empty.
-  bool all_timer_queues_are_empty() const
-  {
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      if (!timer_queues_[i]->empty())
-        return false;
-    return true;
+    if (Own_Thread)
+    {
+      reactor->run_thread();
+    }
   }
 
   // Get the timeout value for the select call.
   timeval* get_timeout(timeval& tv)
   {
-    if (all_timer_queues_are_empty())
-      return 0;
-
     // By default we will wait no longer than 5 minutes. This will ensure that
     // any changes to the system clock are detected after no longer than this.
-    boost::posix_time::time_duration minimum_wait_duration
-      = boost::posix_time::minutes(5);
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      boost::posix_time::time_duration wait_duration
-        = timer_queues_[i]->wait_duration();
-      if (wait_duration < minimum_wait_duration)
-        minimum_wait_duration = wait_duration;
-    }
-
-    if (minimum_wait_duration > boost::posix_time::time_duration())
-    {
-      tv.tv_sec = minimum_wait_duration.total_seconds();
-      tv.tv_usec = minimum_wait_duration.total_microseconds() % 1000000;
-    }
-    else
-    {
-      tv.tv_sec = 0;
-      tv.tv_usec = 0;
-    }
-
+    long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+    tv.tv_sec = usec / 1000000;
+    tv.tv_usec = usec % 1000000;
     return &tv;
   }
 
-  // Cancel all operations associated with the given descriptor. The do_cancel
-  // function of the handler objects will be invoked. This function does not
-  // acquire the select_reactor's mutex.
-  void cancel_ops_unlocked(socket_type descriptor)
-  {
-    bool interrupt = read_op_queue_.cancel_operations(descriptor);
-    interrupt = write_op_queue_.cancel_operations(descriptor) || interrupt;
-    interrupt = except_op_queue_.cancel_operations(descriptor) || interrupt;
-    if (interrupt)
+  // Cancel all operations associated with the given descriptor. This function
+  // does not acquire the select_reactor's mutex.
+  void cancel_ops_unlocked(socket_type descriptor,
+      const boost::system::error_code& ec)
+  {
+    bool need_interrupt = false;
+    op_queue<operation> ops;
+    for (int i = 0; i < max_ops; ++i)
+      need_interrupt = op_queue_[i].cancel_operations(
+          descriptor, ops, ec) || need_interrupt;
+    io_service_.post_deferred_completions(ops);
+    if (need_interrupt)
       interrupter_.interrupt();
   }
 
-  // Clean up operations and timers. We must not hold the lock since the
-  // destructors may make calls back into this reactor. We make a copy of the
-  // vector of timer queues since the original may be modified while the lock
-  // is not held.
-  void complete_operations_and_timers(
-      boost::asio::detail::mutex::scoped_lock& lock)
-  {
-    timer_queues_for_cleanup_ = timer_queues_;
-    lock.unlock();
-    read_op_queue_.complete_operations();
-    write_op_queue_.complete_operations();
-    except_op_queue_.complete_operations();
-    for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
-      timer_queues_for_cleanup_[i]->complete_timers();
-  }
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_;
 
   // Mutex to protect access to internal data.
   boost::asio::detail::mutex mutex_;
 
-  // Whether the select loop is currently running or not.
-  bool select_in_progress_;
-
   // The interrupter is used to break a blocking select call.
   select_interrupter interrupter_;
 
-  // The queue of read operations.
-  reactor_op_queue<socket_type> read_op_queue_;
-
-  // The queue of write operations.
-  reactor_op_queue<socket_type> write_op_queue_;
-
-  // The queue of exception operations.
-  reactor_op_queue<socket_type> except_op_queue_;
+  // The queues of read, write and except operations.
+  reactor_op_queue<socket_type> op_queue_[max_ops];
 
   // The timer queues.
-  std::vector<timer_queue_base*> timer_queues_;
-
-  // A copy of the timer queues, used when cleaning up timers. The copy is
-  // stored as a class data member to avoid unnecessary memory allocation.
-  std::vector<timer_queue_base*> timer_queues_for_cleanup_;
-
-  // The descriptors that are pending cancellation.
-  std::vector<socket_type> pending_cancellations_;
+  timer_queue_set timer_queues_;
 
   // Does the reactor loop thread need to stop.
   bool stop_thread_;
Modified: trunk/boost/asio/detail/service_registry.hpp
==============================================================================
--- trunk/boost/asio/detail/service_registry.hpp	(original)
+++ trunk/boost/asio/detail/service_registry.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -18,7 +18,6 @@
 #include <boost/asio/detail/push_options.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <memory>
 #include <typeinfo>
 #include <boost/asio/detail/pop_options.hpp>
 
@@ -80,7 +79,7 @@
     while (first_service_)
     {
       boost::asio::io_service::service* next_service = first_service_->next_;
-      delete first_service_;
+      destroy(first_service_);
       first_service_ = next_service;
     }
   }
@@ -91,14 +90,105 @@
   template <typename Service>
   Service& use_service()
   {
+    boost::asio::io_service::service::key key;
+    init_key(key, Service::id);
+    factory_type factory = &service_registry::create<Service>;
+    return *static_cast<Service*>(do_use_service(key, factory));
+  }
+
+  // Add a service object. Returns false on error, in which case ownership of
+  // the object is retained by the caller.
+  template <typename Service>
+  bool add_service(Service* new_service)
+  {
+    boost::asio::io_service::service::key key;
+    init_key(key, Service::id);
+    return do_add_service(key, new_service);
+  }
+
+  // Check whether a service object of the specified type already exists.
+  template <typename Service>
+  bool has_service() const
+  {
+    boost::asio::io_service::service::key key;
+    init_key(key, Service::id);
+    return do_has_service(key);
+  }
+
+private:
+  // Initialise a service's key based on its id.
+  void init_key(boost::asio::io_service::service::key& key,
+      const boost::asio::io_service::id& id)
+  {
+    key.type_info_ = 0;
+    key.id_ = &id;
+  }
+
+#if !defined(BOOST_ASIO_NO_TYPEID)
+  // Initialise a service's key based on its id.
+  template <typename Service>
+  void init_key(boost::asio::io_service::service::key& key,
+      const boost::asio::detail::service_id<Service>& /*id*/)
+  {
+    key.type_info_ = &typeid(typeid_wrapper<Service>);
+    key.id_ = 0;
+  }
+#endif // !defined(BOOST_ASIO_NO_TYPEID)
+
+  // Check if a service matches the given id.
+  static bool keys_match(
+      const boost::asio::io_service::service::key& key1,
+      const boost::asio::io_service::service::key& key2)
+  {
+    if (key1.id_ && key2.id_)
+      if (key1.id_ == key2.id_)
+        return true;
+    if (key1.type_info_ && key2.type_info_)
+      if (*key1.type_info_ == *key2.type_info_)
+        return true;
+    return false;
+  }
+
+  // The type of a factory function used for creating a service instance.
+  typedef boost::asio::io_service::service*
+    (*factory_type)(boost::asio::io_service&);
+
+  // Factory function for creating a service instance.
+  template <typename Service>
+  static boost::asio::io_service::service* create(
+      boost::asio::io_service& owner)
+  {
+    return new Service(owner);
+  }
+
+  // Destroy a service instance.
+  static void destroy(boost::asio::io_service::service* service)
+  {
+    delete service;
+  }
+
+  // Helper class to manage service pointers.
+  struct auto_service_ptr
+  {
+    boost::asio::io_service::service* ptr_;
+    ~auto_service_ptr() { destroy(ptr_); }
+  };
+
+  // Get the service object corresponding to the specified service key. Will
+  // create a new service object automatically if no such object already
+  // exists. Ownership of the service object is not transferred to the caller.
+  boost::asio::io_service::service* do_use_service(
+      const boost::asio::io_service::service::key& key,
+      factory_type factory)
+  {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    // First see if there is an existing service object for the given type.
+    // First see if there is an existing service object with the given key.
     boost::asio::io_service::service* service = first_service_;
     while (service)
     {
-      if (service_id_matches(*service, Service::id))
-        return *static_cast<Service*>(service);
+      if (keys_match(service->key_, key))
+        return service;
       service = service->next_;
     }
 
@@ -106,9 +196,8 @@
     // at this time to allow for nested calls into this function from the new
     // service's constructor.
     lock.unlock();
-    std::auto_ptr<Service> new_service(new Service(owner_));
-    init_service_id(*new_service, Service::id);
-    Service& new_service_ref = *new_service;
+    auto_service_ptr new_service = { factory(owner_) };
+    new_service.ptr_->key_ = key;
     lock.lock();
 
     // Check that nobody else created another service object of the same type
@@ -116,52 +205,52 @@
     service = first_service_;
     while (service)
     {
-      if (service_id_matches(*service, Service::id))
-        return *static_cast<Service*>(service);
+      if (keys_match(service->key_, key))
+        return service;
       service = service->next_;
     }
 
     // Service was successfully initialised, pass ownership to registry.
-    new_service->next_ = first_service_;
-    first_service_ = new_service.release();
-
-    return new_service_ref;
+    new_service.ptr_->next_ = first_service_;
+    first_service_ = new_service.ptr_;
+    new_service.ptr_ = 0;
+    return first_service_;
   }
 
   // Add a service object. Returns false on error, in which case ownership of
   // the object is retained by the caller.
-  template <typename Service>
-  bool add_service(Service* new_service)
+  bool do_add_service(
+      const boost::asio::io_service::service::key& key,
+      boost::asio::io_service::service* new_service)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    // Check if there is an existing service object for the given type.
+    // Check if there is an existing service object with the given key.
     boost::asio::io_service::service* service = first_service_;
     while (service)
     {
-      if (service_id_matches(*service, Service::id))
+      if (keys_match(service->key_, key))
         return false;
       service = service->next_;
     }
 
     // Take ownership of the service object.
-    init_service_id(*new_service, Service::id);
+    new_service->key_ = key;
     new_service->next_ = first_service_;
     first_service_ = new_service;
 
     return true;
   }
 
-  // Check whether a service object of the specified type already exists.
-  template <typename Service>
-  bool has_service() const
+  // Check whether a service object with the specified key already exists.
+  bool do_has_service(const boost::asio::io_service::service::key& key) const
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     boost::asio::io_service::service* service = first_service_;
     while (service)
     {
-      if (service_id_matches(*service, Service::id))
+      if (keys_match(service->key_, key))
         return true;
       service = service->next_;
     }
@@ -169,46 +258,6 @@
     return false;
   }
 
-private:
-  // Set a service's id.
-  void init_service_id(boost::asio::io_service::service& service,
-      const boost::asio::io_service::id& id)
-  {
-    service.type_info_ = 0;
-    service.id_ = &id;
-  }
-
-#if !defined(BOOST_ASIO_NO_TYPEID)
-  // Set a service's id.
-  template <typename Service>
-  void init_service_id(boost::asio::io_service::service& service,
-      const boost::asio::detail::service_id<Service>& /*id*/)
-  {
-    service.type_info_ = &typeid(typeid_wrapper<Service>);
-    service.id_ = 0;
-  }
-#endif // !defined(BOOST_ASIO_NO_TYPEID)
-
-  // Check if a service matches the given id.
-  static bool service_id_matches(
-      const boost::asio::io_service::service& service,
-      const boost::asio::io_service::id& id)
-  {
-    return service.id_ == &id;
-  }
-
-#if !defined(BOOST_ASIO_NO_TYPEID)
-  // Check if a service matches the given id.
-  template <typename Service>
-  static bool service_id_matches(
-      const boost::asio::io_service::service& service,
-      const boost::asio::detail::service_id<Service>& /*id*/)
-  {
-    return service.type_info_ != 0
-      && *service.type_info_ == typeid(typeid_wrapper<Service>);
-  }
-#endif // !defined(BOOST_ASIO_NO_TYPEID)
-
   // Mutex to protect access to internal data.
   mutable boost::asio::detail::mutex mutex_;
 
Added: trunk/boost/asio/detail/solaris_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/solaris_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,59 @@
+//
+// solaris_fenced_block.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_SOLARIS_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(__sun)
+
+#include <boost/asio/detail/push_options.hpp>
+#include <atomic.h>
+#include <boost/asio/detail/pop_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class solaris_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  solaris_fenced_block()
+  {
+    membar_consumer();
+  }
+
+  // Destructor.
+  ~solaris_fenced_block()
+  {
+    membar_producer();
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(__sun)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_SOLARIS_FENCED_BLOCK_HPP
Modified: trunk/boost/asio/detail/strand_service.hpp
==============================================================================
--- trunk/boost/asio/detail/strand_service.hpp	(original)
+++ trunk/boost/asio/detail/strand_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -18,19 +18,19 @@
 #include <boost/asio/detail/push_options.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/aligned_storage.hpp>
-#include <boost/assert.hpp>
 #include <boost/functional/hash.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/call_stack.hpp>
+#include <boost/asio/detail/completion_handler.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 #include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/operation.hpp>
 #include <boost/asio/detail/service_base.hpp>
 
 namespace boost {
@@ -41,252 +41,45 @@
 class strand_service
   : public boost::asio::detail::service_base<strand_service>
 {
+private:
+  struct on_do_complete_exit;
+  struct on_dispatch_exit;
+
 public:
-  class handler_base;
-  class invoke_current_handler;
-  class post_next_waiter_on_exit;
 
   // The underlying implementation of a strand.
   class strand_impl
+    : public operation
   {
   public:
     strand_impl()
-      : current_handler_(0),
-        first_waiter_(0),
-        last_waiter_(0)
+      : operation(&strand_service::do_complete),
+        count_(0)
     {
     }
 
   private:
     // Only this service will have access to the internal values.
     friend class strand_service;
-    friend class post_next_waiter_on_exit;
-    friend class invoke_current_handler;
+    friend struct on_do_complete_exit;
+    friend struct on_dispatch_exit;
 
     // Mutex to protect access to internal data.
     boost::asio::detail::mutex mutex_;
 
-    // The handler that is ready to execute. If this pointer is non-null then it
-    // indicates that a handler holds the lock.
-    handler_base* current_handler_;
-
-    // The start of the list of waiting handlers for the strand.
-    handler_base* first_waiter_;
-    
-    // The end of the list of waiting handlers for the strand.
-    handler_base* last_waiter_;
-
-    // Storage for posted handlers.
-    typedef boost::aligned_storage<128> handler_storage_type;
-#if defined(__BORLANDC__)
-    boost::aligned_storage<128> handler_storage_;
-#else
-    handler_storage_type handler_storage_;
-#endif
-  };
-
-  friend class strand_impl;
-
-  typedef strand_impl* implementation_type;
-
-  // Base class for all handler types.
-  class handler_base
-  {
-  public:
-    typedef void (*invoke_func_type)(handler_base*,
-        strand_service&, implementation_type&);
-    typedef void (*destroy_func_type)(handler_base*);
-
-    handler_base(invoke_func_type invoke_func, destroy_func_type destroy_func)
-      : next_(0),
-        invoke_func_(invoke_func),
-        destroy_func_(destroy_func)
-    {
-    }
-
-    void invoke(strand_service& service_impl, implementation_type& impl)
-    {
-      invoke_func_(this, service_impl, impl);
-    }
-
-    void destroy()
-    {
-      destroy_func_(this);
-    }
-
-  protected:
-    ~handler_base()
-    {
-    }
-
-  private:
-    friend class strand_service;
-    friend class strand_impl;
-    friend class post_next_waiter_on_exit;
-    handler_base* next_;
-    invoke_func_type invoke_func_;
-    destroy_func_type destroy_func_;
-  };
-
-  // Helper class to allow handlers to be dispatched.
-  class invoke_current_handler
-  {
-  public:
-    invoke_current_handler(strand_service& service_impl,
-        const implementation_type& impl)
-      : service_impl_(service_impl),
-        impl_(impl)
-    {
-    }
-
-    void operator()()
-    {
-      impl_->current_handler_->invoke(service_impl_, impl_);
-    }
-
-    friend void* asio_handler_allocate(std::size_t size,
-        invoke_current_handler* this_handler)
-    {
-      return this_handler->do_handler_allocate(size);
-    }
-
-    friend void asio_handler_deallocate(void*, std::size_t,
-        invoke_current_handler*)
-    {
-    }
-
-    void* do_handler_allocate(std::size_t size)
-    {
-#if defined(__BORLANDC__)
-      BOOST_ASSERT(size <= boost::aligned_storage<128>::size);
-#else
-      BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
-#endif
-      (void)size;
-      return impl_->handler_storage_.address();
-    }
-
-    // The asio_handler_invoke hook is not defined here since the default one
-    // provides the correct behaviour, and including it here breaks MSVC 7.1
-    // in some situations.
-
-  private:
-    strand_service& service_impl_;
-    implementation_type impl_;
-  };
-
-  // Helper class to automatically enqueue next waiter on block exit.
-  class post_next_waiter_on_exit
-  {
-  public:
-    post_next_waiter_on_exit(strand_service& service_impl,
-        implementation_type& impl)
-      : service_impl_(service_impl),
-        impl_(impl),
-        cancelled_(false)
-    {
-    }
-
-    ~post_next_waiter_on_exit()
-    {
-      if (!cancelled_)
-      {
-        boost::asio::detail::mutex::scoped_lock lock(impl_->mutex_);
-        impl_->current_handler_ = impl_->first_waiter_;
-        if (impl_->current_handler_)
-        {
-          impl_->first_waiter_ = impl_->first_waiter_->next_;
-          if (impl_->first_waiter_ == 0)
-            impl_->last_waiter_ = 0;
-          lock.unlock();
-          service_impl_.get_io_service().post(
-              invoke_current_handler(service_impl_, impl_));
-        }
-      }
-    }
-
-    void cancel()
-    {
-      cancelled_ = true;
-    }
+    // The count of handlers in the strand, including the upcall (if any).
+    std::size_t count_;
 
-  private:
-    strand_service& service_impl_;
-    implementation_type& impl_;
-    bool cancelled_;
+    // The handlers waiting on the strand.
+    op_queue<operation> queue_;
   };
 
-  // Class template for a waiter.
-  template <typename Handler>
-  class handler_wrapper
-    : public handler_base
-  {
-  public:
-    handler_wrapper(Handler handler)
-      : handler_base(&handler_wrapper<Handler>::do_invoke,
-          &handler_wrapper<Handler>::do_destroy),
-        handler_(handler)
-    {
-    }
-
-    static void do_invoke(handler_base* base,
-        strand_service& service_impl, implementation_type& impl)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      post_next_waiter_on_exit p1(service_impl, impl);
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(h->handler_);
-
-      // A handler object must still be valid when the next waiter is posted
-      // since destroying the last handler might cause the strand object to be
-      // destroyed. Therefore we create a second post_next_waiter_on_exit object
-      // that will be destroyed before the handler object.
-      p1.cancel();
-      post_next_waiter_on_exit p2(service_impl, impl);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Indicate that this strand is executing on the current thread.
-      call_stack<strand_impl>::context ctx(impl);
-
-      // Make the upcall.
-      boost_asio_handler_invoke_helpers::invoke(handler, handler);
-    }
-
-    static void do_destroy(handler_base* base)
-    {
-      // Take ownership of the handler object.
-      typedef handler_wrapper<Handler> this_type;
-      this_type* h(static_cast<this_type*>(base));
-      typedef handler_alloc_traits<Handler, this_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(h->handler_, h);
-
-      // 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(h->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-    }
-
-  private:
-    Handler handler_;
-  };
+  typedef strand_impl* implementation_type;
 
   // Construct a new strand service for the specified io_service.
   explicit strand_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<strand_service>(io_service),
+      io_service_(boost::asio::use_service<io_service_impl>(io_service)),
       mutex_(),
       salt_(0)
   {
@@ -295,37 +88,13 @@
   // Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
-    // Construct a list of all handlers to be destroyed.
+    op_queue<operation> ops;
+
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
-    handler_base* first_handler = 0;
+
     for (std::size_t i = 0; i < num_implementations; ++i)
-    {
       if (strand_impl* impl = implementations_[i].get())
-      {
-        if (impl->current_handler_)
-        {
-          impl->current_handler_->next_ = first_handler;
-          first_handler = impl->current_handler_;
-          impl->current_handler_ = 0;
-        }
-        if (impl->first_waiter_)
-        {
-          impl->last_waiter_->next_ = first_handler;
-          first_handler = impl->first_waiter_;
-          impl->first_waiter_ = 0;
-          impl->last_waiter_ = 0;
-        }
-      }
-    }
-
-    // Destroy all handlers without holding the lock.
-    lock.unlock();
-    while (first_handler)
-    {
-      handler_base* next = first_handler->next_;
-      first_handler->destroy();
-      first_handler = next;
-    }
+        ops.push(impl->queue_);
   }
 
   // Construct a new strand implementation.
@@ -352,45 +121,54 @@
   template <typename Handler>
   void dispatch(implementation_type& impl, Handler handler)
   {
+    // If we are already in the strand then the handler can run immediately.
     if (call_stack<strand_impl>::contains(impl))
     {
+      boost::asio::detail::fenced_block b;
       boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      return;
     }
-    else
+
+    // Allocate and construct an object to wrap the handler.
+    typedef completion_handler<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    // If we are running inside the io_service, and no other handler is queued
+    // or running, then the handler can run immediately.
+    bool can_dispatch = call_stack<io_service_impl>::contains(&io_service_);
+    impl->mutex_.lock();
+    bool first = (++impl->count_ == 1);
+    if (can_dispatch && first)
     {
-      // Allocate and construct an object to wrap the handler.
-      typedef handler_wrapper<Handler> value_type;
-      typedef handler_alloc_traits<Handler, value_type> alloc_traits;
-      raw_handler_ptr<alloc_traits> raw_ptr(handler);
-      handler_ptr<alloc_traits> ptr(raw_ptr, handler);
-
-      boost::asio::detail::mutex::scoped_lock lock(impl->mutex_);
-
-      if (impl->current_handler_ == 0)
-      {
-        // This handler now has the lock, so can be dispatched immediately.
-        impl->current_handler_ = ptr.release();
-        lock.unlock();
-        this->get_io_service().dispatch(invoke_current_handler(*this, impl));
-      }
-      else
-      {
-        // Another handler already holds the lock, so this handler must join
-        // the list of waiters. The handler will be posted automatically when
-        // its turn comes.
-        if (impl->last_waiter_)
-        {
-          impl->last_waiter_->next_ = ptr.get();
-          impl->last_waiter_ = impl->last_waiter_->next_;
-        }
-        else
-        {
-          impl->first_waiter_ = ptr.get();
-          impl->last_waiter_ = ptr.get();
-        }
-        ptr.release();
-      }
+      // Immediate invocation is allowed.
+      impl->mutex_.unlock();
+
+      // Memory must be releaesed before any upcall is made.
+      ptr.reset();
+
+      // Indicate that this strand is executing on the current thread.
+      call_stack<strand_impl>::context ctx(impl);
+
+      // Ensure the next handler, if any, is scheduled on block exit.
+      on_dispatch_exit on_exit = { &io_service_, impl };
+      (void)on_exit;
+
+      boost::asio::detail::fenced_block b;
+      boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      return;
     }
+
+    // Immediate invocation is not allowed, so enqueue for later.
+    impl->queue_.push(ptr.get());
+    impl->mutex_.unlock();
+    ptr.release();
+
+    // The first handler to be enqueued is responsible for scheduling the
+    // strand.
+    if (first)
+      io_service_.post_immediate_completion(impl);
   }
 
   // Request the io_service to invoke the given handler and return immediately.
@@ -398,40 +176,85 @@
   void post(implementation_type& impl, Handler handler)
   {
     // Allocate and construct an object to wrap the handler.
-    typedef handler_wrapper<Handler> value_type;
+    typedef completion_handler<Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
     handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-    boost::asio::detail::mutex::scoped_lock lock(impl->mutex_);
+    // Add the handler to the queue.
+    impl->mutex_.lock();
+    bool first = (++impl->count_ == 1);
+    impl->queue_.push(ptr.get());
+    impl->mutex_.unlock();
+    ptr.release();
+
+    // The first handler to be enqueue is responsible for scheduling the strand.
+    if (first)
+      io_service_.post_immediate_completion(impl);
+  }
+
+private:
+  static void do_complete(io_service_impl* owner, operation* base,
+      boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+  {
+    if (owner)
+    {
+      strand_impl* impl = static_cast<strand_impl*>(base);
+
+      // Get the next handler to be executed.
+      impl->mutex_.lock();
+      operation* o = impl->queue_.front();
+      impl->queue_.pop();
+      impl->mutex_.unlock();
+
+      // Indicate that this strand is executing on the current thread.
+      call_stack<strand_impl>::context ctx(impl);
+
+      // Ensure the next handler, if any, is scheduled on block exit.
+      on_do_complete_exit on_exit = { owner, impl };
+      (void)on_exit;
+
+      o->complete(*owner);
+    }
+  }
+
+  // Helper class to re-post the strand on exit.
+  struct on_do_complete_exit
+  {
+    io_service_impl* owner_;
+    strand_impl* impl_;
 
-    if (impl->current_handler_ == 0)
+    ~on_do_complete_exit()
     {
-      // This handler now has the lock, so can be dispatched immediately.
-      impl->current_handler_ = ptr.release();
-      lock.unlock();
-      this->get_io_service().post(invoke_current_handler(*this, impl));
+      impl_->mutex_.lock();
+      bool more_handlers = (--impl_->count_ > 0);
+      impl_->mutex_.unlock();
+
+      if (more_handlers)
+        owner_->post_immediate_completion(impl_);
     }
-    else
+  };
+
+  // Helper class to re-post the strand on exit.
+  struct on_dispatch_exit
+  {
+    io_service_impl* io_service_;
+    strand_impl* impl_;
+
+    ~on_dispatch_exit()
     {
-      // Another handler already holds the lock, so this handler must join the
-      // list of waiters. The handler will be posted automatically when its turn
-      // comes.
-      if (impl->last_waiter_)
-      {
-        impl->last_waiter_->next_ = ptr.get();
-        impl->last_waiter_ = impl->last_waiter_->next_;
-      }
-      else
-      {
-        impl->first_waiter_ = ptr.get();
-        impl->last_waiter_ = ptr.get();
-      }
-      ptr.release();
+      impl_->mutex_.lock();
+      bool more_handlers = (--impl_->count_ > 0);
+      impl_->mutex_.unlock();
+
+      if (more_handlers)
+        io_service_->post_immediate_completion(impl_);
     }
-  }
+  };
+
+  // The io_service implementation used to post completions.
+  io_service_impl& io_service_;
 
-private:
   // Mutex to protect access to the array of implementations.
   boost::asio::detail::mutex mutex_;
 
Modified: trunk/boost/asio/detail/task_io_service.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service.hpp	(original)
+++ trunk/boost/asio/detail/task_io_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -15,21 +15,25 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#if defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
-#include <boost/asio/detail/task_io_service_2lock.hpp>
-#else // defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
-
 #include <boost/asio/detail/push_options.hpp>
 
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/call_stack.hpp>
+#include <boost/asio/detail/completion_handler.hpp>
 #include <boost/asio/detail/event.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/handler_queue.hpp>
 #include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/detail/task_io_service_fwd.hpp>
+#include <boost/asio/detail/task_io_service_operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/detail/atomic_count.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -40,6 +44,8 @@
   : public boost::asio::detail::service_base<task_io_service<Task> >
 {
 public:
+  typedef task_io_service_operation<Task> operation;
+
   // Constructor.
   task_io_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<task_io_service<Task> >(io_service),
@@ -65,12 +71,12 @@
     lock.unlock();
 
     // Destroy handler objects.
-    while (!handler_queue_.empty())
+    while (!op_queue_.empty())
     {
-      handler_queue::handler* h = handler_queue_.front();
-      handler_queue_.pop();
-      if (h != &task_handler_)
-        h->destroy();
+      operation* o = op_queue_.front();
+      op_queue_.pop();
+      if (o != &task_operation_)
+        o->destroy();
     }
 
     // Reset to initial state.
@@ -84,14 +90,21 @@
     if (!shutdown_ && !task_)
     {
       task_ = &use_service<Task>(this->get_io_service());
-      handler_queue_.push(&task_handler_);
-      interrupt_one_idle_thread(lock);
+      op_queue_.push(&task_operation_);
+      wake_one_thread_and_unlock(lock);
     }
   }
 
   // Run the event loop until interrupted or no more work.
   size_t run(boost::system::error_code& ec)
   {
+    ec = boost::system::error_code();
+    if (outstanding_work_ == 0)
+    {
+      stop();
+      return 0;
+    }
+
     typename call_stack<task_io_service>::context ctx(this);
 
     idle_thread_info this_idle_thread;
@@ -100,7 +113,7 @@
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     size_t n = 0;
-    while (do_one(lock, &this_idle_thread, ec))
+    for (; do_one(lock, &this_idle_thread); lock.lock())
       if (n != (std::numeric_limits<size_t>::max)())
         ++n;
     return n;
@@ -109,6 +122,13 @@
   // Run until interrupted or one operation is performed.
   size_t run_one(boost::system::error_code& ec)
   {
+    ec = boost::system::error_code();
+    if (outstanding_work_ == 0)
+    {
+      stop();
+      return 0;
+    }
+
     typename call_stack<task_io_service>::context ctx(this);
 
     idle_thread_info this_idle_thread;
@@ -116,18 +136,25 @@
 
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    return do_one(lock, &this_idle_thread, ec);
+    return do_one(lock, &this_idle_thread);
   }
 
   // Poll for operations without blocking.
   size_t poll(boost::system::error_code& ec)
   {
+    if (outstanding_work_ == 0)
+    {
+      stop();
+      ec = boost::system::error_code();
+      return 0;
+    }
+
     typename call_stack<task_io_service>::context ctx(this);
 
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     size_t n = 0;
-    while (do_one(lock, 0, ec))
+    for (; do_one(lock, 0); lock.lock())
       if (n != (std::numeric_limits<size_t>::max)())
         ++n;
     return n;
@@ -136,11 +163,18 @@
   // Poll for one operation without blocking.
   size_t poll_one(boost::system::error_code& ec)
   {
+    ec = boost::system::error_code();
+    if (outstanding_work_ == 0)
+    {
+      stop();
+      return 0;
+    }
+
     typename call_stack<task_io_service>::context ctx(this);
 
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
-    return do_one(lock, 0, ec);
+    return do_one(lock, 0);
   }
 
   // Interrupt the event processing loop.
@@ -160,16 +194,14 @@
   // Notify that some work has started.
   void work_started()
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     ++outstanding_work_;
   }
 
   // Notify that some work has finished.
   void work_finished()
   {
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (--outstanding_work_ == 0)
-      stop_all_threads(lock);
+      stop();
   }
 
   // Request invocation of the given handler.
@@ -177,7 +209,10 @@
   void dispatch(Handler handler)
   {
     if (call_stack<task_io_service>::contains(this))
+    {
+      boost::asio::detail::fenced_block b;
       boost_asio_handler_invoke_helpers::invoke(handler, handler);
+    }
     else
       post(handler);
   }
@@ -187,29 +222,41 @@
   void post(Handler handler)
   {
     // Allocate and construct an operation to wrap the handler.
-    handler_queue::scoped_ptr ptr(handler_queue::wrap(handler));
-
-    boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
-    // If the service has been shut down we silently discard the handler.
-    if (shutdown_)
-      return;
+    typedef completion_handler<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-    // Add the handler to the end of the queue.
-    handler_queue_.push(ptr.get());
+    post_immediate_completion(ptr.get());
     ptr.release();
+  }
 
-    // An undelivered handler is treated as unfinished work.
-    ++outstanding_work_;
+  // Request invocation of the given operation and return immediately. Assumes
+  // that work_started() has not yet been called for the operation.
+  void post_immediate_completion(operation* op)
+  {
+    work_started();
+    post_deferred_completion(op);
+  }
+
+  // Request invocation of the given operation and return immediately. Assumes
+  // that work_started() was previously called for the operation.
+  void post_deferred_completion(operation* op)
+  {
+    boost::asio::detail::mutex::scoped_lock lock(mutex_);
+    op_queue_.push(op);
+    wake_one_thread_and_unlock(lock);
+  }
 
-    // Wake up a thread to execute the handler.
-    if (!interrupt_one_idle_thread(lock))
+  // Request invocation of the given operations and return immediately. Assumes
+  // that work_started() was previously called for each operation.
+  void post_deferred_completions(op_queue<operation>& ops)
+  {
+    if (!ops.empty())
     {
-      if (!task_interrupted_ && task_)
-      {
-        task_interrupted_ = true;
-        task_->interrupt();
-      }
+      boost::asio::detail::mutex::scoped_lock lock(mutex_);
+      op_queue_.push(ops);
+      wake_one_thread_and_unlock(lock);
     }
   }
 
@@ -217,57 +264,60 @@
   struct idle_thread_info;
 
   size_t do_one(boost::asio::detail::mutex::scoped_lock& lock,
-      idle_thread_info* this_idle_thread, boost::system::error_code& ec)
+      idle_thread_info* this_idle_thread)
   {
-    if (outstanding_work_ == 0 && !stopped_)
-    {
-      stop_all_threads(lock);
-      ec = boost::system::error_code();
-      return 0;
-    }
-
     bool polling = !this_idle_thread;
     bool task_has_run = false;
     while (!stopped_)
     {
-      if (!handler_queue_.empty())
+      if (!op_queue_.empty())
       {
         // Prepare to execute first handler from queue.
-        handler_queue::handler* h = handler_queue_.front();
-        handler_queue_.pop();
+        operation* o = op_queue_.front();
+        op_queue_.pop();
+        bool more_handlers = (!op_queue_.empty());
 
-        if (h == &task_handler_)
+        if (o == &task_operation_)
         {
-          bool more_handlers = (!handler_queue_.empty());
           task_interrupted_ = more_handlers || polling;
 
           // If the task has already run and we're polling then we're done.
           if (task_has_run && polling)
           {
             task_interrupted_ = true;
-            handler_queue_.push(&task_handler_);
-            ec = boost::system::error_code();
+            op_queue_.push(&task_operation_);
             return 0;
           }
           task_has_run = true;
 
-          lock.unlock();
-          task_cleanup c(lock, *this);
-
-          // Run the task. May throw an exception. Only block if the handler
-          // queue is empty and we have an idle_thread_info object, otherwise
-          // we want to return as soon as possible.
-          task_->run(!more_handlers && !polling);
+          if (more_handlers)
+            wake_one_idle_thread_and_unlock(lock);
+          else
+            lock.unlock();
+
+          op_queue<operation> completed_ops;
+          task_cleanup c = { this, &lock, &completed_ops };
+          (void)c;
+
+          // Run the task. May throw an exception. Only block if the operation
+          // queue is empty and we're not polling, otherwise we want to return
+          // as soon as possible.
+          task_->run(!more_handlers && !polling, completed_ops);
         }
         else
         {
-          lock.unlock();
-          handler_cleanup c(lock, *this);
+          if (more_handlers)
+            wake_one_thread_and_unlock(lock);
+          else
+            lock.unlock();
+
+          // Ensure the count of outstanding work is decremented on block exit.
+          work_finished_on_block_exit on_exit = { this };
+          (void)on_exit;
 
-          // Invoke the handler. May throw an exception.
-          h->invoke(); // invoke() deletes the handler object
+          // Complete the operation. May throw an exception.
+          o->complete(*this); // deletes the operation object
 
-          ec = boost::system::error_code();
           return 1;
         }
       }
@@ -281,12 +331,10 @@
       }
       else
       {
-        ec = boost::system::error_code();
         return 0;
       }
     }
 
-    ec = boost::system::error_code();
     return 0;
   }
 
@@ -295,7 +343,15 @@
       boost::asio::detail::mutex::scoped_lock& lock)
   {
     stopped_ = true;
-    interrupt_all_idle_threads(lock);
+
+    while (first_idle_thread_)
+    {
+      idle_thread_info* idle_thread = first_idle_thread_;
+      first_idle_thread_ = idle_thread->next;
+      idle_thread->next = 0;
+      idle_thread->wakeup_event.signal(lock);
+    }
+
     if (!task_interrupted_ && task_)
     {
       task_interrupted_ = true;
@@ -303,9 +359,10 @@
     }
   }
 
-  // Interrupt a single idle thread. Returns true if a thread was interrupted,
-  // false if no running thread could be found to interrupt.
-  bool interrupt_one_idle_thread(
+  // Wakes a single idle thread and unlocks the mutex. Returns true if an idle
+  // thread was found. If there is no idle thread, returns false and leaves the
+  // mutex locked.
+  bool wake_one_idle_thread_and_unlock(
       boost::asio::detail::mutex::scoped_lock& lock)
   {
     if (first_idle_thread_)
@@ -313,74 +370,56 @@
       idle_thread_info* idle_thread = first_idle_thread_;
       first_idle_thread_ = idle_thread->next;
       idle_thread->next = 0;
-      idle_thread->wakeup_event.signal(lock);
+      idle_thread->wakeup_event.signal_and_unlock(lock);
       return true;
     }
     return false;
   }
 
-  // Interrupt all idle threads.
-  void interrupt_all_idle_threads(
+  // Wake a single idle thread, or the task, and always unlock the mutex.
+  void wake_one_thread_and_unlock(
       boost::asio::detail::mutex::scoped_lock& lock)
   {
-    while (first_idle_thread_)
+    if (!wake_one_idle_thread_and_unlock(lock))
     {
-      idle_thread_info* idle_thread = first_idle_thread_;
-      first_idle_thread_ = idle_thread->next;
-      idle_thread->next = 0;
-      idle_thread->wakeup_event.signal(lock);
+      if (!task_interrupted_ && task_)
+      {
+        task_interrupted_ = true;
+        task_->interrupt();
+      }
+      lock.unlock();
     }
   }
 
   // Helper class to perform task-related operations on block exit.
-  class task_cleanup;
-  friend class task_cleanup;
-  class task_cleanup
-  {
-  public:
-    task_cleanup(boost::asio::detail::mutex::scoped_lock& lock,
-        task_io_service& task_io_svc)
-      : lock_(lock),
-        task_io_service_(task_io_svc)
-    {
-    }
-
+  struct task_cleanup;
+  friend struct task_cleanup;
+  struct task_cleanup
+  {
     ~task_cleanup()
     {
-      // Reinsert the task at the end of the handler queue.
-      lock_.lock();
-      task_io_service_.task_interrupted_ = true;
-      task_io_service_.handler_queue_.push(&task_io_service_.task_handler_);
+      // Enqueue the completed operations and reinsert the task at the end of
+      // the operation queue.
+      lock_->lock();
+      task_io_service_->task_interrupted_ = true;
+      task_io_service_->op_queue_.push(*ops_);
+      task_io_service_->op_queue_.push(&task_io_service_->task_operation_);
     }
 
-  private:
-    boost::asio::detail::mutex::scoped_lock& lock_;
-    task_io_service& task_io_service_;
+    task_io_service* task_io_service_;
+    boost::asio::detail::mutex::scoped_lock* lock_;
+    op_queue<operation>* ops_;
   };
 
-  // Helper class to perform handler-related operations on block exit.
-  class handler_cleanup;
-  friend class handler_cleanup;
-  class handler_cleanup
+  // Helper class to call work_finished() on block exit.
+  struct work_finished_on_block_exit
   {
-  public:
-    handler_cleanup(boost::asio::detail::mutex::scoped_lock& lock,
-        task_io_service& task_io_svc)
-      : lock_(lock),
-        task_io_service_(task_io_svc)
-    {
-    }
-
-    ~handler_cleanup()
+    ~work_finished_on_block_exit()
     {
-      lock_.lock();
-      if (--task_io_service_.outstanding_work_ == 0)
-        task_io_service_.stop_all_threads(lock_);
+      task_io_service_->work_finished();
     }
 
-  private:
-    boost::asio::detail::mutex::scoped_lock& lock_;
-    task_io_service& task_io_service_;
+    task_io_service* task_io_service_;
   };
 
   // Mutex to protect access to internal data.
@@ -389,25 +428,20 @@
   // The task to be run by this service.
   Task* task_;
 
-  // Handler object to represent the position of the task in the queue.
-  class task_handler
-    : public handler_queue::handler
+  // Operation object to represent the position of the task in the queue.
+  struct task_operation : public operation
   {
-  public:
-    task_handler()
-      : handler_queue::handler(0, 0)
-    {
-    }
-  } task_handler_;
+    task_operation() : operation(0) {}
+  } task_operation_;
 
   // Whether the task has been interrupted.
   bool task_interrupted_;
 
   // The count of unfinished work.
-  int outstanding_work_;
+  boost::detail::atomic_count outstanding_work_;
 
   // The queue of handlers that are ready to be delivered.
-  handler_queue handler_queue_;
+  op_queue<operation> op_queue_;
 
   // Flag to indicate that the dispatcher has been stopped.
   bool stopped_;
@@ -422,7 +456,7 @@
     idle_thread_info* next;
   };
 
-  // The number of threads that are currently idle.
+  // The threads that are currently idle.
   idle_thread_info* first_idle_thread_;
 };
 
@@ -430,9 +464,6 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/system/error_code.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
-#endif // defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
-
 #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP
Deleted: trunk/boost/asio/detail/task_io_service_2lock.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service_2lock.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
+++ (empty file)
@@ -1,475 +0,0 @@
-//
-// task_io_service_2lock.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_TASK_IO_SERVICE_2LOCK_HPP
-#define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_2LOCK_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/call_stack.hpp>
-#include <boost/asio/detail/event.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/indirect_handler_queue.hpp>
-#include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/task_io_service_fwd.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/detail/atomic_count.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-// An alternative task_io_service implementation based on a two-lock queue.
-
-template <typename Task>
-class task_io_service
-  : public boost::asio::detail::service_base<task_io_service<Task> >
-{
-public:
-  typedef indirect_handler_queue handler_queue;
-
-  // Constructor.
-  task_io_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<task_io_service<Task> >(io_service),
-      front_mutex_(),
-      back_mutex_(),
-      task_(0),
-      outstanding_work_(0),
-      front_stopped_(false),
-      back_stopped_(false),
-      back_shutdown_(false),
-      back_first_idle_thread_(0),
-      back_task_thread_(0)
-  {
-  }
-
-  void init(size_t /*concurrency_hint*/)
-  {
-  }
-
-  // Destroy all user-defined handler objects owned by the service.
-  void shutdown_service()
-  {
-    boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-    back_shutdown_ = true;
-    back_lock.unlock();
-
-    // Destroy handler objects.
-    while (handler_queue::handler* h = handler_queue_.pop())
-      if (h != &task_handler_)
-        h->destroy();
-
-    // Reset to initial state.
-    task_ = 0;
-  }
-
-  // Initialise the task, if required.
-  void init_task()
-  {
-    boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-    if (!back_shutdown_ && !task_)
-    {
-      task_ = &use_service<Task>(this->get_io_service());
-      handler_queue_.push(&task_handler_);
-      interrupt_one_idle_thread(back_lock);
-    }
-  }
-
-  // Run the event loop until interrupted or no more work.
-  size_t run(boost::system::error_code& ec)
-  {
-    if (outstanding_work_ == 0)
-    {
-      stop();
-      ec = boost::system::error_code();
-      return 0;
-    }
-
-    typename call_stack<task_io_service>::context ctx(this);
-
-    idle_thread_info this_idle_thread;
-    this_idle_thread.next = 0;
-
-    size_t n = 0;
-    while (do_one(&this_idle_thread, ec))
-      if (n != (std::numeric_limits<size_t>::max)())
-        ++n;
-    return n;
-  }
-
-  // Run until interrupted or one operation is performed.
-  size_t run_one(boost::system::error_code& ec)
-  {
-    if (outstanding_work_ == 0)
-    {
-      stop();
-      ec = boost::system::error_code();
-      return 0;
-    }
-
-    typename call_stack<task_io_service>::context ctx(this);
-
-    idle_thread_info this_idle_thread;
-    this_idle_thread.next = 0;
-
-    return do_one(&this_idle_thread, ec);
-  }
-
-  // Poll for operations without blocking.
-  size_t poll(boost::system::error_code& ec)
-  {
-    if (outstanding_work_ == 0)
-    {
-      stop();
-      ec = boost::system::error_code();
-      return 0;
-    }
-
-    typename call_stack<task_io_service>::context ctx(this);
-
-    size_t n = 0;
-    while (do_one(0, ec))
-      if (n != (std::numeric_limits<size_t>::max)())
-        ++n;
-    return n;
-  }
-
-  // Poll for one operation without blocking.
-  size_t poll_one(boost::system::error_code& ec)
-  {
-    if (outstanding_work_ == 0)
-    {
-      stop();
-      ec = boost::system::error_code();
-      return 0;
-    }
-
-    typename call_stack<task_io_service>::context ctx(this);
-
-    return do_one(0, ec);
-  }
-
-  // Interrupt the event processing loop.
-  void stop()
-  {
-    boost::asio::detail::mutex::scoped_lock front_lock(front_mutex_);
-    front_stopped_ = true;
-    front_lock.unlock();
-
-    boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-    back_stopped_ = true;
-    interrupt_all_idle_threads(back_lock);
-  }
-
-  // Reset in preparation for a subsequent run invocation.
-  void reset()
-  {
-    boost::asio::detail::mutex::scoped_lock front_lock(front_mutex_);
-    front_stopped_ = false;
-    front_lock.unlock();
-
-    boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-    back_stopped_ = false;
-  }
-
-  // Notify that some work has started.
-  void work_started()
-  {
-    ++outstanding_work_;
-  }
-
-  // Notify that some work has finished.
-  void work_finished()
-  {
-    if (--outstanding_work_ == 0)
-      stop();
-  }
-
-  // Request invocation of the given handler.
-  template <typename Handler>
-  void dispatch(Handler handler)
-  {
-    if (call_stack<task_io_service>::contains(this))
-      boost_asio_handler_invoke_helpers::invoke(handler, handler);
-    else
-      post(handler);
-  }
-
-  // Request invocation of the given handler and return immediately.
-  template <typename Handler>
-  void post(Handler handler)
-  {
-    // Allocate and construct an operation to wrap the handler.
-    handler_queue::scoped_ptr ptr(handler_queue::wrap(handler));
-
-    boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-
-    // If the service has been shut down we silently discard the handler.
-    if (back_shutdown_)
-      return;
-
-    // Add the handler to the end of the queue.
-    handler_queue_.push(ptr.get());
-    ptr.release();
-
-    // An undelivered handler is treated as unfinished work.
-    ++outstanding_work_;
-
-    // Wake up a thread to execute the handler.
-    interrupt_one_idle_thread(back_lock);
-  }
-
-private:
-  struct idle_thread_info;
-
-  size_t do_one(idle_thread_info* this_idle_thread,
-      boost::system::error_code& ec)
-  {
-    bool task_has_run = false;
-    for (;;)
-    {
-      // The front lock must be held before we can pop items from the queue.
-      boost::asio::detail::mutex::scoped_lock front_lock(front_mutex_);
-      if (front_stopped_)
-      {
-        ec = boost::system::error_code();
-        return 0;
-      }
-
-      if (handler_queue::handler* h = handler_queue_.pop())
-      {
-        if (h == &task_handler_)
-        {
-          bool more_handlers = handler_queue_.poppable();
-          unsigned long front_version = handler_queue_.front_version();
-          front_lock.unlock();
-
-          // The task is always added to the back of the queue when we exit
-          // this block.
-          task_cleanup c(*this);
-
-          // If we're polling and the task has already run then we're done.
-          bool polling = !this_idle_thread;
-          if (task_has_run && polling)
-          {
-            ec = boost::system::error_code();
-            return 0;
-          }
-
-          // If we're considering going idle we need to check whether the queue
-          // is still empty. If it is, add the thread to the list of idle
-          // threads.
-          if (!more_handlers && !polling)
-          {
-            boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-            if (back_stopped_)
-            {
-              ec = boost::system::error_code();
-              return 0;
-            }
-            else if (front_version == handler_queue_.back_version())
-            {
-              back_task_thread_ = this_idle_thread;
-            }
-            else
-            {
-              more_handlers = true;
-            }
-          }
-
-          // Run the task. May throw an exception. Only block if the handler
-          // queue is empty and we're not polling, otherwise we want to return
-          // as soon as possible.
-          task_has_run = true;
-          task_->run(!more_handlers && !polling);
-        }
-        else
-        {
-          front_lock.unlock();
-          handler_cleanup c(*this);
-
-          // Invoke the handler. May throw an exception.
-          h->invoke(); // invoke() deletes the handler object
-
-          ec = boost::system::error_code();
-          return 1;
-        }
-      }
-      else if (this_idle_thread)
-      {
-        unsigned long front_version = handler_queue_.front_version();
-        front_lock.unlock();
-
-        // If we're considering going idle we need to check whether the queue
-        // is still empty. If it is, add the thread to the list of idle
-        // threads.
-        boost::asio::detail::mutex::scoped_lock back_lock(back_mutex_);
-        if (back_stopped_)
-        {
-          ec = boost::system::error_code();
-          return 0;
-        }
-        else if (front_version == handler_queue_.back_version())
-        {
-          this_idle_thread->next = back_first_idle_thread_;
-          back_first_idle_thread_ = this_idle_thread;
-          this_idle_thread->wakeup_event.clear(back_lock);
-          this_idle_thread->wakeup_event.wait(back_lock);
-        }
-      }
-      else
-      {
-        ec = boost::system::error_code();
-        return 0;
-      }
-    }
-  }
-
-  // Interrupt a single idle thread.
-  void interrupt_one_idle_thread(
-      boost::asio::detail::mutex::scoped_lock& back_lock)
-  {
-    if (back_first_idle_thread_)
-    {
-      idle_thread_info* idle_thread = back_first_idle_thread_;
-      back_first_idle_thread_ = idle_thread->next;
-      idle_thread->next = 0;
-      idle_thread->wakeup_event.signal(back_lock);
-    }
-    else if (back_task_thread_ && task_)
-    {
-      back_task_thread_ = 0;
-      task_->interrupt();
-    }
-  }
-
-  // Interrupt all idle threads.
-  void interrupt_all_idle_threads(
-      boost::asio::detail::mutex::scoped_lock& back_lock)
-  {
-    while (back_first_idle_thread_)
-    {
-      idle_thread_info* idle_thread = back_first_idle_thread_;
-      back_first_idle_thread_ = idle_thread->next;
-      idle_thread->next = 0;
-      idle_thread->wakeup_event.signal(back_lock);
-    }
-
-    if (back_task_thread_ && task_)
-    {
-      back_task_thread_ = 0;
-      task_->interrupt();
-    }
-  }
-
-  // Helper class to perform task-related operations on block exit.
-  class task_cleanup;
-  friend class task_cleanup;
-  class task_cleanup
-  {
-  public:
-    task_cleanup(task_io_service& task_io_svc)
-      : task_io_service_(task_io_svc)
-    {
-    }
-
-    ~task_cleanup()
-    {
-      // Reinsert the task at the end of the handler queue.
-      boost::asio::detail::mutex::scoped_lock back_lock(
-          task_io_service_.back_mutex_);
-      task_io_service_.back_task_thread_ = 0;
-      task_io_service_.handler_queue_.push(&task_io_service_.task_handler_);
-    }
-
-  private:
-    task_io_service& task_io_service_;
-  };
-
-  // Helper class to perform handler-related operations on block exit.
-  class handler_cleanup
-  {
-  public:
-    handler_cleanup(task_io_service& task_io_svc)
-      : task_io_service_(task_io_svc)
-    {
-    }
-
-    ~handler_cleanup()
-    {
-      task_io_service_.work_finished();
-    }
-
-  private:
-    task_io_service& task_io_service_;
-  };
-
-  // Mutexes to protect access to internal data.
-  boost::asio::detail::mutex front_mutex_;
-  boost::asio::detail::mutex back_mutex_;
-
-  // The task to be run by this service.
-  Task* task_;
-
-  // Handler object to represent the position of the task in the queue.
-  class task_handler
-    : public handler_queue::handler
-  {
-  public:
-    task_handler()
-      : handler_queue::handler(0, 0)
-    {
-    }
-  } task_handler_;
-
-  // The count of unfinished work.
-  boost::detail::atomic_count outstanding_work_;
-
-  // The queue of handlers that are ready to be delivered.
-  handler_queue handler_queue_;
-
-  // Flag to indicate that the dispatcher has been stopped.
-  bool front_stopped_;
-  bool back_stopped_;
-
-  // Flag to indicate that the dispatcher has been shut down.
-  bool back_shutdown_;
-
-  // Structure containing information about an idle thread.
-  struct idle_thread_info
-  {
-    event wakeup_event;
-    idle_thread_info* next;
-  };
-
-  // The number of threads that are currently idle.
-  idle_thread_info* back_first_idle_thread_;
-
-  // The thread that is currently blocked on the task.
-  idle_thread_info* back_task_thread_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_2LOCK_HPP
Added: trunk/boost/asio/detail/task_io_service_operation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/task_io_service_operation.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,71 @@
+//
+// task_io_service_operation.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_TASK_IO_SERVICE_OPERATION_HPP
+#define BOOST_ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/task_io_service_fwd.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Base class for all operations. A function pointer is used instead of virtual
+// functions to avoid the associated overhead.
+template <typename Task>
+class task_io_service_operation
+{
+public:
+  void complete(task_io_service<Task>& owner)
+  {
+    func_(&owner, this, boost::system::error_code(), 0);
+  }
+
+  void destroy()
+  {
+    func_(0, this, boost::system::error_code(), 0);
+  }
+
+protected:
+  typedef void (*func_type)(task_io_service<Task>*,
+      task_io_service_operation*, boost::system::error_code, std::size_t);
+
+  task_io_service_operation(func_type func)
+    : next_(0),
+      func_(func)
+  {
+  }
+
+  // Prevents deletion through this type.
+  ~task_io_service_operation()
+  {
+  }
+
+private:
+  friend class op_queue_access;
+  task_io_service_operation* next_;
+  func_type func_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_OPERATION_HPP
Added: trunk/boost/asio/detail/timer_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/timer_op.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,46 @@
+//
+// timer_op.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_TIMER_OP_HPP
+#define BOOST_ASIO_DETAIL_TIMER_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/operation.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class timer_op
+  : public operation
+{
+public:
+  // The error code to be passed to the completion handler.
+  boost::system::error_code ec_;
+
+protected:
+  timer_op(func_type func)
+    : operation(func)
+  {
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TIMER_OP_HPP
Modified: trunk/boost/asio/detail/timer_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue.hpp	(original)
+++ trunk/boost/asio/detail/timer_queue.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -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 @@
   // 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)
-    {
-      result.first->second->prev_ = new_timer.get();
-      new_timer.get()->next_ = result.first->second;
-      result.first->second = new_timer.get();
+      timers_.insert(value_type(token, timer()));
+    result.first->second.op_queue_.push(op);
+    if (result.second)
+    {
+      // 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 @@
   }
 
   // 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
-  {
-  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()
+  // Cancel and dequeue the timers with the given token.
+  std::size_t cancel_timer(void* timer_token, 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())
     {
+      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 @@
   // 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 @@
   }
 
   // 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 @@
     }
 
     // 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
Modified: trunk/boost/asio/detail/timer_queue_base.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue_base.hpp	(original)
+++ trunk/boost/asio/detail/timer_queue_base.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -17,13 +17,9 @@
 
 #include <boost/asio/detail/push_options.hpp>
 
-#include <boost/asio/detail/socket_types.hpp> // Must come before posix_time.
-
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/operation.hpp>
 
 namespace boost {
 namespace asio {
@@ -33,6 +29,9 @@
   : private noncopyable
 {
 public:
+  // Constructor.
+  timer_queue_base() : next_(0) {}
+
   // Destructor.
   virtual ~timer_queue_base() {}
 
@@ -40,19 +39,22 @@
   virtual bool empty() const = 0;
 
   // Get the time to wait until the next timer.
-  virtual boost::posix_time::time_duration wait_duration() const = 0;
+  virtual long wait_duration_msec(long max_duration) const = 0;
+
+  // Get the time to wait until the next timer.
+  virtual long wait_duration_usec(long max_duration) const = 0;
 
-  // Dispatch all ready timers.
-  virtual void dispatch_timers() = 0;
+  // Dequeue all ready timers.
+  virtual void get_ready_timers(op_queue<operation>& ops) = 0;
 
-  // Dispatch any pending cancels for timers.
-  virtual void dispatch_cancellations() = 0;
+  // Dequeue all timers.
+  virtual void get_all_timers(op_queue<operation>& ops) = 0;
 
-  // Complete all timers that are waiting to be completed.
-  virtual void complete_timers() = 0;
+private:
+  friend class timer_queue_set;
 
-  // Destroy all timers.
-  virtual void destroy_timers() = 0;
+  // Next timer queue in the set.
+  timer_queue_base* next_;
 };
 
 } // namespace detail
Added: trunk/boost/asio/detail/timer_queue_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/timer_queue_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,33 @@
+//
+// timer_queue_fwd.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_TIMER_QUEUE_FWD_HPP
+#define BOOST_ASIO_DETAIL_TIMER_QUEUE_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+class timer_queue;
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_FWD_HPP
Added: trunk/boost/asio/detail/timer_queue_set.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/timer_queue_set.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,117 @@
+//
+// timer_queue_set.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_TIMER_QUEUE_SET_HPP
+#define BOOST_ASIO_DETAIL_TIMER_QUEUE_SET_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/timer_queue_base.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class timer_queue_set
+{
+public:
+  // Constructor.
+  timer_queue_set()
+    : first_(0)
+  {
+  }
+
+  // Add a timer queue to the set.
+  void insert(timer_queue_base* q)
+  {
+    q->next_ = first_;
+    first_ = q;
+  }
+
+  // Remove a timer queue from the set.
+  void erase(timer_queue_base* q)
+  {
+    if (first_)
+    {
+      if (q == first_)
+      {
+        first_ = q->next_;
+        q->next_ = 0;
+        return;
+      }
+
+      for (timer_queue_base* p = first_; p->next_; p = p->next_)
+      {
+        if (p->next_ == q)
+        {
+          p->next_ = q->next_;
+          q->next_ = 0;
+          return;
+        }
+      }
+    }
+  }
+
+  // Determine whether all queues are empty.
+  bool all_empty() const
+  {
+    for (timer_queue_base* p = first_; p; p = p->next_)
+      if (!p->empty())
+        return false;
+    return true;
+  }
+
+  // Get the wait duration in milliseconds.
+  long wait_duration_msec(long max_duration) const
+  {
+    long min_duration = max_duration;
+    for (timer_queue_base* p = first_; p; p = p->next_)
+      min_duration = p->wait_duration_msec(min_duration);
+    return min_duration;
+  }
+
+  // Get the wait duration in microseconds.
+  long wait_duration_usec(long max_duration) const
+  {
+    long min_duration = max_duration;
+    for (timer_queue_base* p = first_; p; p = p->next_)
+      min_duration = p->wait_duration_usec(min_duration);
+    return min_duration;
+  }
+
+  // Dequeue all ready timers.
+  void get_ready_timers(op_queue<operation>& ops)
+  {
+    for (timer_queue_base* p = first_; p; p = p->next_)
+      p->get_ready_timers(ops);
+  }
+
+  // Dequeue all timers.
+  void get_all_timers(op_queue<operation>& ops)
+  {
+    for (timer_queue_base* p = first_; p; p = p->next_)
+      p->get_all_timers(ops);
+  }
+
+private:
+  timer_queue_base* first_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_SET_HPP
Added: trunk/boost/asio/detail/timer_scheduler.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/timer_scheduler.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,36 @@
+//
+// timer_scheduler.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_TIMER_SCHEDULER_HPP
+#define BOOST_ASIO_DETAIL_TIMER_SCHEDULER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/timer_scheduler_fwd.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_service.hpp>
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+# include <boost/asio/detail/epoll_reactor.hpp>
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+# include <boost/asio/detail/kqueue_reactor.hpp>
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+# include <boost/asio/detail/dev_poll_reactor.hpp>
+#else
+# include <boost/asio/detail/select_reactor.hpp>
+#endif
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TIMER_SCHEDULER_HPP
Added: trunk/boost/asio/detail/timer_scheduler_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/timer_scheduler_fwd.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,48 @@
+//
+// timer_scheduler_fwd.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_TIMER_SCHEDULER_FWD_HPP
+#define BOOST_ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/dev_poll_reactor_fwd.hpp>
+#include <boost/asio/detail/epoll_reactor_fwd.hpp>
+#include <boost/asio/detail/kqueue_reactor_fwd.hpp>
+#include <boost/asio/detail/select_reactor_fwd.hpp>
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+typedef win_iocp_io_service timer_scheduler;
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+typedef epoll_reactor timer_scheduler;
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+typedef kqueue_reactor timer_scheduler;
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+typedef dev_poll_reactor timer_scheduler;
+#else
+typedef select_reactor<false> timer_scheduler;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_TIMER_SCHEDULER_FWD_HPP
Modified: trunk/boost/asio/detail/win_event.hpp
==============================================================================
--- trunk/boost/asio/detail/win_event.hpp	(original)
+++ trunk/boost/asio/detail/win_event.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -71,6 +71,15 @@
     ::SetEvent(event_);
   }
 
+  // Signal the event and unlock the mutex.
+  template <typename Lock>
+  void signal_and_unlock(Lock& lock)
+  {
+    BOOST_ASSERT(lock.locked());
+    lock.unlock();
+    ::SetEvent(event_);
+  }
+
   // Reset the event.
   template <typename Lock>
   void clear(Lock& lock)
Added: trunk/boost/asio/detail/win_fenced_block.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_fenced_block.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,57 @@
+//
+// win_fenced_block.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_WIN_FENCED_BLOCK_HPP
+#define BOOST_ASIO_DETAIL_WIN_FENCED_BLOCK_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <boost/config.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_WINDOWS)
+
+#include <boost/asio/detail/socket_types.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class win_fenced_block
+  : private noncopyable
+{
+public:
+  // Constructor.
+  win_fenced_block()
+  {
+    MemoryBarrier();
+  }
+
+  // Destructor.
+  ~win_fenced_block()
+  {
+    MemoryBarrier();
+  }
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_WINDOWS)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_WIN_FENCED_BLOCK_HPP
Modified: trunk/boost/asio/detail/win_iocp_handle_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_handle_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_handle_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -26,13 +26,14 @@
 #include <boost/cstdint.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/buffer.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 #include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/operation.hpp>
 #include <boost/asio/detail/win_iocp_io_service.hpp>
 
 namespace boost {
@@ -40,12 +41,8 @@
 namespace detail {
 
 class win_iocp_handle_service
-  : public boost::asio::detail::service_base<win_iocp_handle_service>
 {
 public:
-  // Base class for all operations.
-  typedef win_iocp_io_service::operation operation;
-
   // The native type of a stream handle.
   typedef HANDLE native_type;
 
@@ -81,8 +78,7 @@
   };
 
   win_iocp_handle_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<win_iocp_handle_service>(io_service),
-      iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)),
+    : iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)),
       mutex_(),
       impl_list_(0)
   {
@@ -307,16 +303,9 @@
       return 0;
     }
 
-    // Find first buffer of non-zero length.
-    boost::asio::const_buffer buffer;
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    for (DWORD i = 0; iter != end; ++iter, ++i)
-    {
-      buffer = boost::asio::const_buffer(*iter);
-      if (boost::asio::buffer_size(buffer) != 0)
-        break;
-    }
+    boost::asio::const_buffer buffer =
+      buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence>::first(buffers);
 
     // A request to write 0 bytes on a handle is a no-op.
     if (boost::asio::buffer_size(buffer) == 0)
@@ -365,79 +354,48 @@
   }
 
   template <typename ConstBufferSequence, typename Handler>
-  class write_operation
-    : public operation
+  class write_op : public operation
   {
   public:
-    write_operation(win_iocp_io_service& io_service,
-        const ConstBufferSequence& buffers, Handler handler)
-      : operation(io_service,
-          &write_operation<ConstBufferSequence, Handler>::do_completion_impl,
-          &write_operation<ConstBufferSequence, Handler>::destroy_impl),
-        work_(io_service.get_io_service()),
+    write_op(const ConstBufferSequence& buffers, Handler handler)
+      : operation(&write_op::do_complete),
         buffers_(buffers),
         handler_(handler)
     {
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef write_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      write_op* o(static_cast<write_op*>(base));
+      typedef handler_alloc_traits<Handler, write_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename ConstBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename ConstBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        boost::asio::buffer_cast<const char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::const_buffer,
+            ConstBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      boost_asio_handler_invoke_helpers::invoke(
-          bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef write_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
-    boost::asio::io_service::work work_;
+  private:
     ConstBufferSequence buffers_;
     Handler handler_;
   };
@@ -457,65 +415,16 @@
   void async_write_some_at(implementation_type& impl, boost::uint64_t offset,
       const ConstBufferSequence& buffers, Handler handler)
   {
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-
     // Allocate and construct an operation to wrap the handler.
-    typedef write_operation<ConstBufferSequence, Handler> value_type;
+    typedef write_op<ConstBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, buffers, handler);
-
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
-
-    // Find first buffer of non-zero length.
-    boost::asio::const_buffer buffer;
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    for (DWORD i = 0; iter != end; ++iter, ++i)
-    {
-      buffer = boost::asio::const_buffer(*iter);
-      if (boost::asio::buffer_size(buffer) != 0)
-        break;
-    }
-
-    // A request to write 0 bytes on a handle is a no-op.
-    if (boost::asio::buffer_size(buffer) == 0)
-    {
-      ptr.get()->on_immediate_completion(0, 0);
-      ptr.release();
-      return;
-    }
-
-    // Write the data.
-    DWORD bytes_transferred = 0;
-    ptr.get()->Offset = offset & 0xFFFFFFFF;
-    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-    BOOL ok = ::WriteFile(impl.handle_,
-        boost::asio::buffer_cast<LPCVOID>(buffer),
-        static_cast<DWORD>(boost::asio::buffer_size(buffer)),
-        &bytes_transferred, ptr.get());
-    DWORD last_error = ::GetLastError();
+    handler_ptr<alloc_traits> ptr(raw_ptr, buffers, handler);
 
-    // Check if the operation completed immediately.
-    if (!ok && last_error != ERROR_IO_PENDING)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_write_op(impl, offset,
+        buffer_sequence_adapter<boost::asio::const_buffer,
+          ConstBufferSequence>::first(buffers), ptr.get());
+    ptr.release();
   }
 
   // Read some data. Returns the number of bytes received.
@@ -537,16 +446,9 @@
       return 0;
     }
     
-    // Find first buffer of non-zero length.
-    boost::asio::mutable_buffer buffer;
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    for (DWORD i = 0; iter != end; ++iter, ++i)
-    {
-      buffer = boost::asio::mutable_buffer(*iter);
-      if (boost::asio::buffer_size(buffer) != 0)
-        break;
-    }
+    boost::asio::mutable_buffer buffer =
+      buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence>::first(buffers);
 
     // A request to read 0 bytes on a stream handle is a no-op.
     if (boost::asio::buffer_size(buffer) == 0)
@@ -609,89 +511,54 @@
   }
 
   template <typename MutableBufferSequence, typename Handler>
-  class read_operation
-    : public operation
+  class read_op : public operation
   {
   public:
-    read_operation(win_iocp_io_service& io_service,
-        const MutableBufferSequence& buffers, Handler handler)
-      : operation(io_service,
-          &read_operation<
-            MutableBufferSequence, Handler>::do_completion_impl,
-          &read_operation<
-            MutableBufferSequence, Handler>::destroy_impl),
-        work_(io_service.get_io_service()),
+    read_op(const MutableBufferSequence& buffers, Handler handler)
+      : operation(&read_op::do_complete),
         buffers_(buffers),
         handler_(handler)
     {
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef read_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      read_op* o(static_cast<read_op*>(base));
+      typedef handler_alloc_traits<Handler, read_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename MutableBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename MutableBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        boost::asio::buffer_cast<char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::mutable_buffer,
+            MutableBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Check for the end-of-file condition.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      if (!ec && bytes_transferred == 0 || last_error == ERROR_HANDLE_EOF)
-      {
-        ec = boost::asio::error::eof;
-      }
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost_asio_handler_invoke_helpers::invoke(
-        bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef read_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef boost::asio::detail::handler_alloc_traits<
-        Handler, op_type> alloc_traits;
-      boost::asio::detail::handler_ptr<alloc_traits> ptr(
-        handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
+        // Map non-portable errors to their portable counterparts.
+        if (ec.value() == ERROR_HANDLE_EOF)
+        {
+          ec = boost::asio::error::eof;
+        }
 
-      // Free the memory associated with the handler.
-      ptr.reset();
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
-    boost::asio::io_service::work work_;
+  private:
     MutableBufferSequence buffers_;
     Handler handler_;
   };
@@ -712,63 +579,16 @@
   void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
       const MutableBufferSequence& buffers, Handler handler)
   {
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-
     // Allocate and construct an operation to wrap the handler.
-    typedef read_operation<MutableBufferSequence, Handler> value_type;
+    typedef read_op<MutableBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, buffers, handler);
-
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
-
-    // Find first buffer of non-zero length.
-    boost::asio::mutable_buffer buffer;
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    for (DWORD i = 0; iter != end; ++iter, ++i)
-    {
-      buffer = boost::asio::mutable_buffer(*iter);
-      if (boost::asio::buffer_size(buffer) != 0)
-        break;
-    }
+    handler_ptr<alloc_traits> ptr(raw_ptr, buffers, handler);
 
-    // A request to receive 0 bytes on a stream handle is a no-op.
-    if (boost::asio::buffer_size(buffer) == 0)
-    {
-      ptr.get()->on_immediate_completion(0, 0);
-      ptr.release();
-      return;
-    }
-
-    // Read some data.
-    DWORD bytes_transferred = 0;
-    ptr.get()->Offset = offset & 0xFFFFFFFF;
-    ptr.get()->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
-    BOOL ok = ::ReadFile(impl.handle_,
-        boost::asio::buffer_cast<LPVOID>(buffer),
-        static_cast<DWORD>(boost::asio::buffer_size(buffer)),
-        &bytes_transferred, ptr.get());
-    DWORD last_error = ::GetLastError();
-    if (!ok && last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_read_op(impl, offset,
+        buffer_sequence_adapter<boost::asio::mutable_buffer,
+          MutableBufferSequence>::first(buffers), ptr.get());
+    ptr.release();
   }
 
 private:
@@ -794,6 +614,93 @@
   void async_read_some_at(implementation_type& impl, boost::uint64_t offset,
       const null_buffers& buffers, Handler handler);
 
+  // Helper function to start a write operation.
+  void start_write_op(implementation_type& impl, boost::uint64_t offset,
+      const boost::asio::const_buffer& buffer, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
+
+    if (!is_open(impl))
+    {
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    }
+    else if (boost::asio::buffer_size(buffer) == 0)
+    {
+      // A request to write 0 bytes on a handle is a no-op.
+      iocp_service_.on_completion(op);
+    }
+    else
+    {
+      DWORD bytes_transferred = 0;
+      op->Offset = offset & 0xFFFFFFFF;
+      op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
+      BOOL ok = ::WriteFile(impl.handle_,
+          boost::asio::buffer_cast<LPCVOID>(buffer),
+          static_cast<DWORD>(boost::asio::buffer_size(buffer)),
+          &bytes_transferred, op);
+      DWORD last_error = ::GetLastError();
+      if (!ok && last_error != ERROR_IO_PENDING
+          && last_error != ERROR_MORE_DATA)
+      {
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      }
+      else
+      {
+        iocp_service_.on_pending(op);
+      }
+    }
+  }
+
+  // Helper function to start a read operation.
+  void start_read_op(implementation_type& impl, boost::uint64_t offset,
+      const boost::asio::mutable_buffer& buffer, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
+
+    if (!is_open(impl))
+    {
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    }
+    else if (boost::asio::buffer_size(buffer) == 0)
+    {
+      // A request to read 0 bytes on a handle is a no-op.
+      iocp_service_.on_completion(op);
+    }
+    else
+    {
+      DWORD bytes_transferred = 0;
+      op->Offset = offset & 0xFFFFFFFF;
+      op->OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
+      BOOL ok = ::ReadFile(impl.handle_,
+          boost::asio::buffer_cast<LPVOID>(buffer),
+          static_cast<DWORD>(boost::asio::buffer_size(buffer)),
+          &bytes_transferred, op);
+      DWORD last_error = ::GetLastError();
+      if (!ok && last_error != ERROR_IO_PENDING
+          && last_error != ERROR_MORE_DATA)
+      {
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      }
+      else
+      {
+        iocp_service_.on_pending(op);
+      }
+    }
+  }
+
+  // Update the ID of the thread from which cancellation is safe.
+  void update_cancellation_thread_id()
+  {
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+    if (impl.safe_cancellation_thread_id_ == 0)
+      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
+    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
+      impl.safe_cancellation_thread_id_ = ~DWORD(0);
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+  }
+
   // Helper function to close a handle when the associated object is being
   // destroyed.
   void close_for_destruction(implementation_type& 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-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -29,122 +29,37 @@
 
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/call_stack.hpp>
+#include <boost/asio/detail/completion_handler.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/timer_queue.hpp>
-#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/timer_op.hpp>
+#include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/detail/timer_queue_fwd.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
+#include <boost/asio/detail/win_iocp_operation.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
+class timer_op;
+
 class win_iocp_io_service
   : public boost::asio::detail::service_base<win_iocp_io_service>
 {
 public:
-  // Base class for all operations. A function pointer is used instead of
-  // virtual functions to avoid the associated overhead.
-  //
-  // This class inherits from OVERLAPPED so that we can downcast to get back to
-  // the operation pointer from the LPOVERLAPPED out parameter of
-  // GetQueuedCompletionStatus.
-  class operation;
-  friend class operation;
-  class operation
-    : public OVERLAPPED
-  {
-  public:
-    typedef void (*invoke_func_type)(operation*, DWORD, size_t);
-    typedef void (*destroy_func_type)(operation*);
-
-    operation(win_iocp_io_service& iocp_service,
-        invoke_func_type invoke_func, destroy_func_type destroy_func)
-      : iocp_service_(iocp_service),
-        ready_(0),
-        last_error_(~DWORD(0)),
-        bytes_transferred_(0),
-        invoke_func_(invoke_func),
-        destroy_func_(destroy_func)
-    {
-      Internal = 0;
-      InternalHigh = 0;
-      Offset = 0;
-      OffsetHigh = 0;
-      hEvent = 0;
-
-      ::InterlockedIncrement(&iocp_service_.outstanding_operations_);
-    }
-
-    void reset()
-    {
-      Internal = 0;
-      InternalHigh = 0;
-      Offset = 0;
-      OffsetHigh = 0;
-      hEvent = 0;
-      ready_ = 0;
-      last_error_ = ~DWORD(0);
-      bytes_transferred_ = 0;
-    }
-
-    void on_pending()
-    {
-      if (::InterlockedCompareExchange(&ready_, 1, 0) == 1)
-        iocp_service_.post_completion(this, last_error_, bytes_transferred_);
-    }
-
-    void on_immediate_completion(DWORD last_error, DWORD bytes_transferred)
-    {
-      ready_ = 1;
-      iocp_service_.post_completion(this, last_error, bytes_transferred);
-    }
-
-    bool on_completion(DWORD last_error, DWORD bytes_transferred)
-    {
-      if (last_error_ == ~DWORD(0))
-      {
-        last_error_ = last_error;
-        bytes_transferred_ = bytes_transferred;
-      }
-
-      if (::InterlockedCompareExchange(&ready_, 1, 0) == 1)
-      {
-        invoke_func_(this, last_error_, bytes_transferred_);
-        return true;
-      }
-
-      return false;
-    }
-
-    void destroy()
-    {
-      destroy_func_(this);
-    }
-
-  protected:
-    // Prevent deletion through this type.
-    ~operation()
-    {
-      ::InterlockedDecrement(&iocp_service_.outstanding_operations_);
-    }
-
-  private:
-    win_iocp_io_service& iocp_service_;
-    long ready_;
-    DWORD last_error_;
-    DWORD bytes_transferred_;
-    invoke_func_type invoke_func_;
-    destroy_func_type destroy_func_;
-  };
+  typedef win_iocp_operation operation;
 
   // Constructor.
   win_iocp_io_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<win_iocp_io_service>(io_service),
       iocp_(),
       outstanding_work_(0),
-      outstanding_operations_(0),
       stopped_(0),
       shutdown_(0),
       timer_thread_(0),
@@ -172,24 +87,34 @@
   {
     ::InterlockedExchange(&shutdown_, 1);
 
-    while (::InterlockedExchangeAdd(&outstanding_operations_, 0) > 0)
+    while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0)
     {
-      DWORD bytes_transferred = 0;
-#if defined(WINVER) && (WINVER < 0x0500)
-      DWORD completion_key = 0;
-#else
-      DWORD_PTR completion_key = 0;
-#endif
-      LPOVERLAPPED overlapped = 0;
-      ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
-          &completion_key, &overlapped, INFINITE);
-      if (overlapped)
-        static_cast<operation*>(overlapped)->destroy();
+      op_queue<operation> ops;
+      timer_queues_.get_all_timers(ops);
+      ops.push(completed_ops_);
+      if (!ops.empty())
+      {
+        while (operation* op = ops.front())
+        {
+          ops.pop();
+          ::InterlockedDecrement(&outstanding_work_);
+          op->destroy();
+        }
+      }
+      else
+      {
+        DWORD bytes_transferred = 0;
+        dword_ptr_t completion_key = 0;
+        LPOVERLAPPED overlapped = 0;
+        ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
+            &completion_key, &overlapped, max_timeout);
+        if (overlapped)
+        {
+          ::InterlockedDecrement(&outstanding_work_);
+          static_cast<operation*>(overlapped)->destroy();
+        }
+      }
     }
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      timer_queues_[i]->destroy_timers();
-    timer_queues_.clear();
   }
 
   // Initialise the task. Nothing to do here.
@@ -219,6 +144,7 @@
   {
     if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
     {
+      stop();
       ec = boost::system::error_code();
       return 0;
     }
@@ -237,6 +163,7 @@
   {
     if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
     {
+      stop();
       ec = boost::system::error_code();
       return 0;
     }
@@ -251,6 +178,7 @@
   {
     if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
     {
+      stop();
       ec = boost::system::error_code();
       return 0;
     }
@@ -269,6 +197,7 @@
   {
     if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
     {
+      stop();
       ec = boost::system::error_code();
       return 0;
     }
@@ -319,7 +248,10 @@
   void dispatch(Handler handler)
   {
     if (call_stack<win_iocp_io_service>::contains(this))
+    {
+      boost::asio::detail::fenced_block b;
       boost_asio_handler_invoke_helpers::invoke(handler, handler);
+    }
     else
       post(handler);
   }
@@ -328,37 +260,128 @@
   template <typename Handler>
   void post(Handler handler)
   {
-    // If the service has been shut down we silently discard the handler.
-    if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
-      return;
-
     // Allocate and construct an operation to wrap the handler.
-    typedef handler_operation<Handler> value_type;
+    typedef completion_handler<Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, *this, handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+
+    post_immediate_completion(ptr.get());
+    ptr.release();
+  }
+
+  // Request invocation of the given operation and return immediately. Assumes
+  // that work_started() has not yet been called for the operation.
+  void post_immediate_completion(operation* op)
+  {
+    work_started();
+    post_deferred_completion(op);
+  }
+
+  // Request invocation of the given operation and return immediately. Assumes
+  // that work_started() was previously called for the operation.
+  void post_deferred_completion(operation* op)
+  {
+    // Flag the operation as ready.
+    op->ready_ = 1;
 
     // Enqueue the operation on the I/O completion port.
-    ptr.get()->on_immediate_completion(0, 0);
+    if (!::PostQueuedCompletionStatus(iocp_.handle,
+          0, overlapped_contains_result, op))
+    {
+      // Out of resources. Put on completed queue instead.
+      boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+      completed_ops_.push(op);
+    }
+  }
 
-    // Operation has been successfully posted.
-    ptr.release();
+  // Request invocation of the given operation and return immediately. Assumes
+  // that work_started() was previously called for the operations.
+  void post_deferred_completions(op_queue<operation>& ops)
+  {
+    while (operation* op = ops.front())
+    {
+      ops.pop();
+
+      // Flag the operation as ready.
+      op->ready_ = 1;
+
+      // Enqueue the operation on the I/O completion port.
+      if (!::PostQueuedCompletionStatus(iocp_.handle,
+            0, overlapped_contains_result, op))
+      {
+        // Out of resources. Put on completed queue instead.
+        boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+        completed_ops_.push(op);
+        completed_ops_.push(ops);
+      }
+    }
   }
 
-  // Request invocation of the given OVERLAPPED-derived operation.
-  void post_completion(operation* op, DWORD op_last_error,
-      DWORD bytes_transferred)
+  // Called after starting an overlapped I/O operation that did not complete
+  // immediately. The caller must have already called work_started() prior to
+  // starting the operation.
+  void on_pending(operation* op)
   {
+    if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1)
+    {
+      // Enqueue the operation on the I/O completion port.
+      if (!::PostQueuedCompletionStatus(iocp_.handle,
+            0, overlapped_contains_result, op))
+      {
+        // Out of resources. Put on completed queue instead.
+        boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+        completed_ops_.push(op);
+      }
+    }
+  }
+
+  // Called after starting an overlapped I/O operation that completed
+  // immediately. The caller must have already called work_started() prior to
+  // starting the operation.
+  void on_completion(operation* op,
+      DWORD last_error = 0, DWORD bytes_transferred = 0)
+  {
+    // Flag that the operation is ready for invocation.
+    op->ready_ = 1;
+
+    // Store results in the OVERLAPPED structure.
+    op->Internal = reinterpret_cast<ulong_ptr_t>(
+        &boost::asio::error::get_system_category());
+    op->Offset = last_error;
+    op->OffsetHigh = bytes_transferred;
+
     // Enqueue the operation on the I/O completion port.
     if (!::PostQueuedCompletionStatus(iocp_.handle,
-          bytes_transferred, op_last_error, op))
+          0, overlapped_contains_result, op))
     {
-      DWORD last_error = ::GetLastError();
-      boost::system::system_error e(
-          boost::system::error_code(last_error,
-            boost::asio::error::get_system_category()),
-          "pqcs");
-      boost::throw_exception(e);
+      // Out of resources. Put on completed queue instead.
+      boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+      completed_ops_.push(op);
+    }
+  }
+
+  // Called after starting an overlapped I/O operation that completed
+  // immediately. The caller must have already called work_started() prior to
+  // starting the operation.
+  void on_completion(operation* op,
+      const boost::system::error_code& ec, DWORD bytes_transferred = 0)
+  {
+    // Flag that the operation is ready for invocation.
+    op->ready_ = 1;
+
+    // Store results in the OVERLAPPED structure.
+    op->Internal = reinterpret_cast<ulong_ptr_t>(&ec.category());
+    op->Offset = ec.value();
+    op->OffsetHigh = bytes_transferred;
+
+    // Enqueue the operation on the I/O completion port.
+    if (!::PostQueuedCompletionStatus(iocp_.handle,
+          0, overlapped_contains_result, op))
+    {
+      // Out of resources. Put on completed queue instead.
+      boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+      completed_ops_.push(op);
     }
   }
 
@@ -367,7 +390,7 @@
   void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
-    timer_queues_.push_back(&timer_queue);
+    timer_queues_.insert(&timer_queue);
   }
 
   // Remove a timer queue from the service.
@@ -375,36 +398,28 @@
   void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
   {
     boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      if (timer_queues_[i] == &timer_queue)
-      {
-        timer_queues_.erase(timer_queues_.begin() + i);
-        return;
-      }
-    }
+    timer_queues_.erase(&timer_queue);
   }
 
-  // Schedule a timer in the given timer queue to expire at the specified
-  // absolute time. The handler object will be invoked when the timer expires.
-  template <typename Time_Traits, typename Handler>
+  // 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, Handler handler, void* token)
+      const typename Time_Traits::time_type& time, timer_op* op, void* token)
   {
     // If the service has been shut down we silently discard the timer.
     if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
       return;
 
     boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
-    if (timer_queue.enqueue_timer(time, handler, token))
+    bool interrupt = timer_queue.enqueue_timer(time, op, token);
+    work_started();
+    if (interrupt && !timer_interrupt_issued_)
     {
-      if (!timer_interrupt_issued_)
-      {
-        timer_interrupt_issued_ = true;
-        lock.unlock();
-        ::PostQueuedCompletionStatus(iocp_.handle,
-            0, steal_timer_dispatching, 0);
-      }
+      timer_interrupt_issued_ = true;
+      lock.unlock();
+      ::PostQueuedCompletionStatus(iocp_.handle,
+          0, steal_timer_dispatching, 0);
     }
   }
 
@@ -418,7 +433,9 @@
       return 0;
 
     boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
-    std::size_t n = timer_queue.cancel_timer(token);
+    op_queue<operation> ops;
+    std::size_t n = timer_queue.cancel_timer(token, ops);
+    post_deferred_completions(ops);
     if (n > 0 && !timer_interrupt_issued_)
     {
       timer_interrupt_issued_ = true;
@@ -430,6 +447,14 @@
   }
 
 private:
+#if defined(WINVER) && (WINVER < 0x0500)
+  typedef DWORD dword_ptr_t;
+  typedef ULONG ulong_ptr_t;
+#else // defined(WINVER) && (WINVER < 0x0500)
+  typedef DWORD_PTR dword_ptr_t;
+  typedef ULONG_PTR ulong_ptr_t;
+#endif // defined(WINVER) && (WINVER < 0x0500)
+
   // Dequeues at most one operation from the I/O completion port, and then
   // executes it. Returns the number of operations that were dequeued (i.e.
   // either 0 or 1).
@@ -454,11 +479,7 @@
 
       // Get the next operation from the queue.
       DWORD bytes_transferred = 0;
-#if defined(WINVER) && (WINVER < 0x0500)
-      DWORD completion_key = 0;
-#else
-      DWORD_PTR completion_key = 0;
-#endif
+      dword_ptr_t completion_key = 0;
       LPOVERLAPPED overlapped = 0;
       ::SetLastError(0);
       BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
@@ -468,32 +489,11 @@
       // Dispatch any pending timers.
       if (dispatching_timers)
       {
-        try
-        {
-          boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
-          if (!timer_queues_.empty())
-          {
-            timer_queues_copy_ = timer_queues_;
-            for (std::size_t i = 0; i < timer_queues_copy_.size(); ++i)
-            {
-              timer_queues_copy_[i]->dispatch_timers();
-              timer_queues_copy_[i]->dispatch_cancellations();
-              timer_queues_copy_[i]->complete_timers();
-            }
-          }
-        }
-        catch (...)
-        {
-          // Transfer responsibility for dispatching timers to another thread.
-          if (::InterlockedCompareExchange(&timer_thread_,
-                0, this_thread_id) == this_thread_id)
-          {
-            ::PostQueuedCompletionStatus(iocp_.handle,
-                0, transfer_timer_dispatching, 0);
-          }
-
-          throw;
-        }
+        boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
+        op_queue<operation> ops;
+        ops.push(completed_ops_);
+        timer_queues_.get_ready_timers(ops);
+        post_deferred_completions(ops);
       }
 
       if (!ok && overlapped == 0)
@@ -522,11 +522,9 @@
       }
       else if (overlapped)
       {
-        // We may have been passed a last_error value in the completion_key.
-        if (last_error == 0)
-        {
-          last_error = completion_key;
-        }
+        operation* op = static_cast<operation*>(overlapped);
+        boost::system::error_code result_ec(last_error,
+            boost::asio::error::get_system_category());
 
         // Transfer responsibility for dispatching timers to another thread.
         if (dispatching_timers && ::InterlockedCompareExchange(
@@ -536,14 +534,35 @@
               0, transfer_timer_dispatching, 0);
         }
 
-        // Ensure that the io_service does not exit due to running out of work
-        // while we make the upcall.
-        auto_work work(*this);
+        // We may have been passed the last_error and bytes_transferred in the
+        // OVERLAPPED structure itself.
+        if (completion_key == overlapped_contains_result)
+        {
+          result_ec = boost::system::error_code(static_cast<int>(op->Offset),
+              *reinterpret_cast<boost::system::error_category*>(op->Internal));
+          bytes_transferred = op->OffsetHigh;
+        }
 
-        // Dispatch the operation.
-        operation* op = static_cast<operation*>(overlapped);
-        if (op->on_completion(last_error, bytes_transferred))
+        // Otherwise ensure any result has been saved into the OVERLAPPED
+        // structure.
+        else
         {
+          op->Internal = reinterpret_cast<ulong_ptr_t>(&result_ec.category());
+          op->Offset = result_ec.value();
+          op->OffsetHigh = bytes_transferred;
+        }
+
+        // Dispatch the operation only if ready. The operation may not be ready
+        // if the initiating function (e.g. a call to WSARecv) has not yet
+        // returned. This is because the initiating function still wants access
+        // to the operation's OVERLAPPED structure.
+        if (::InterlockedCompareExchange(&op->ready_, 1, 0) == 1)
+        {
+          // Ensure the count of outstanding work is decremented on block exit.
+          work_finished_on_block_exit on_exit = { this };
+          (void)on_exit;
+
+          op->complete(*this, result_ec, bytes_transferred);
           ec = boost::system::error_code();
           return 1;
         }
@@ -588,126 +607,23 @@
     }
   }
 
-  // Check if all timer queues are empty.
-  bool all_timer_queues_are_empty() const
-  {
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-      if (!timer_queues_[i]->empty())
-        return false;
-    return true;
-  }
-
   // Get the timeout value for the GetQueuedCompletionStatus call. The timeout
   // value is returned as a number of milliseconds. We will wait no longer than
   // 1000 milliseconds.
   DWORD get_timeout()
   {
-    if (all_timer_queues_are_empty())
-      return max_timeout;
-
-    boost::posix_time::time_duration minimum_wait_duration
-      = boost::posix_time::milliseconds(max_timeout);
-
-    for (std::size_t i = 0; i < timer_queues_.size(); ++i)
-    {
-      boost::posix_time::time_duration wait_duration
-        = timer_queues_[i]->wait_duration();
-      if (wait_duration < minimum_wait_duration)
-        minimum_wait_duration = wait_duration;
-    }
-
-    if (minimum_wait_duration > boost::posix_time::time_duration())
-    {
-      int milliseconds = minimum_wait_duration.total_milliseconds();
-      return static_cast<DWORD>(milliseconds > 0 ? milliseconds : 1);
-    }
-    else
-    {
-      return 0;
-    }
+    return timer_queues_.wait_duration_msec(max_timeout);
   }
 
-  struct auto_work
+  // Helper class to call work_finished() on block exit.
+  struct work_finished_on_block_exit
   {
-    auto_work(win_iocp_io_service& io_service)
-      : io_service_(io_service)
+    ~work_finished_on_block_exit()
     {
-      io_service_.work_started();
+      io_service_->work_finished();
     }
 
-    ~auto_work()
-    {
-      io_service_.work_finished();
-    }
-
-  private:
-    win_iocp_io_service& io_service_;
-  };
-
-  template <typename Handler>
-  struct handler_operation
-    : public operation
-  {
-    handler_operation(win_iocp_io_service& io_service,
-        Handler handler)
-      : operation(io_service, &handler_operation<Handler>::do_completion_impl,
-          &handler_operation<Handler>::destroy_impl),
-        io_service_(io_service),
-        handler_(handler)
-    {
-      io_service_.work_started();
-    }
-
-    ~handler_operation()
-    {
-      io_service_.work_finished();
-    }
-
-  private:
-    // Prevent copying and assignment.
-    handler_operation(const handler_operation&);
-    void operator=(const handler_operation&);
-    
-    static void do_completion_impl(operation* op, DWORD, size_t)
-    {
-      // Take ownership of the operation object.
-      typedef handler_operation<Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Make the upcall.
-      boost_asio_handler_invoke_helpers::invoke(handler, handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef handler_operation<Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-    }
-
-    win_iocp_io_service& io_service_;
-    Handler handler_;
+    win_iocp_io_service* io_service_;
   };
 
   // The IO completion port used for queueing operations.
@@ -721,10 +637,6 @@
   // The count of unfinished work.
   long outstanding_work_;
 
-  // The count of unfinished operations.
-  long outstanding_operations_;
-  friend class operation;
-
   // Flag to indicate whether the event loop has been stopped.
   long stopped_;
 
@@ -742,7 +654,12 @@
 
     // Completion key value to indicate that responsibility for dispatching
     // timers should be stolen from another thread.
-    steal_timer_dispatching = 2
+    steal_timer_dispatching = 2,
+
+    // Completion key value to indicate that an operation has posted with the
+    // original last_error and bytes_transferred values stored in the fields of
+    // the OVERLAPPED structure.
+    overlapped_contains_result = 3
   };
 
   // The thread that's currently in charge of dispatching timers.
@@ -755,12 +672,10 @@
   bool timer_interrupt_issued_;
 
   // The timer queues.
-  std::vector<timer_queue_base*> timer_queues_;
+  timer_queue_set timer_queues_;
 
-  // A copy of the timer queues, used when dispatching, cancelling and cleaning
-  // up timers. The copy is stored as a class data member to avoid unnecessary
-  // memory allocation.
-  std::vector<timer_queue_base*> timer_queues_copy_;
+  // The operations that are ready to dispatch.
+  op_queue<operation> completed_ops_;
 };
 
 } // namespace detail
Added: trunk/boost/asio/detail/win_iocp_operation.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_operation.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -0,0 +1,91 @@
+//
+// win_iocp_operation.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_WIN_IOCP_OPERATION_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_OPERATION_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/op_queue.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Base class for all operations. A function pointer is used instead of virtual
+// functions to avoid the associated overhead.
+class win_iocp_operation
+  : public OVERLAPPED
+{
+public:
+  void complete(win_iocp_io_service& owner,
+      const boost::system::error_code& ec = boost::system::error_code(),
+      std::size_t bytes_transferred = 0)
+  {
+    func_(&owner, this, ec, bytes_transferred);
+  }
+
+  void destroy()
+  {
+    func_(0, this, boost::system::error_code(), 0);
+  }
+
+protected:
+  typedef void (*func_type)(win_iocp_io_service*,
+      win_iocp_operation*, boost::system::error_code, std::size_t);
+
+  win_iocp_operation(func_type func)
+    : next_(0),
+      func_(func)
+  {
+    reset();
+  }
+
+  // Prevents deletion through this type.
+  ~win_iocp_operation()
+  {
+  }
+
+  void reset()
+  {
+    Internal = 0;
+    InternalHigh = 0;
+    Offset = 0;
+    OffsetHigh = 0;
+    hEvent = 0;
+    ready_ = 0;
+  }
+
+private:
+  friend class op_queue_access;
+  friend class win_iocp_io_service;
+  win_iocp_operation* next_;
+  func_type func_;
+  long ready_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_OPERATION_HPP
Modified: trunk/boost/asio/detail/win_iocp_overlapped_ptr.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_overlapped_ptr.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_overlapped_ptr.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -21,8 +21,10 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/win_iocp_io_service.hpp>
+#include <boost/asio/detail/win_iocp_operation.hpp>
 
 namespace boost {
 namespace asio {
@@ -35,7 +37,8 @@
 public:
   // Construct an empty win_iocp_overlapped_ptr.
   win_iocp_overlapped_ptr()
-    : ptr_(0)
+    : ptr_(0),
+      iocp_service_(0)
   {
   }
 
@@ -43,7 +46,8 @@
   template <typename Handler>
   explicit win_iocp_overlapped_ptr(
       boost::asio::io_service& io_service, Handler handler)
-    : ptr_(0)
+    : ptr_(0),
+      iocp_service_(0)
   {
     this->reset(io_service, handler);
   }
@@ -61,6 +65,8 @@
     {
       ptr_->destroy();
       ptr_ = 0;
+      iocp_service_->work_finished();
+      iocp_service_ = 0;
     }
   }
 
@@ -69,12 +75,14 @@
   template <typename Handler>
   void reset(boost::asio::io_service& io_service, Handler handler)
   {
-    typedef overlapped_operation<Handler> value_type;
+    typedef overlapped_op<Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, io_service.impl_, handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
+    io_service.impl_.work_started();
     reset();
     ptr_ = ptr.release();
+    iocp_service_ = &io_service.impl_;
   }
 
   // Get the contained OVERLAPPED object.
@@ -93,10 +101,11 @@
   OVERLAPPED* release()
   {
     if (ptr_)
-      ptr_->on_pending();
+      iocp_service_->on_pending(ptr_);
 
     OVERLAPPED* tmp = ptr_;
     ptr_ = 0;
+    iocp_service_ = 0;
     return tmp;
   }
 
@@ -106,99 +115,54 @@
   {
     if (ptr_)
     {
-      ptr_->ec_ = ec;
-      ptr_->on_immediate_completion(0, static_cast<DWORD>(bytes_transferred));
+      iocp_service_->on_completion(ptr_, ec,
+          static_cast<DWORD>(bytes_transferred));
       ptr_ = 0;
+      iocp_service_ = 0;
     }
   }
 
 private:
-  struct overlapped_operation_base
-    : public win_iocp_io_service::operation
-  {
-    overlapped_operation_base(win_iocp_io_service& io_service,
-        invoke_func_type invoke_func, destroy_func_type destroy_func)
-      : win_iocp_io_service::operation(io_service, invoke_func, destroy_func),
-        io_service_(io_service)
-    {
-      io_service_.work_started();
-    }
-
-    ~overlapped_operation_base()
-    {
-      io_service_.work_finished();
-    }
-
-    win_iocp_io_service& io_service_;
-    boost::system::error_code ec_;
-  };
-
   template <typename Handler>
-  struct overlapped_operation
-    : public overlapped_operation_base
+  struct overlapped_op : public win_iocp_operation
   {
-    overlapped_operation(win_iocp_io_service& io_service,
-        Handler handler)
-      : overlapped_operation_base(io_service,
-          &overlapped_operation<Handler>::do_completion_impl,
-          &overlapped_operation<Handler>::destroy_impl),
+    overlapped_op(Handler handler)
+      : win_iocp_operation(&overlapped_op::do_complete),
         handler_(handler)
     {
     }
 
-  private:
-    // Prevent copying and assignment.
-    overlapped_operation(const overlapped_operation&);
-    void operator=(const overlapped_operation&);
-    
-    static void do_completion_impl(win_iocp_io_service::operation* op,
-        DWORD last_error, size_t bytes_transferred)
-    {
-      // Take ownership of the operation object.
-      typedef overlapped_operation<Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // Make a copy of the handler and error_code so that the memory can be
-      // deallocated before the upcall is made.
-      Handler handler(handler_op->handler_);
-      boost::system::error_code ec(handler_op->ec_);
-      if (last_error)
-        ec = boost::system::error_code(last_error,
-            boost::asio::error::get_system_category());
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Make the upcall.
-      boost_asio_handler_invoke_helpers::invoke(
-          bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(win_iocp_io_service::operation* op)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef overlapped_operation<Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
+      overlapped_op* o(static_cast<overlapped_op*>(base));
+      typedef handler_alloc_traits<Handler, overlapped_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
+  private:
     Handler handler_;
   };
 
-  overlapped_operation_base* ptr_;
+  win_iocp_operation* ptr_;
+  win_iocp_io_service* iocp_service_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/win_iocp_serial_port_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_serial_port_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_serial_port_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -37,7 +37,6 @@
 
 // Extend win_iocp_handle_service to provide serial port support.
 class win_iocp_serial_port_service
-  : public boost::asio::detail::service_base<win_iocp_serial_port_service>
 {
 public:
   // The native type of a stream handle.
@@ -47,10 +46,7 @@
   typedef win_iocp_handle_service::implementation_type implementation_type;
 
   win_iocp_serial_port_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        win_iocp_serial_port_service>(io_service),
-      handle_service_(
-          boost::asio::use_service<win_iocp_handle_service>(io_service))
+    : handle_service_(io_service)
   {
   }
 
@@ -279,8 +275,8 @@
   }
 
 private:
-  // The handle service used for initiating asynchronous operations.
-  win_iocp_handle_service& handle_service_;
+  // The implementation used for initiating asynchronous operations.
+  win_iocp_handle_service handle_service_;
 };
 
 } // namespace detail
Modified: trunk/boost/asio/detail/win_iocp_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_socket_service.hpp	(original)
+++ trunk/boost/asio/detail/win_iocp_socket_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -28,15 +28,19 @@
 #include <boost/weak_ptr.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/buffer.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/socket_base.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/fenced_block.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 #include <boost/asio/detail/mutex.hpp>
-#include <boost/asio/detail/select_reactor.hpp>
+#include <boost/asio/detail/null_buffers_op.hpp>
+#include <boost/asio/detail/operation.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/reactor_op.hpp>
 #include <boost/asio/detail/socket_holder.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
@@ -48,7 +52,6 @@
 
 template <typename Protocol>
 class win_iocp_socket_service
-  : public boost::asio::detail::service_base<win_iocp_socket_service<Protocol> >
 {
 public:
   // The protocol type.
@@ -57,9 +60,6 @@
   // The endpoint type.
   typedef typename Protocol::endpoint endpoint_type;
 
-  // Base class for all operations.
-  typedef win_iocp_io_service::operation operation;
-
   struct noop_deleter { void operator()(void*) {} };
   typedef boost::shared_ptr<void> shared_cancel_token_type;
   typedef boost::weak_ptr<void> weak_cancel_token_type;
@@ -114,9 +114,6 @@
     endpoint_type remote_endpoint_;
   };
 
-  // The type of the reactor used for connect operations.
-  typedef detail::select_reactor<true> reactor_type;
-
   // The implementation type of the socket.
   class implementation_type
   {
@@ -161,7 +158,7 @@
     protocol_type protocol_;
 
     // Per-descriptor data used by the reactor.
-    reactor_type::per_descriptor_data reactor_data_;
+    reactor::per_descriptor_data reactor_data_;
 
 #if defined(BOOST_ASIO_ENABLE_CANCELIO)
     // The ID of the thread from which it is safe to cancel asynchronous
@@ -176,14 +173,10 @@
     implementation_type* prev_;
   };
 
-  // The maximum number of buffers to support in a single operation.
-  enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
-
   // Constructor.
   win_iocp_socket_service(boost::asio::io_service& io_service)
-    : boost::asio::detail::service_base<
-        win_iocp_socket_service<Protocol> >(io_service),
-      iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)),
+    : io_service_(io_service),
+      iocp_service_(use_service<win_iocp_io_service>(io_service)),
       reactor_(0),
       mutex_(),
       impl_list_(0)
@@ -304,11 +297,11 @@
       // Check if the reactor was created, in which case we need to close the
       // socket on the reactor as well to cancel any operations that might be
       // running there.
-      reactor_type* reactor = static_cast<reactor_type*>(
+      reactor* r = static_cast<reactor*>(
             interlocked_compare_exchange_pointer(
               reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (reactor)
-        reactor->close_descriptor(impl.socket_, impl.reactor_data_);
+      if (r)
+        r->close_descriptor(impl.socket_, impl.reactor_data_);
 
       if (socket_ops::close(impl.socket_, ec) == socket_error_retval)
         return ec;
@@ -665,23 +658,11 @@
       return 0;
     }
 
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = const_cast<char*>(
-          boost::asio::buffer_cast<const char*>(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
     // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
+    if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
@@ -689,8 +670,8 @@
 
     // Send the data.
     DWORD bytes_transferred = 0;
-    int result = ::WSASend(impl.socket_, bufs,
-        i, &bytes_transferred, flags, 0, 0);
+    int result = ::WSASend(impl.socket_, bufs.buffers(),
+        bufs.count(), &bytes_transferred, flags, 0, 0);
     if (result != 0)
     {
       DWORD last_error = ::WSAGetLastError();
@@ -724,94 +705,63 @@
   }
 
   template <typename ConstBufferSequence, typename Handler>
-  class send_operation
-    : public operation
+  class send_op : public operation
   {
   public:
-    send_operation(win_iocp_io_service& io_service,
-        weak_cancel_token_type cancel_token,
+    send_op(weak_cancel_token_type cancel_token,
         const ConstBufferSequence& buffers, Handler handler)
-      : operation(io_service,
-          &send_operation<ConstBufferSequence, Handler>::do_completion_impl,
-          &send_operation<ConstBufferSequence, Handler>::destroy_impl),
-        work_(io_service.get_io_service()),
+      : operation(&send_op::do_complete),
         cancel_token_(cancel_token),
         buffers_(buffers),
         handler_(handler)
     {
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef send_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      send_op* o(static_cast<send_op*>(base));
+      typedef handler_alloc_traits<Handler, send_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename ConstBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename ConstBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        boost::asio::buffer_cast<const char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::const_buffer,
+            ConstBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Map non-portable errors to their portable counterparts.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      if (ec.value() == ERROR_NETNAME_DELETED)
-      {
-        if (handler_op->cancel_token_.expired())
-          ec = boost::asio::error::operation_aborted;
-        else
-          ec = boost::asio::error::connection_reset;
-      }
-      else if (ec.value() == ERROR_PORT_UNREACHABLE)
-      {
-        ec = boost::asio::error::connection_refused;
-      }
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost_asio_handler_invoke_helpers::invoke(
-          detail::bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef send_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
+        // Map non-portable errors to their portable counterparts.
+        if (ec.value() == ERROR_NETNAME_DELETED)
+        {
+          if (o->cancel_token_.expired())
+            ec = boost::asio::error::operation_aborted;
+          else
+            ec = boost::asio::error::connection_reset;
+        }
+        else if (ec.value() == ERROR_PORT_UNREACHABLE)
+        {
+          ec = boost::asio::error::connection_refused;
+        }
 
-      // Free the memory associated with the handler.
-      ptr.reset();
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
-    boost::asio::io_service::work work_;
+  private:
     weak_cancel_token_type cancel_token_;
     ConstBufferSequence buffers_;
     Handler handler_;
@@ -823,127 +773,34 @@
   void async_send(implementation_type& impl, const ConstBufferSequence& buffers,
       socket_base::message_flags flags, Handler handler)
   {
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
     // Allocate and construct an operation to wrap the handler.
-    typedef send_operation<ConstBufferSequence, Handler> value_type;
+    typedef send_op<ConstBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_,
+    handler_ptr<alloc_traits> ptr(raw_ptr,
         impl.cancel_token_, buffers, handler);
 
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
-
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = const_cast<char*>(
-          boost::asio::buffer_cast<const char*>(buffer));
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
-
-    // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
-    {
-      ptr.get()->on_immediate_completion(0, 0);
-      ptr.release();
-      return;
-    }
-
-    // Send the data.
-    DWORD bytes_transferred = 0;
-    int result = ::WSASend(impl.socket_, bufs, i,
-        &bytes_transferred, flags, ptr.get(), 0);
-    DWORD last_error = ::WSAGetLastError();
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
-    // Check if the operation completed immediately.
-    if (result != 0 && last_error != WSA_IO_PENDING)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_send_op(impl, bufs.buffers(), bufs.count(), flags,
+        impl.protocol_.type() == SOCK_STREAM && bufs.all_empty(), ptr.get());
+    ptr.release();
   }
 
-  template <typename Handler>
-  class null_buffers_operation
-  {
-  public:
-    null_buffers_operation(boost::asio::io_service& io_service, Handler handler)
-      : work_(io_service),
-        handler_(handler)
-    {
-    }
-
-    bool perform(boost::system::error_code&,
-        std::size_t& bytes_transferred)
-    {
-      bytes_transferred = 0;
-      return true;
-    }
-
-    void complete(const boost::system::error_code& ec,
-        std::size_t bytes_transferred)
-    {
-      work_.get_io_service().post(bind_handler(
-            handler_, ec, bytes_transferred));
-    }
-
-  private:
-    boost::asio::io_service::work work_;
-    Handler handler_;
-  };
-
   // Start an asynchronous wait until data can be sent without blocking.
   template <typename Handler>
   void async_send(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Check if the reactor was already obtained from the io_service.
-      reactor_type* reactor = static_cast<reactor_type*>(
-            interlocked_compare_exchange_pointer(
-              reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (!reactor)
-      {
-        reactor = &(boost::asio::use_service<reactor_type>(
-              this->get_io_service()));
-        interlocked_exchange_pointer(
-            reinterpret_cast<void**>(&reactor_), reactor);
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      reactor->start_write_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    start_reactor_op(impl, reactor::write_op, ptr.get());
+    ptr.release();
   }
 
   // Send a datagram to the specified endpoint. Returns the number of bytes
@@ -959,23 +816,14 @@
       return 0;
     }
 
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = const_cast<char*>(
-          boost::asio::buffer_cast<const char*>(buffer));
-    }
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
     // Send the data.
     DWORD bytes_transferred = 0;
-    int result = ::WSASendTo(impl.socket_, bufs, i, &bytes_transferred,
-        flags, destination.data(), static_cast<int>(destination.size()), 0, 0);
+    int result = ::WSASendTo(impl.socket_, bufs.buffers(), bufs.count(),
+        &bytes_transferred, flags, destination.data(),
+        static_cast<int>(destination.size()), 0, 0);
     if (result != 0)
     {
       DWORD last_error = ::WSAGetLastError();
@@ -1008,85 +856,57 @@
   }
 
   template <typename ConstBufferSequence, typename Handler>
-  class send_to_operation
-    : public operation
+  class send_to_op : public operation
   {
   public:
-    send_to_operation(win_iocp_io_service& io_service,
+    send_to_op(weak_cancel_token_type cancel_token,
         const ConstBufferSequence& buffers, Handler handler)
-      : operation(io_service,
-          &send_to_operation<ConstBufferSequence, Handler>::do_completion_impl,
-          &send_to_operation<ConstBufferSequence, Handler>::destroy_impl),
-        work_(io_service.get_io_service()),
+      : operation(&send_to_op::do_complete),
+        cancel_token_(cancel_token),
         buffers_(buffers),
         handler_(handler)
     {
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef send_to_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      send_to_op* o(static_cast<send_to_op*>(base));
+      typedef handler_alloc_traits<Handler, send_to_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename ConstBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename ConstBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::const_buffer buffer(*iter);
-        boost::asio::buffer_cast<const char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::const_buffer,
+            ConstBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Map non-portable errors to their portable counterparts.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      if (ec.value() == ERROR_PORT_UNREACHABLE)
-      {
-        ec = boost::asio::error::connection_refused;
-      }
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost_asio_handler_invoke_helpers::invoke(
-          detail::bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef send_to_operation<ConstBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
+        // Map non-portable errors to their portable counterparts.
+        if (ec.value() == ERROR_PORT_UNREACHABLE)
+        {
+          ec = boost::asio::error::connection_refused;
+        }
 
-      // Free the memory associated with the handler.
-      ptr.reset();
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
-    boost::asio::io_service::work work_;
+  private:
+    weak_cancel_token_type cancel_token_;
     ConstBufferSequence buffers_;
     Handler handler_;
   };
@@ -1098,57 +918,19 @@
       const ConstBufferSequence& buffers, const endpoint_type& destination,
       socket_base::message_flags flags, Handler handler)
   {
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
     // Allocate and construct an operation to wrap the handler.
-    typedef send_to_operation<ConstBufferSequence, Handler> value_type;
+    typedef send_to_op<ConstBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, buffers, handler);
-
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
-
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename ConstBufferSequence::const_iterator iter = buffers.begin();
-    typename ConstBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::const_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = const_cast<char*>(
-          boost::asio::buffer_cast<const char*>(buffer));
-    }
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        impl.cancel_token_, buffers, handler);
 
-    // Send the data.
-    DWORD bytes_transferred = 0;
-    int result = ::WSASendTo(impl.socket_, bufs, i, &bytes_transferred, flags,
-        destination.data(), static_cast<int>(destination.size()), ptr.get(), 0);
-    DWORD last_error = ::WSAGetLastError();
+    buffer_sequence_adapter<boost::asio::const_buffer,
+        ConstBufferSequence> bufs(buffers);
 
-    // Check if the operation completed immediately.
-    if (result != 0 && last_error != WSA_IO_PENDING)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_send_to_op(impl, bufs.buffers(),
+        bufs.count(), destination, flags, ptr.get());
+    ptr.release();
   }
 
   // Start an asynchronous wait until data can be sent without blocking.
@@ -1156,29 +938,14 @@
   void async_send_to(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, const endpoint_type&, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Check if the reactor was already obtained from the io_service.
-      reactor_type* reactor = static_cast<reactor_type*>(
-            interlocked_compare_exchange_pointer(
-              reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (!reactor)
-      {
-        reactor = &(boost::asio::use_service<reactor_type>(
-              this->get_io_service()));
-        interlocked_exchange_pointer(
-            reinterpret_cast<void**>(&reactor_), reactor);
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      reactor->start_write_op(impl.socket_, impl.reactor_data_,
-          null_buffers_operation<Handler>(this->get_io_service(), handler),
-          false);
-    }
+    start_reactor_op(impl, reactor::write_op, ptr.get());
+    ptr.release();
   }
 
   // Receive some data from the peer. Returns the number of bytes received.
@@ -1193,22 +960,11 @@
       return 0;
     }
 
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = boost::asio::buffer_cast<char*>(buffer);
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
     // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
+    if (impl.protocol_.type() == SOCK_STREAM && bufs.all_empty())
     {
       ec = boost::system::error_code();
       return 0;
@@ -1217,8 +973,8 @@
     // Receive some data.
     DWORD bytes_transferred = 0;
     DWORD recv_flags = flags;
-    int result = ::WSARecv(impl.socket_, bufs, i,
-        &bytes_transferred, &recv_flags, 0, 0);
+    int result = ::WSARecv(impl.socket_, bufs.buffers(),
+        bufs.count(), &bytes_transferred, &recv_flags, 0, 0);
     if (result != 0)
     {
       DWORD last_error = ::WSAGetLastError();
@@ -1257,106 +1013,73 @@
   }
 
   template <typename MutableBufferSequence, typename Handler>
-  class receive_operation
-    : public operation
+  class receive_op : public operation
   {
   public:
-    receive_operation(int protocol_type, win_iocp_io_service& io_service,
-        weak_cancel_token_type cancel_token,
+    receive_op(int protocol_type, weak_cancel_token_type cancel_token,
         const MutableBufferSequence& buffers, Handler handler)
-      : operation(io_service,
-          &receive_operation<
-            MutableBufferSequence, Handler>::do_completion_impl,
-          &receive_operation<
-            MutableBufferSequence, Handler>::destroy_impl),
+      : operation(&receive_op::do_complete),
         protocol_type_(protocol_type),
-        work_(io_service.get_io_service()),
         cancel_token_(cancel_token),
         buffers_(buffers),
         handler_(handler)
     {
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef receive_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      receive_op* o(static_cast<receive_op*>(base));
+      typedef handler_alloc_traits<Handler, receive_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename MutableBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename MutableBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        boost::asio::buffer_cast<char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::mutable_buffer,
+            MutableBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Map non-portable errors to their portable counterparts.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      if (ec.value() == ERROR_NETNAME_DELETED)
-      {
-        if (handler_op->cancel_token_.expired())
-          ec = boost::asio::error::operation_aborted;
-        else
-          ec = boost::asio::error::connection_reset;
-      }
-      else if (ec.value() == ERROR_PORT_UNREACHABLE)
-      {
-        ec = boost::asio::error::connection_refused;
-      }
-
-      // Check for connection closed.
-      else if (!ec && bytes_transferred == 0
-          && handler_op->protocol_type_ == SOCK_STREAM
-          && !boost::is_same<MutableBufferSequence, null_buffers>::value)
-      {
-        ec = boost::asio::error::eof;
-      }
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost_asio_handler_invoke_helpers::invoke(
-          detail::bind_handler(handler, ec, bytes_transferred), handler);
-    }
+        // Map non-portable errors to their portable counterparts.
+        if (ec.value() == ERROR_NETNAME_DELETED)
+        {
+          if (o->cancel_token_.expired())
+            ec = boost::asio::error::operation_aborted;
+          else
+            ec = boost::asio::error::connection_reset;
+        }
+        else if (ec.value() == ERROR_PORT_UNREACHABLE)
+        {
+          ec = boost::asio::error::connection_refused;
+        }
 
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef receive_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
+        // Check for connection closed.
+        else if (!ec && bytes_transferred == 0
+            && o->protocol_type_ == SOCK_STREAM
+            && !boost::is_same<MutableBufferSequence, null_buffers>::value)
+        {
+          ec = boost::asio::error::eof;
+        }
 
-      // Free the memory associated with the handler.
-      ptr.reset();
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
+  private:
     int protocol_type_;
-    boost::asio::io_service::work work_;
     weak_cancel_token_type cancel_token_;
     MutableBufferSequence buffers_;
     Handler handler_;
@@ -1369,67 +1092,20 @@
       const MutableBufferSequence& buffers,
       socket_base::message_flags flags, Handler handler)
   {
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
     // Allocate and construct an operation to wrap the handler.
-    typedef receive_operation<MutableBufferSequence, Handler> value_type;
+    typedef receive_op<MutableBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
     int protocol_type = impl.protocol_.type();
     handler_ptr<alloc_traits> ptr(raw_ptr, protocol_type,
-        iocp_service_, impl.cancel_token_, buffers, handler);
-
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
-
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    size_t total_buffer_size = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = boost::asio::buffer_cast<char*>(buffer);
-      total_buffer_size += boost::asio::buffer_size(buffer);
-    }
+        impl.cancel_token_, buffers, handler);
 
-    // A request to receive 0 bytes on a stream socket is a no-op.
-    if (impl.protocol_.type() == SOCK_STREAM && total_buffer_size == 0)
-    {
-      ptr.get()->on_immediate_completion(0, 0);
-      ptr.release();
-      return;
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
-    // Receive some data.
-    DWORD bytes_transferred = 0;
-    DWORD recv_flags = flags;
-    int result = ::WSARecv(impl.socket_, bufs, i,
-        &bytes_transferred, &recv_flags, ptr.get(), 0);
-    DWORD last_error = ::WSAGetLastError();
-    if (result != 0 && last_error != WSA_IO_PENDING)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_receive_op(impl, bufs.buffers(), bufs.count(), flags,
+        protocol_type == SOCK_STREAM && bufs.all_empty(), ptr.get());
+    ptr.release();
   }
 
   // Wait until data can be received without blocking.
@@ -1437,75 +1113,36 @@
   void async_receive(implementation_type& impl, const null_buffers& buffers,
       socket_base::message_flags flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else if (impl.protocol_.type() == SOCK_STREAM)
+    if (impl.protocol_.type() == SOCK_STREAM)
     {
       // For stream sockets on Windows, we may issue a 0-byte overlapped
       // WSARecv to wait until there is data available on the socket.
 
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-      // Update the ID of the thread from which cancellation is safe.
-      if (impl.safe_cancellation_thread_id_ == 0)
-        impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-      else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-        impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
       // Allocate and construct an operation to wrap the handler.
-      typedef receive_operation<null_buffers, Handler> value_type;
+      typedef receive_op<null_buffers, Handler> value_type;
       typedef handler_alloc_traits<Handler, value_type> alloc_traits;
       raw_handler_ptr<alloc_traits> raw_ptr(handler);
       int protocol_type = impl.protocol_.type();
       handler_ptr<alloc_traits> ptr(raw_ptr, protocol_type,
-          iocp_service_, impl.cancel_token_, buffers, handler);
+          impl.cancel_token_, buffers, handler);
 
-      // Issue a receive operation with an empty buffer.
       ::WSABUF buf = { 0, 0 };
-      DWORD bytes_transferred = 0;
-      DWORD recv_flags = flags;
-      int result = ::WSARecv(impl.socket_, &buf, 1,
-          &bytes_transferred, &recv_flags, ptr.get(), 0);
-      DWORD last_error = ::WSAGetLastError();
-      if (result != 0 && last_error != WSA_IO_PENDING)
-      {
-        ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-        ptr.release();
-      }
-      else
-      {
-        ptr.get()->on_pending();
-        ptr.release();
-      }
+      start_receive_op(impl, &buf, 1, flags, false, ptr.get());
+      ptr.release();
     }
     else
     {
-      // Check if the reactor was already obtained from the io_service.
-      reactor_type* reactor = static_cast<reactor_type*>(
-            interlocked_compare_exchange_pointer(
-              reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (!reactor)
-      {
-        reactor = &(boost::asio::use_service<reactor_type>(
-              this->get_io_service()));
-        interlocked_exchange_pointer(
-            reinterpret_cast<void**>(&reactor_), reactor);
-      }
+      // Allocate and construct an operation to wrap the handler.
+      typedef null_buffers_op<Handler> value_type;
+      typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+      raw_handler_ptr<alloc_traits> raw_ptr(handler);
+      handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      if (flags & socket_base::message_out_of_band)
-      {
-        reactor->start_except_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler));
-      }
-      else
-      {
-        reactor->start_read_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler),
-            false);
-      }
+      start_reactor_op(impl,
+          (flags & socket_base::message_out_of_band)
+            ? reactor::except_op : reactor::read_op,
+          ptr.get());
+      ptr.release();
     }
   }
 
@@ -1523,24 +1160,16 @@
       return 0;
     }
 
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = boost::asio::buffer_cast<char*>(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
     // Receive some data.
     DWORD bytes_transferred = 0;
     DWORD recv_flags = flags;
     int endpoint_size = static_cast<int>(sender_endpoint.capacity());
-    int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred,
-        &recv_flags, sender_endpoint.data(), &endpoint_size, 0, 0);
+    int result = ::WSARecvFrom(impl.socket_, bufs.buffers(),
+        bufs.count(), &bytes_transferred, &recv_flags,
+        sender_endpoint.data(), &endpoint_size, 0, 0);
     if (result != 0)
     {
       DWORD last_error = ::WSAGetLastError();
@@ -1583,22 +1212,15 @@
   }
 
   template <typename MutableBufferSequence, typename Handler>
-  class receive_from_operation
-    : public operation
+  class receive_from_op : public operation
   {
   public:
-    receive_from_operation(int protocol_type, win_iocp_io_service& io_service,
-        endpoint_type& endpoint, const MutableBufferSequence& buffers,
-        Handler handler)
-      : operation(io_service,
-          &receive_from_operation<
-            MutableBufferSequence, Handler>::do_completion_impl,
-          &receive_from_operation<
-            MutableBufferSequence, Handler>::destroy_impl),
+    receive_from_op(int protocol_type, endpoint_type& endpoint,
+        const MutableBufferSequence& buffers, Handler handler)
+      : operation(&receive_from_op::do_complete),
         protocol_type_(protocol_type),
         endpoint_(endpoint),
         endpoint_size_(static_cast<int>(endpoint.capacity())),
-        work_(io_service.get_io_service()),
         buffers_(buffers),
         handler_(handler)
     {
@@ -1609,83 +1231,51 @@
       return endpoint_size_;
     }
 
-  private:
-    static void do_completion_impl(operation* op,
-        DWORD last_error, size_t bytes_transferred)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t bytes_transferred)
     {
       // Take ownership of the operation object.
-      typedef receive_from_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      receive_from_op* o(static_cast<receive_from_op*>(base));
+      typedef handler_alloc_traits<Handler, receive_from_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
+      // Make the upcall if required.
+      if (owner)
+      {
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-      // Check whether buffers are still valid.
-      typename MutableBufferSequence::const_iterator iter
-        = handler_op->buffers_.begin();
-      typename MutableBufferSequence::const_iterator end
-        = handler_op->buffers_.end();
-      while (iter != end)
-      {
-        boost::asio::mutable_buffer buffer(*iter);
-        boost::asio::buffer_cast<char*>(buffer);
-        ++iter;
-      }
+        // Check whether buffers are still valid.
+        buffer_sequence_adapter<boost::asio::mutable_buffer,
+            MutableBufferSequence>::validate(o->buffers_);
 #endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
 
-      // Map non-portable errors to their portable counterparts.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      if (ec.value() == ERROR_PORT_UNREACHABLE)
-      {
-        ec = boost::asio::error::connection_refused;
-      }
-
-      // Check for connection closed.
-      if (!ec && bytes_transferred == 0
-          && handler_op->protocol_type_ == SOCK_STREAM)
-      {
-        ec = boost::asio::error::eof;
-      }
+        // Map non-portable errors to their portable counterparts.
+        if (ec.value() == ERROR_PORT_UNREACHABLE)
+        {
+          ec = boost::asio::error::connection_refused;
+        }
 
-      // Record the size of the endpoint returned by the operation.
-      handler_op->endpoint_.resize(handler_op->endpoint_size_);
+        // Record the size of the endpoint returned by the operation.
+        o->endpoint_.resize(o->endpoint_size_);
 
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost_asio_handler_invoke_helpers::invoke(
-          detail::bind_handler(handler, ec, bytes_transferred), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef receive_from_operation<MutableBufferSequence, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-    }
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder2<Handler, boost::system::error_code, std::size_t>
+          handler(o->handler_, ec, bytes_transferred);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
+    }
 
+  private:
     int protocol_type_;
     endpoint_type& endpoint_;
     int endpoint_size_;
-    boost::asio::io_service::work work_;
+    weak_cancel_token_type cancel_token_;
     MutableBufferSequence buffers_;
     Handler handler_;
   };
@@ -1698,58 +1288,20 @@
       const MutableBufferSequence& buffers, endpoint_type& sender_endp,
       socket_base::message_flags flags, Handler handler)
   {
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
     // Allocate and construct an operation to wrap the handler.
-    typedef receive_from_operation<MutableBufferSequence, Handler> value_type;
+    typedef receive_from_op<MutableBufferSequence, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
     int protocol_type = impl.protocol_.type();
-    handler_ptr<alloc_traits> ptr(raw_ptr, protocol_type,
-        iocp_service_, sender_endp, buffers, handler);
-
-    if (!is_open(impl))
-    {
-      ptr.get()->on_immediate_completion(WSAEBADF, 0);
-      ptr.release();
-      return;
-    }
+    handler_ptr<alloc_traits> ptr(raw_ptr,
+        protocol_type, sender_endp, buffers, handler);
 
-    // Copy buffers into WSABUF array.
-    ::WSABUF bufs[max_buffers];
-    typename MutableBufferSequence::const_iterator iter = buffers.begin();
-    typename MutableBufferSequence::const_iterator end = buffers.end();
-    DWORD i = 0;
-    for (; iter != end && i < max_buffers; ++iter, ++i)
-    {
-      boost::asio::mutable_buffer buffer(*iter);
-      bufs[i].len = static_cast<u_long>(boost::asio::buffer_size(buffer));
-      bufs[i].buf = boost::asio::buffer_cast<char*>(buffer);
-    }
+    buffer_sequence_adapter<boost::asio::mutable_buffer,
+        MutableBufferSequence> bufs(buffers);
 
-    // Receive some data.
-    DWORD bytes_transferred = 0;
-    DWORD recv_flags = flags;
-    int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred,
-        &recv_flags, sender_endp.data(), &ptr.get()->endpoint_size(),
-        ptr.get(), 0);
-    DWORD last_error = ::WSAGetLastError();
-    if (result != 0 && last_error != WSA_IO_PENDING)
-    {
-      ptr.get()->on_immediate_completion(last_error, bytes_transferred);
-      ptr.release();
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    start_receive_from_op(impl, bufs.buffers(), bufs.count(),
+        sender_endp, flags, &ptr.get()->endpoint_size(), ptr.get());
+    ptr.release();
   }
 
   // Wait until data can be received without blocking.
@@ -1758,40 +1310,20 @@
       const null_buffers&, endpoint_type& sender_endpoint,
       socket_base::message_flags flags, Handler handler)
   {
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor, 0));
-    }
-    else
-    {
-      // Check if the reactor was already obtained from the io_service.
-      reactor_type* reactor = static_cast<reactor_type*>(
-            interlocked_compare_exchange_pointer(
-              reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (!reactor)
-      {
-        reactor = &(boost::asio::use_service<reactor_type>(
-              this->get_io_service()));
-        interlocked_exchange_pointer(
-            reinterpret_cast<void**>(&reactor_), reactor);
-      }
+    // Allocate and construct an operation to wrap the handler.
+    typedef null_buffers_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, handler);
 
-      // Reset endpoint since it can be given no sensible value at this time.
-      sender_endpoint = endpoint_type();
+    // Reset endpoint since it can be given no sensible value at this time.
+    sender_endpoint = endpoint_type();
 
-      if (flags & socket_base::message_out_of_band)
-      {
-        reactor->start_except_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler));
-      }
-      else
-      {
-        reactor->start_read_op(impl.socket_, impl.reactor_data_,
-            null_buffers_operation<Handler>(this->get_io_service(), handler),
-            false);
-      }
-    }
+    start_reactor_op(impl,
+        (flags & socket_base::message_out_of_band)
+          ? reactor::except_op : reactor::read_op,
+        ptr.get());
+    ptr.release();
   }
 
   // Accept a new connection.
@@ -1852,32 +1384,27 @@
   }
 
   template <typename Socket, typename Handler>
-  class accept_operation
-    : public operation
+  class accept_op : public operation
   {
   public:
-    accept_operation(win_iocp_io_service& io_service,
-        socket_type socket, socket_type new_socket, Socket& peer,
-        const protocol_type& protocol, endpoint_type* peer_endpoint,
-        bool enable_connection_aborted, Handler handler)
-      : operation(io_service,
-          &accept_operation<Socket, Handler>::do_completion_impl,
-          &accept_operation<Socket, Handler>::destroy_impl),
-        io_service_(io_service),
+    accept_op(win_iocp_io_service& iocp_service, socket_type socket,
+        Socket& peer, const protocol_type& protocol,
+        endpoint_type* peer_endpoint, bool enable_connection_aborted,
+        Handler handler)
+      : operation(&accept_op::do_complete),
+        iocp_service_(iocp_service),
         socket_(socket),
-        new_socket_(new_socket),
         peer_(peer),
         protocol_(protocol),
         peer_endpoint_(peer_endpoint),
-        work_(io_service.get_io_service()),
         enable_connection_aborted_(enable_connection_aborted),
         handler_(handler)
     {
     }
 
-    socket_type new_socket()
+    socket_holder& new_socket()
     {
-      return new_socket_.get();
+      return new_socket_;
     }
 
     void* output_buffer()
@@ -1890,166 +1417,145 @@
       return sizeof(sockaddr_storage_type) + 16;
     }
 
-  private:
-    static void do_completion_impl(operation* op, DWORD last_error, size_t)
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code ec, std::size_t /*bytes_transferred*/)
     {
-      // Take ownership of the operation object.
-      typedef accept_operation<Socket, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
+      // Take ownership of the handler object.
+      accept_op* o(static_cast<accept_op*>(base));
+      typedef handler_alloc_traits<Handler, accept_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
 
-      // Map Windows error ERROR_NETNAME_DELETED to connection_aborted.
-      if (last_error == ERROR_NETNAME_DELETED)
+      // Make the upcall if required.
+      if (owner)
       {
-        last_error = WSAECONNABORTED;
-      }
+        // Map Windows error ERROR_NETNAME_DELETED to connection_aborted.
+        if (ec.value() == ERROR_NETNAME_DELETED)
+        {
+          ec = boost::asio::error::connection_aborted;
+        }
 
-      // Restart the accept operation if we got the connection_aborted error
-      // and the enable_connection_aborted socket option is not set.
-      if (last_error == WSAECONNABORTED
-          && !ptr.get()->enable_connection_aborted_)
-      {
-        // Reset OVERLAPPED structure.
-        ptr.get()->reset();
-
-        // Create a new socket for the next connection, since the AcceptEx call
-        // fails with WSAEINVAL if we try to reuse the same socket.
-        boost::system::error_code ec;
-        ptr.get()->new_socket_.reset();
-        ptr.get()->new_socket_.reset(socket_ops::socket(
-              ptr.get()->protocol_.family(), ptr.get()->protocol_.type(),
-              ptr.get()->protocol_.protocol(), ec));
-        if (ptr.get()->new_socket() != invalid_socket)
+        // Restart the accept operation if we got the connection_aborted error
+        // and the enable_connection_aborted socket option is not set.
+        if (ec == boost::asio::error::connection_aborted
+            && !o->enable_connection_aborted_)
         {
-          // Accept a connection.
-          DWORD bytes_read = 0;
-          BOOL result = ::AcceptEx(ptr.get()->socket_, ptr.get()->new_socket(),
-              ptr.get()->output_buffer(), 0, ptr.get()->address_length(),
-              ptr.get()->address_length(), &bytes_read, ptr.get());
-          last_error = ::WSAGetLastError();
+          // Reset OVERLAPPED structure.
+          o->reset();
 
-          // Check if the operation completed immediately.
-          if (!result && last_error != WSA_IO_PENDING)
+          // Create a new socket for the next connection, since the AcceptEx
+          // call fails with WSAEINVAL if we try to reuse the same socket.
+          o->new_socket_.reset();
+          o->new_socket_.reset(socket_ops::socket(o->protocol_.family(),
+                o->protocol_.type(), o->protocol_.protocol(), ec));
+          if (o->new_socket_.get() != invalid_socket)
           {
-            if (last_error == ERROR_NETNAME_DELETED
-                || last_error == WSAECONNABORTED)
+            // Accept a connection.
+            DWORD bytes_read = 0;
+            BOOL result = ::AcceptEx(o->socket_, o->new_socket_.get(),
+                o->output_buffer(), 0, o->address_length(),
+                o->address_length(), &bytes_read, o);
+            DWORD last_error = ::WSAGetLastError();
+            ec = boost::system::error_code(last_error,
+                boost::asio::error::get_system_category());
+
+            // Check if the operation completed immediately.
+            if (!result && last_error != WSA_IO_PENDING)
             {
-              // Post this handler so that operation will be restarted again.
-              ptr.get()->on_immediate_completion(last_error, 0);
-              ptr.release();
-              return;
+              if (last_error == ERROR_NETNAME_DELETED
+                  || last_error == WSAECONNABORTED)
+              {
+                // Post this handler so that operation will be restarted again.
+                o->iocp_service_.work_started();
+                o->iocp_service_.on_completion(o, ec);
+                ptr.release();
+                return;
+              }
+              else
+              {
+                // Operation already complete. Continue with rest of this
+                // handler.
+              }
             }
             else
             {
-              // Operation already complete. Continue with rest of this handler.
+              // Asynchronous operation has been successfully restarted.
+              o->iocp_service_.work_started();
+              o->iocp_service_.on_pending(o);
+              ptr.release();
+              return;
             }
           }
+        }
+
+        // Get the address of the peer.
+        endpoint_type peer_endpoint;
+        if (!ec)
+        {
+          LPSOCKADDR local_addr = 0;
+          int local_addr_length = 0;
+          LPSOCKADDR remote_addr = 0;
+          int remote_addr_length = 0;
+          GetAcceptExSockaddrs(o->output_buffer(), 0, o->address_length(),
+              o->address_length(), &local_addr, &local_addr_length,
+              &remote_addr, &remote_addr_length);
+          if (static_cast<std::size_t>(remote_addr_length)
+              > peer_endpoint.capacity())
+          {
+            ec = boost::asio::error::invalid_argument;
+          }
           else
           {
-            // Asynchronous operation has been successfully restarted.
-            ptr.get()->on_pending();
-            ptr.release();
-            return;
+            using namespace std; // For memcpy.
+            memcpy(peer_endpoint.data(), remote_addr, remote_addr_length);
+            peer_endpoint.resize(static_cast<std::size_t>(remote_addr_length));
           }
         }
-      }
 
-      // Get the address of the peer.
-      endpoint_type peer_endpoint;
-      if (last_error == 0)
-      {
-        LPSOCKADDR local_addr = 0;
-        int local_addr_length = 0;
-        LPSOCKADDR remote_addr = 0;
-        int remote_addr_length = 0;
-        GetAcceptExSockaddrs(handler_op->output_buffer(), 0,
-            handler_op->address_length(), handler_op->address_length(),
-            &local_addr, &local_addr_length, &remote_addr, &remote_addr_length);
-        if (static_cast<std::size_t>(remote_addr_length)
-            > peer_endpoint.capacity())
+        // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname
+        // and getpeername will work on the accepted socket.
+        if (!ec)
         {
-          last_error = WSAEINVAL;
+          SOCKET update_ctx_param = o->socket_;
+          socket_ops::setsockopt(o->new_socket_.get(),
+                SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
+                &update_ctx_param, sizeof(SOCKET), ec);
         }
-        else
-        {
-          using namespace std; // For memcpy.
-          memcpy(peer_endpoint.data(), remote_addr, remote_addr_length);
-          peer_endpoint.resize(static_cast<std::size_t>(remote_addr_length));
-        }
-      }
 
-      // Need to set the SO_UPDATE_ACCEPT_CONTEXT option so that getsockname
-      // and getpeername will work on the accepted socket.
-      if (last_error == 0)
-      {
-        SOCKET update_ctx_param = handler_op->socket_;
-        boost::system::error_code ec;
-        if (socket_ops::setsockopt(handler_op->new_socket_.get(),
-              SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
-              &update_ctx_param, sizeof(SOCKET), ec) != 0)
+        // If the socket was successfully accepted, transfer ownership of the
+        // socket to the peer object.
+        if (!ec)
         {
-          last_error = ec.value();
+          o->peer_.assign(o->protocol_,
+              native_type(o->new_socket_.get(), peer_endpoint), ec);
+          if (!ec)
+            o->new_socket_.release();
         }
-      }
 
-      // If the socket was successfully accepted, transfer ownership of the
-      // socket to the peer object.
-      if (last_error == 0)
-      {
-        boost::system::error_code ec;
-        handler_op->peer_.assign(handler_op->protocol_,
-            native_type(handler_op->new_socket_.get(), peer_endpoint), ec);
-        if (ec)
-          last_error = ec.value();
-        else
-          handler_op->new_socket_.release();
+        // Pass endpoint back to caller.
+        if (o->peer_endpoint_)
+          *o->peer_endpoint_ = peer_endpoint;
+
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder1<Handler, boost::system::error_code>
+          handler(o->handler_, ec);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
       }
-
-      // Pass endpoint back to caller.
-      if (handler_op->peer_endpoint_)
-        *handler_op->peer_endpoint_ = peer_endpoint;
-
-      // Make a copy of the handler so that the memory can be deallocated before
-      // the upcall is made.
-      Handler handler(handler_op->handler_);
-
-      // Free the memory associated with the handler.
-      ptr.reset();
-
-      // Call the handler.
-      boost::system::error_code ec(last_error,
-          boost::asio::error::get_system_category());
-      boost_asio_handler_invoke_helpers::invoke(
-          detail::bind_handler(handler, ec), handler);
-    }
-
-    static void destroy_impl(operation* op)
-    {
-      // Take ownership of the operation object.
-      typedef accept_operation<Socket, Handler> op_type;
-      op_type* handler_op(static_cast<op_type*>(op));
-      typedef handler_alloc_traits<Handler, op_type> alloc_traits;
-      handler_ptr<alloc_traits> ptr(handler_op->handler_, handler_op);
-
-      // 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(handler_op->handler_);
-      (void)handler;
-
-      // Free the memory associated with the handler.
-      ptr.reset();
     }
 
-    win_iocp_io_service& io_service_;
+  private:
+    win_iocp_io_service& iocp_service_;
     socket_type socket_;
     socket_holder new_socket_;
     Socket& peer_;
     protocol_type protocol_;
     endpoint_type* peer_endpoint_;
-    boost::asio::io_service::work work_;
     unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
     bool enable_connection_aborted_;
     Handler handler_;
@@ -2061,86 +1567,18 @@
   void async_accept(implementation_type& impl, Socket& peer,
       endpoint_type* peer_endpoint, Handler handler)
   {
-    // Check whether acceptor has been initialised.
-    if (!is_open(impl))
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor));
-      return;
-    }
-
-    // Check that peer socket has not already been opened.
-    if (peer.is_open())
-    {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::already_open));
-      return;
-    }
-
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
-    // Create a new socket for the connection.
-    boost::system::error_code ec;
-    socket_holder sock(socket_ops::socket(impl.protocol_.family(),
-          impl.protocol_.type(), impl.protocol_.protocol(), ec));
-    if (sock.get() == invalid_socket)
-    {
-      this->get_io_service().post(bind_handler(handler, ec));
-      return;
-    }
-
     // Allocate and construct an operation to wrap the handler.
-    typedef accept_operation<Socket, Handler> value_type;
+    typedef accept_op<Socket, Handler> value_type;
     typedef handler_alloc_traits<Handler, value_type> alloc_traits;
     raw_handler_ptr<alloc_traits> raw_ptr(handler);
-    socket_type new_socket = sock.get();
     bool enable_connection_aborted =
       (impl.flags_ & implementation_type::enable_connection_aborted);
-    handler_ptr<alloc_traits> ptr(raw_ptr,
-        iocp_service_, impl.socket_, new_socket, peer, impl.protocol_,
-        peer_endpoint, enable_connection_aborted, handler);
-    sock.release();
-
-    // Accept a connection.
-    DWORD bytes_read = 0;
-    BOOL result = ::AcceptEx(impl.socket_, ptr.get()->new_socket(),
-        ptr.get()->output_buffer(), 0, ptr.get()->address_length(),
-        ptr.get()->address_length(), &bytes_read, ptr.get());
-    DWORD last_error = ::WSAGetLastError();
-
-    // Check if the operation completed immediately.
-    if (!result && last_error != WSA_IO_PENDING)
-    {
-      if (!enable_connection_aborted
-          && (last_error == ERROR_NETNAME_DELETED
-            || last_error == WSAECONNABORTED))
-      {
-        // Post handler so that operation will be restarted again. We do not
-        // perform the AcceptEx again here to avoid the possibility of starving
-        // other handlers.
-        ptr.get()->on_immediate_completion(last_error, 0);
-        ptr.release();
-      }
-      else
-      {
-        boost::asio::io_service::work work(this->get_io_service());
-        ptr.reset();
-        boost::system::error_code ec(last_error,
-            boost::asio::error::get_system_category());
-        iocp_service_.post(bind_handler(handler, ec));
-      }
-    }
-    else
-    {
-      ptr.get()->on_pending();
-      ptr.release();
-    }
+    handler_ptr<alloc_traits> ptr(raw_ptr, iocp_service_, impl.socket_, peer,
+        impl.protocol_, peer_endpoint, enable_connection_aborted, handler);
+
+    start_accept_op(impl, peer.is_open(), ptr.get()->new_socket(),
+        ptr.get()->output_buffer(), ptr.get()->address_length(), ptr.get());
+    ptr.release();
   }
 
   // Connect the socket to the specified endpoint.
@@ -2159,67 +1597,76 @@
     return ec;
   }
 
-  template <typename Handler>
-  class connect_operation
+  class connect_op_base : public reactor_op
   {
   public:
-    connect_operation(socket_type socket, bool user_set_non_blocking,
-        boost::asio::io_service& io_service, Handler handler)
-      : socket_(socket),
-        user_set_non_blocking_(user_set_non_blocking),
-        io_service_(io_service),
-        work_(io_service),
-        handler_(handler)
+    connect_op_base(socket_type socket, func_type complete_func)
+      : reactor_op(&connect_op_base::do_perform, complete_func),
+        socket_(socket)
     {
     }
 
-    bool perform(boost::system::error_code& ec,
-        std::size_t& bytes_transferred)
+    static bool do_perform(reactor_op* base)
     {
-      bytes_transferred = 0;
-
-      // Check whether the operation was successful.
-      if (ec)
-        return true;
+      connect_op_base* o(static_cast<connect_op_base*>(base));
 
       // Get the error code from the connect operation.
       int connect_error = 0;
       size_t connect_error_len = sizeof(connect_error);
-      if (socket_ops::getsockopt(socket_, SOL_SOCKET, SO_ERROR,
-            &connect_error, &connect_error_len, ec) == socket_error_retval)
+      if (socket_ops::getsockopt(o->socket_, SOL_SOCKET, SO_ERROR,
+            &connect_error, &connect_error_len, o->ec_) == socket_error_retval)
         return true;
 
-      // If connection failed then post the handler with the error code.
+      // The connection failed so the handler will be posted with an error code.
       if (connect_error)
       {
-        ec = boost::system::error_code(connect_error,
+        o->ec_ = boost::system::error_code(connect_error,
             boost::asio::error::get_system_category());
-        return true;
       }
 
-      // Revert socket to blocking mode unless the user requested otherwise.
-      if (!user_set_non_blocking_)
-      {
-        ioctl_arg_type non_blocking = 0;
-        if (socket_ops::ioctl(socket_, FIONBIO, &non_blocking, ec))
-          return true;
-      }
-
-      // Post the result of the successful connection operation.
-      ec = boost::system::error_code();
       return true;
     }
 
-    void complete(const boost::system::error_code& ec, std::size_t)
+  private:
+    socket_type socket_;
+  };
+
+  template <typename Handler>
+  class connect_op : public connect_op_base
+  {
+  public:
+    connect_op(socket_type socket, Handler handler)
+      : connect_op_base(socket, &connect_op::do_complete),
+        handler_(handler)
     {
-      io_service_.post(bind_handler(handler_, ec));
+    }
+
+    static void do_complete(io_service_impl* owner, operation* base,
+        boost::system::error_code /*ec*/, std::size_t /*bytes_transferred*/)
+    {
+      // Take ownership of the handler object.
+      connect_op* o(static_cast<connect_op*>(base));
+      typedef handler_alloc_traits<Handler, connect_op> alloc_traits;
+      handler_ptr<alloc_traits> ptr(o->handler_, o);
+
+      // Make the upcall if required.
+      if (owner)
+      {
+        // Make a copy of the handler so that the memory can be deallocated
+        // before the upcall is made. Even if we're not about to make an
+        // upcall, 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.
+        detail::binder1<Handler, boost::system::error_code>
+          handler(o->handler_, o->ec_);
+        ptr.reset();
+        boost::asio::detail::fenced_block b;
+        boost_asio_handler_invoke_helpers::invoke(handler, handler);
+      }
     }
 
   private:
-    socket_type socket_;
-    bool user_set_non_blocking_;
-    boost::asio::io_service& io_service_;
-    boost::asio::io_service::work work_;
     Handler handler_;
   };
 
@@ -2228,86 +1675,216 @@
   void async_connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, Handler handler)
   {
-    if (!is_open(impl))
+    // Allocate and construct an operation to wrap the handler.
+    typedef connect_op<Handler> value_type;
+    typedef handler_alloc_traits<Handler, value_type> alloc_traits;
+    raw_handler_ptr<alloc_traits> raw_ptr(handler);
+    handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_, handler);
+
+    start_connect_op(impl, ptr.get(), peer_endpoint);
+    ptr.release();
+  }
+
+private:
+  // Helper function to start an asynchronous send operation.
+  void start_send_op(implementation_type& impl, WSABUF* buffers,
+      std::size_t buffer_count, socket_base::message_flags flags,
+      bool noop, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
+
+    if (noop)
+      iocp_service_.on_completion(op);
+    else if (!is_open(impl))
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    else
     {
-      this->get_io_service().post(bind_handler(handler,
-            boost::asio::error::bad_descriptor));
-      return;
+      DWORD bytes_transferred = 0;
+      int result = ::WSASend(impl.socket_, buffers,
+          buffer_count, &bytes_transferred, flags, op, 0);
+      DWORD last_error = ::WSAGetLastError();
+      if (last_error == ERROR_PORT_UNREACHABLE)
+        last_error = WSAECONNREFUSED;
+      if (result != 0 && last_error != WSA_IO_PENDING)
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      else
+        iocp_service_.on_pending(op);
     }
+  }
 
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
-    // Update the ID of the thread from which cancellation is safe.
-    if (impl.safe_cancellation_thread_id_ == 0)
-      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
-    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
-      impl.safe_cancellation_thread_id_ = ~DWORD(0);
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+  // Helper function to start an asynchronous send_to operation.
+  void start_send_to_op(implementation_type& impl, WSABUF* buffers,
+      std::size_t buffer_count, const endpoint_type& destination,
+      socket_base::message_flags flags, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
 
-    // Check if the reactor was already obtained from the io_service.
-    reactor_type* reactor = static_cast<reactor_type*>(
-          interlocked_compare_exchange_pointer(
-            reinterpret_cast<void**>(&reactor_), 0, 0));
-    if (!reactor)
+    if (!is_open(impl))
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    else
     {
-      reactor = &(boost::asio::use_service<reactor_type>(
-            this->get_io_service()));
-      interlocked_exchange_pointer(
-          reinterpret_cast<void**>(&reactor_), reactor);
+      DWORD bytes_transferred = 0;
+      int result = ::WSASendTo(impl.socket_, buffers, buffer_count,
+          &bytes_transferred, flags, destination.data(),
+          static_cast<int>(destination.size()), op, 0);
+      DWORD last_error = ::WSAGetLastError();
+      if (last_error == ERROR_PORT_UNREACHABLE)
+        last_error = WSAECONNREFUSED;
+      if (result != 0 && last_error != WSA_IO_PENDING)
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      else
+        iocp_service_.on_pending(op);
     }
+  }
+
+  // Helper function to start an asynchronous receive operation.
+  void start_receive_op(implementation_type& impl, WSABUF* buffers,
+      std::size_t buffer_count, socket_base::message_flags flags,
+      bool noop, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
 
-    // Mark the socket as non-blocking so that the connection will take place
-    // asynchronously.
-    ioctl_arg_type non_blocking = 1;
-    boost::system::error_code ec;
-    if (socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec))
+    if (noop)
+      iocp_service_.on_completion(op);
+    else if (!is_open(impl))
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    else
     {
-      this->get_io_service().post(bind_handler(handler, ec));
-      return;
+      DWORD bytes_transferred = 0;
+      DWORD recv_flags = flags;
+      int result = ::WSARecv(impl.socket_, buffers, buffer_count,
+          &bytes_transferred, &recv_flags, op, 0);
+      DWORD last_error = ::WSAGetLastError();
+      if (last_error == ERROR_NETNAME_DELETED)
+        last_error = WSAECONNRESET;
+      else if (last_error == ERROR_PORT_UNREACHABLE)
+        last_error = WSAECONNREFUSED;
+      if (result != 0 && last_error != WSA_IO_PENDING)
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      else
+        iocp_service_.on_pending(op);
     }
+  }
+
+  // Helper function to start an asynchronous receive_from operation.
+  void start_receive_from_op(implementation_type& impl, WSABUF* buffers,
+      std::size_t buffer_count, endpoint_type& sender_endpoint,
+      socket_base::message_flags flags, int* endpoint_size, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
 
-    // Start the connect operation.
-    if (socket_ops::connect(impl.socket_, peer_endpoint.data(),
-          peer_endpoint.size(), ec) == 0)
-    {
-      // Revert socket to blocking mode unless the user requested otherwise.
-      if (!(impl.flags_ & implementation_type::user_set_non_blocking))
-      {
-        non_blocking = 0;
-        socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ec);
-      }
-
-      // The connect operation has finished successfully so we need to post the
-      // handler immediately.
-      this->get_io_service().post(bind_handler(handler, ec));
-    }
-    else if (ec == boost::asio::error::in_progress
-        || ec == boost::asio::error::would_block)
-    {
-      // The connection is happening in the background, and we need to wait
-      // until the socket becomes writeable.
-      boost::shared_ptr<bool> completed(new bool(false));
-      reactor->start_connect_op(impl.socket_, impl.reactor_data_,
-          connect_operation<Handler>(
-            impl.socket_,
-            (impl.flags_ & implementation_type::user_set_non_blocking) != 0,
-            this->get_io_service(), handler));
+    if (!is_open(impl))
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    else
+    {
+      DWORD bytes_transferred = 0;
+      DWORD recv_flags = flags;
+      int result = ::WSARecvFrom(impl.socket_, buffers,
+          buffer_count, &bytes_transferred, &recv_flags,
+          sender_endpoint.data(), endpoint_size, op, 0);
+      DWORD last_error = ::WSAGetLastError();
+      if (last_error == ERROR_PORT_UNREACHABLE)
+        last_error = WSAECONNREFUSED;
+      if (result != 0 && last_error != WSA_IO_PENDING)
+        iocp_service_.on_completion(op, last_error, bytes_transferred);
+      else
+        iocp_service_.on_pending(op);
     }
+  }
+
+  // Helper function to start an asynchronous receive_from operation.
+  void start_accept_op(implementation_type& impl,
+      bool peer_is_open, socket_holder& new_socket,
+      void* output_buffer, DWORD address_length, operation* op)
+  {
+    update_cancellation_thread_id();
+    iocp_service_.work_started();
+
+    if (!is_open(impl))
+      iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+    else if (peer_is_open)
+      iocp_service_.on_completion(op, boost::asio::error::already_open);
     else
     {
-      // Revert socket to blocking mode unless the user requested otherwise.
-      if (!(impl.flags_ & implementation_type::user_set_non_blocking))
+      boost::system::error_code ec;
+      new_socket.reset(socket_ops::socket(impl.protocol_.family(),
+            impl.protocol_.type(), impl.protocol_.protocol(), ec));
+      if (new_socket.get() == invalid_socket)
+        iocp_service_.on_completion(op, ec);
+      else
       {
-        non_blocking = 0;
-        boost::system::error_code ignored_ec;
-        socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec);
+        DWORD bytes_read = 0;
+        BOOL result = ::AcceptEx(impl.socket_, new_socket.get(), output_buffer,
+            0, address_length, address_length, &bytes_read, op);
+        DWORD last_error = ::WSAGetLastError();
+        if (!result && last_error != WSA_IO_PENDING)
+          iocp_service_.on_completion(op, last_error);
+        else
+          iocp_service_.on_pending(op);
       }
+    }
+  }
+
+  // Start an asynchronous read or write operation using the the reactor.
+  void start_reactor_op(implementation_type& impl, int op_type, reactor_op* op)
+  {
+    reactor& r = get_reactor();
+    update_cancellation_thread_id();
 
-      // The connect operation has failed, so post the handler immediately.
-      this->get_io_service().post(bind_handler(handler, ec));
+    if (is_open(impl))
+    {
+      r.start_op(op_type, impl.socket_, impl.reactor_data_, op, false);
+      return;
     }
+    else
+      op->ec_ = boost::asio::error::bad_descriptor;
+
+    iocp_service_.post_immediate_completion(op);
+  }
+
+  // Start the asynchronous connect operation using the reactor.
+  void start_connect_op(implementation_type& impl,
+      reactor_op* op, const endpoint_type& peer_endpoint)
+  {
+    reactor& r = get_reactor();
+    update_cancellation_thread_id();
+
+    if (is_open(impl))
+    {
+      ioctl_arg_type non_blocking = 1;
+      if (!socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_))
+      {
+        if (socket_ops::connect(impl.socket_, peer_endpoint.data(),
+              peer_endpoint.size(), op->ec_) != 0)
+        {
+          if (!op->ec_
+              && !(impl.flags_ & implementation_type::user_set_non_blocking))
+          {
+            non_blocking = 0;
+            socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, op->ec_);
+          }
+
+          if (op->ec_ == boost::asio::error::in_progress
+              || op->ec_ == boost::asio::error::would_block)
+          {
+            op->ec_ = boost::system::error_code();
+            r.start_op(reactor::connect_op, impl.socket_,
+                impl.reactor_data_, op, true);
+            return;
+          }
+        }
+      }
+    }
+    else
+      op->ec_ = boost::asio::error::bad_descriptor;
+
+    iocp_service_.post_immediate_completion(op);
   }
 
-private:
   // Helper function to close a socket when the associated object is being
   // destroyed.
   void close_for_destruction(implementation_type& impl)
@@ -2317,11 +1894,11 @@
       // Check if the reactor was created, in which case we need to close the
       // socket on the reactor as well to cancel any operations that might be
       // running there.
-      reactor_type* reactor = static_cast<reactor_type*>(
+      reactor* r = static_cast<reactor*>(
             interlocked_compare_exchange_pointer(
               reinterpret_cast<void**>(&reactor_), 0, 0));
-      if (reactor)
-        reactor->close_descriptor(impl.socket_, impl.reactor_data_);
+      if (r)
+        r->close_descriptor(impl.socket_, impl.reactor_data_);
 
       // The socket destructor must not block. If the user has changed the
       // linger option to block in the foreground, we will change it back to the
@@ -2347,6 +1924,33 @@
     }
   }
 
+  // Update the ID of the thread from which cancellation is safe.
+  void update_cancellation_thread_id()
+  {
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+    if (impl.safe_cancellation_thread_id_ == 0)
+      impl.safe_cancellation_thread_id_ = ::GetCurrentThreadId();
+    else if (impl.safe_cancellation_thread_id_ != ::GetCurrentThreadId())
+      impl.safe_cancellation_thread_id_ = ~DWORD(0);
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+  }
+
+  // Helper function to get the reactor. If no reactor has been created yet, a
+  // new one is obtained from the io_service and a pointer to it is cached in
+  // this service.
+  reactor& get_reactor()
+  {
+    reactor* r = static_cast<reactor*>(
+          interlocked_compare_exchange_pointer(
+            reinterpret_cast<void**>(&reactor_), 0, 0));
+    if (!r)
+    {
+      r = &(use_service<reactor>(io_service_));
+      interlocked_exchange_pointer(reinterpret_cast<void**>(&reactor_), r);
+    }
+    return *r;
+  }
+
   // Helper function to emulate InterlockedCompareExchangePointer functionality
   // for:
   // - very old Platform SDKs; and
@@ -2375,13 +1979,16 @@
 #endif
   }
 
+  // The io_service used to obtain the reactor, if required.
+  boost::asio::io_service& io_service_;
+
   // The IOCP service used for running asynchronous operations and dispatching
   // handlers.
   win_iocp_io_service& iocp_service_;
 
   // The reactor used for performing connect operations. This object is created
   // only if needed.
-  reactor_type* reactor_;
+  reactor* reactor_;
 
   // Mutex to protect access to the linked list of implementations. 
   boost::asio::detail::mutex mutex_;
Modified: trunk/boost/asio/detail/win_mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/win_mutex.hpp	(original)
+++ trunk/boost/asio/detail/win_mutex.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -66,15 +66,7 @@
   // Lock the mutex.
   void lock()
   {
-    int error = do_lock();
-    if (error != 0)
-    {
-      boost::system::system_error e(
-          boost::system::error_code(error,
-            boost::asio::error::get_system_category()),
-          "mutex");
-      boost::throw_exception(e);
-    }
+    ::EnterCriticalSection(&crit_section_);
   }
 
   // Unlock the mutex.
@@ -92,12 +84,12 @@
 #if defined(__MINGW32__)
     // Not sure if MinGW supports structured exception handling, so for now
     // we'll just call the Windows API and hope.
-    ::InitializeCriticalSection(&crit_section_);
+    ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
     return 0;
 #else
     __try
     {
-      ::InitializeCriticalSection(&crit_section_);
+      ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
     }
     __except(GetExceptionCode() == STATUS_NO_MEMORY
         ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
@@ -109,34 +101,6 @@
 #endif
   }
 
-  // Locking must be performed in a separate function to lock() since the
-  // compiler does not support the use of structured exceptions and C++
-  // exceptions in the same function.
-  int do_lock()
-  {
-#if defined(__MINGW32__)
-    // Not sure if MinGW supports structured exception handling, so for now
-    // we'll just call the Windows API and hope.
-    ::EnterCriticalSection(&crit_section_);
-    return 0;
-#else
-    __try
-    {
-      ::EnterCriticalSection(&crit_section_);
-    }
-    __except(GetExceptionCode() == STATUS_INVALID_HANDLE
-        || GetExceptionCode() == STATUS_NO_MEMORY
-        ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
-    {
-      if (GetExceptionCode() == STATUS_NO_MEMORY)
-        return ERROR_OUTOFMEMORY;
-      return ERROR_INVALID_HANDLE;
-    }
-
-    return 0;
-#endif
-  }
-
   ::CRITICAL_SECTION crit_section_;
 };
 
Modified: trunk/boost/asio/impl/io_service.ipp
==============================================================================
--- trunk/boost/asio/impl/io_service.ipp	(original)
+++ trunk/boost/asio/impl/io_service.ipp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -26,18 +26,9 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_io_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/task_io_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/task_io_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/task_io_service.hpp>
 #else
-# include <boost/asio/detail/select_reactor.hpp>
 # include <boost/asio/detail/task_io_service.hpp>
+# include <boost/asio/detail/reactor.hpp>
 #endif
 
 namespace boost {
@@ -176,7 +167,6 @@
 
 inline io_service::service::service(boost::asio::io_service& owner)
   : owner_(owner),
-    type_info_(0),
     next_(0)
 {
 }
Modified: trunk/boost/asio/impl/read.ipp
==============================================================================
--- trunk/boost/asio/impl/read.ipp	(original)
+++ trunk/boost/asio/impl/read.ipp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -24,6 +24,7 @@
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/completion_condition.hpp>
 #include <boost/asio/error.hpp>
+#include <boost/asio/detail/base_from_completion_cond.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/consuming_buffers.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
@@ -42,14 +43,14 @@
   boost::asio::detail::consuming_buffers<
     mutable_buffer, MutableBufferSequence> tmp(buffers);
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   while (tmp.begin() != tmp.end())
   {
     std::size_t bytes_transferred = s.read_some(tmp, ec);
     tmp.consume(bytes_transferred);
     total_transferred += bytes_transferred;
-    tmp.set_max_size(detail::adapt_completion_condition_result(
+    tmp.prepare(detail::adapt_completion_condition_result(
           completion_condition(ec, total_transferred)));
   }
   return total_transferred;
@@ -130,51 +131,111 @@
 {
   template <typename AsyncReadStream, typename MutableBufferSequence,
       typename CompletionCondition, typename ReadHandler>
-  class read_handler
+  class read_op
+    : detail::base_from_completion_cond<CompletionCondition>
   {
   public:
-    typedef boost::asio::detail::consuming_buffers<
-      mutable_buffer, MutableBufferSequence> buffers_type;
-
-    read_handler(AsyncReadStream& stream, const buffers_type& buffers,
+    read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
         CompletionCondition completion_condition, ReadHandler handler)
-      : stream_(stream),
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
         buffers_(buffers),
         total_transferred_(0),
-        completion_condition_(completion_condition),
-        handler_(handler)
+        handler_(handler),
+        start_(true)
     {
     }
 
     void operator()(const boost::system::error_code& ec,
         std::size_t bytes_transferred)
     {
-      total_transferred_ += bytes_transferred;
-      buffers_.consume(bytes_transferred);
-      buffers_.set_max_size(detail::adapt_completion_condition_result(
-            completion_condition_(ec, total_transferred_)));
-      if (buffers_.begin() == buffers_.end())
+      switch (start_)
       {
+        case true: start_ = false;
+        buffers_.prepare(this->check(ec, total_transferred_));
+        for (;;)
+        {
+          stream_.async_read_some(buffers_, *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          buffers_.consume(bytes_transferred);
+          buffers_.prepare(this->check(ec, total_transferred_));
+          if ((!ec && bytes_transferred == 0)
+              || buffers_.begin() == buffers_.end())
+            break;
+        }
+
         handler_(ec, total_transferred_);
       }
-      else
+    }
+
+  //private:
+    AsyncReadStream& stream_;
+    boost::asio::detail::consuming_buffers<
+      mutable_buffer, MutableBufferSequence> buffers_;
+    std::size_t total_transferred_;
+    ReadHandler handler_;
+    bool start_;
+  };
+
+  template <typename AsyncReadStream,
+      typename CompletionCondition, typename ReadHandler>
+  class read_op<AsyncReadStream, boost::asio::mutable_buffers_1,
+      CompletionCondition, ReadHandler>
+    : detail::base_from_completion_cond<CompletionCondition>
+  {
+  public:
+    read_op(AsyncReadStream& stream,
+        const boost::asio::mutable_buffers_1& buffers,
+        CompletionCondition completion_condition,
+        ReadHandler handler)
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
+        buffer_(buffers),
+        total_transferred_(0),
+        handler_(handler),
+        start_(true)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      std::size_t n = 0;
+      switch (start_)
       {
-        stream_.async_read_some(buffers_, *this);
+        case true: start_ = false;
+        n = this->check(ec, total_transferred_);
+        for (;;)
+        {
+          stream_.async_read_some(boost::asio::buffer(
+                buffer_ + total_transferred_, n), *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          if ((!ec && bytes_transferred == 0)
+              || (n = this->check(ec, total_transferred_)) == 0
+              || total_transferred_ == boost::asio::buffer_size(buffer_))
+            break;
+        }
+
+        handler_(ec, total_transferred_);
       }
     }
 
   //private:
     AsyncReadStream& stream_;
-    buffers_type buffers_;
+    boost::asio::mutable_buffer buffer_;
     std::size_t total_transferred_;
-    CompletionCondition completion_condition_;
     ReadHandler handler_;
+    bool start_;
   };
 
   template <typename AsyncReadStream, typename MutableBufferSequence,
       typename CompletionCondition, typename ReadHandler>
   inline void* asio_handler_allocate(std::size_t size,
-      read_handler<AsyncReadStream, MutableBufferSequence,
+      read_op<AsyncReadStream, MutableBufferSequence,
         CompletionCondition, ReadHandler>* this_handler)
   {
     return boost_asio_handler_alloc_helpers::allocate(
@@ -184,7 +245,7 @@
   template <typename AsyncReadStream, typename MutableBufferSequence,
       typename CompletionCondition, typename ReadHandler>
   inline void asio_handler_deallocate(void* pointer, std::size_t size,
-      read_handler<AsyncReadStream, MutableBufferSequence,
+      read_op<AsyncReadStream, MutableBufferSequence,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_alloc_helpers::deallocate(
@@ -195,7 +256,7 @@
       typename MutableBufferSequence, typename CompletionCondition,
       typename ReadHandler>
   inline void asio_handler_invoke(const Function& function,
-      read_handler<AsyncReadStream, MutableBufferSequence,
+      read_op<AsyncReadStream, MutableBufferSequence,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_invoke_helpers::invoke(
@@ -208,24 +269,10 @@
 inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
     CompletionCondition completion_condition, ReadHandler handler)
 {
-  boost::asio::detail::consuming_buffers<
-    mutable_buffer, MutableBufferSequence> tmp(buffers);
-
-  boost::system::error_code ec;
-  std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
-        completion_condition(ec, total_transferred)));
-  if (tmp.begin() == tmp.end())
-  {
-    s.get_io_service().post(detail::bind_handler(
-          handler, ec, total_transferred));
-    return;
-  }
-
-  s.async_read_some(tmp,
-      detail::read_handler<AsyncReadStream, MutableBufferSequence,
-        CompletionCondition, ReadHandler>(
-          s, tmp, completion_condition, handler));
+  detail::read_op<AsyncReadStream, MutableBufferSequence,
+    CompletionCondition, ReadHandler>(
+      s, buffers, completion_condition, handler)(
+        boost::system::error_code(), 0);
 }
 
 template <typename AsyncReadStream, typename MutableBufferSequence,
@@ -242,52 +289,64 @@
 {
   template <typename AsyncReadStream, typename Allocator,
       typename CompletionCondition, typename ReadHandler>
-  class read_streambuf_handler
+  class read_streambuf_op
+    : detail::base_from_completion_cond<CompletionCondition>
   {
   public:
-    read_streambuf_handler(AsyncReadStream& stream,
+    read_streambuf_op(AsyncReadStream& stream,
         basic_streambuf<Allocator>& streambuf,
         CompletionCondition completion_condition, ReadHandler handler)
-      : stream_(stream),
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
         streambuf_(streambuf),
         total_transferred_(0),
-        completion_condition_(completion_condition),
-        handler_(handler)
+        handler_(handler),
+        start_(true)
     {
     }
 
     void operator()(const boost::system::error_code& ec,
         std::size_t bytes_transferred)
     {
-      total_transferred_ += bytes_transferred;
-      streambuf_.commit(bytes_transferred);
-      std::size_t max_size = detail::adapt_completion_condition_result(
-            completion_condition_(ec, total_transferred_));
-      std::size_t bytes_available = std::min<std::size_t>(512,
-          std::min<std::size_t>(max_size,
-            streambuf_.max_size() - streambuf_.size()));
-      if (bytes_available == 0)
+      std::size_t max_size, bytes_available;
+      switch (start_)
       {
+        case true: start_ = false;
+        max_size = this->check(ec, total_transferred_);
+        bytes_available = std::min<std::size_t>(512,
+            std::min<std::size_t>(max_size,
+              streambuf_.max_size() - streambuf_.size()));
+        for (;;)
+        {
+          stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          streambuf_.commit(bytes_transferred);
+          max_size = this->check(ec, total_transferred_);
+          bytes_available = std::min<std::size_t>(512,
+              std::min<std::size_t>(max_size,
+                streambuf_.max_size() - streambuf_.size()));
+          if ((!ec && bytes_transferred == 0) || bytes_available == 0)
+            break;
+        }
+
         handler_(ec, total_transferred_);
       }
-      else
-      {
-        stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
-      }
     }
 
   //private:
     AsyncReadStream& stream_;
     boost::asio::basic_streambuf<Allocator>& streambuf_;
     std::size_t total_transferred_;
-    CompletionCondition completion_condition_;
     ReadHandler handler_;
+    bool start_;
   };
 
   template <typename AsyncReadStream, typename Allocator,
       typename CompletionCondition, typename ReadHandler>
   inline void* asio_handler_allocate(std::size_t size,
-      read_streambuf_handler<AsyncReadStream, Allocator,
+      read_streambuf_op<AsyncReadStream, Allocator,
         CompletionCondition, ReadHandler>* this_handler)
   {
     return boost_asio_handler_alloc_helpers::allocate(
@@ -297,7 +356,7 @@
   template <typename AsyncReadStream, typename Allocator,
       typename CompletionCondition, typename ReadHandler>
   inline void asio_handler_deallocate(void* pointer, std::size_t size,
-      read_streambuf_handler<AsyncReadStream, Allocator,
+      read_streambuf_op<AsyncReadStream, Allocator,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_alloc_helpers::deallocate(
@@ -307,7 +366,7 @@
   template <typename Function, typename AsyncReadStream,
       typename Allocator, typename CompletionCondition, typename ReadHandler>
   inline void asio_handler_invoke(const Function& function,
-      read_streambuf_handler<AsyncReadStream, Allocator,
+      read_streambuf_op<AsyncReadStream, Allocator,
         CompletionCondition, ReadHandler>* this_handler)
   {
     boost_asio_handler_invoke_helpers::invoke(
@@ -321,23 +380,10 @@
     boost::asio::basic_streambuf<Allocator>& b,
     CompletionCondition completion_condition, ReadHandler handler)
 {
-  boost::system::error_code ec;
-  std::size_t total_transferred = 0;
-  std::size_t max_size = detail::adapt_completion_condition_result(
-        completion_condition(ec, total_transferred));
-  std::size_t bytes_available = std::min<std::size_t>(512,
-      std::min<std::size_t>(max_size, b.max_size() - b.size()));
-  if (bytes_available == 0)
-  {
-    s.get_io_service().post(detail::bind_handler(
-          handler, ec, total_transferred));
-    return;
-  }
-
-  s.async_read_some(b.prepare(bytes_available),
-      detail::read_streambuf_handler<AsyncReadStream, Allocator,
-        CompletionCondition, ReadHandler>(
-          s, b, completion_condition, handler));
+  detail::read_streambuf_op<AsyncReadStream,
+    Allocator, CompletionCondition, ReadHandler>(
+      s, b, completion_condition, handler)(
+        boost::system::error_code(), 0);
 }
 
 template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
Modified: trunk/boost/asio/impl/read_at.ipp
==============================================================================
--- trunk/boost/asio/impl/read_at.ipp	(original)
+++ trunk/boost/asio/impl/read_at.ipp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -43,7 +43,7 @@
   boost::asio::detail::consuming_buffers<
     mutable_buffer, MutableBufferSequence> tmp(buffers);
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   while (tmp.begin() != tmp.end())
   {
@@ -51,7 +51,7 @@
         offset + total_transferred, tmp, ec);
     tmp.consume(bytes_transferred);
     total_transferred += bytes_transferred;
-    tmp.set_max_size(detail::adapt_completion_condition_result(
+    tmp.prepare(detail::adapt_completion_condition_result(
           completion_condition(ec, total_transferred)));
   }
   return total_transferred;
@@ -158,7 +158,7 @@
     {
       total_transferred_ += bytes_transferred;
       buffers_.consume(bytes_transferred);
-      buffers_.set_max_size(detail::adapt_completion_condition_result(
+      buffers_.prepare(detail::adapt_completion_condition_result(
             completion_condition_(ec, total_transferred_)));
       if (buffers_.begin() == buffers_.end())
       {
@@ -225,7 +225,7 @@
 
   boost::system::error_code ec;
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   if (tmp.begin() == tmp.end())
   {
Modified: trunk/boost/asio/impl/write.ipp
==============================================================================
--- trunk/boost/asio/impl/write.ipp	(original)
+++ trunk/boost/asio/impl/write.ipp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -19,6 +19,7 @@
 
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/completion_condition.hpp>
+#include <boost/asio/detail/base_from_completion_cond.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/consuming_buffers.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
@@ -37,14 +38,14 @@
   boost::asio::detail::consuming_buffers<
     const_buffer, ConstBufferSequence> tmp(buffers);
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   while (tmp.begin() != tmp.end())
   {
     std::size_t bytes_transferred = s.write_some(tmp, ec);
     tmp.consume(bytes_transferred);
     total_transferred += bytes_transferred;
-    tmp.set_max_size(detail::adapt_completion_condition_result(
+    tmp.prepare(detail::adapt_completion_condition_result(
           completion_condition(ec, total_transferred)));
   }
   return total_transferred;
@@ -111,51 +112,164 @@
 {
   template <typename AsyncWriteStream, typename ConstBufferSequence,
       typename CompletionCondition, typename WriteHandler>
-  class write_handler
+  class write_op
+    : detail::base_from_completion_cond<CompletionCondition>
   {
   public:
-    typedef boost::asio::detail::consuming_buffers<
-      const_buffer, ConstBufferSequence> buffers_type;
-
-    write_handler(AsyncWriteStream& stream, const buffers_type& buffers,
+    write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
         CompletionCondition completion_condition, WriteHandler handler)
-      : stream_(stream),
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
         buffers_(buffers),
         total_transferred_(0),
-        completion_condition_(completion_condition),
-        handler_(handler)
+        handler_(handler),
+        start_(true)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      switch (start_)
+      {
+        case true: start_ = false;
+        buffers_.prepare(this->check(ec, total_transferred_));
+        for (;;)
+        {
+          stream_.async_write_some(buffers_, *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          buffers_.consume(bytes_transferred);
+          buffers_.prepare(this->check(ec, total_transferred_));
+          if ((!ec && bytes_transferred == 0)
+              || buffers_.begin() == buffers_.end())
+            break;
+        }
+
+        handler_(ec, total_transferred_);
+      }
+    }
+
+  //private:
+    AsyncWriteStream& stream_;
+    boost::asio::detail::consuming_buffers<
+      const_buffer, ConstBufferSequence> buffers_;
+    std::size_t total_transferred_;
+    WriteHandler handler_;
+    bool start_;
+  };
+
+  template <typename AsyncWriteStream,
+      typename CompletionCondition, typename WriteHandler>
+  class write_op<AsyncWriteStream, boost::asio::mutable_buffers_1,
+      CompletionCondition, WriteHandler>
+    : detail::base_from_completion_cond<CompletionCondition>
+  {
+  public:
+    write_op(AsyncWriteStream& stream,
+        const boost::asio::mutable_buffers_1& buffers,
+        CompletionCondition completion_condition,
+        WriteHandler handler)
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
+        buffer_(buffers),
+        total_transferred_(0),
+        handler_(handler),
+        start_(true)
     {
     }
 
     void operator()(const boost::system::error_code& ec,
         std::size_t bytes_transferred)
     {
-      total_transferred_ += bytes_transferred;
-      buffers_.consume(bytes_transferred);
-      buffers_.set_max_size(detail::adapt_completion_condition_result(
-            completion_condition_(ec, total_transferred_)));
-      if (buffers_.begin() == buffers_.end())
+      std::size_t n = 0;
+      switch (start_)
       {
+        case true: start_ = false;
+        n = this->check(ec, total_transferred_);
+        for (;;)
+        {
+          stream_.async_write_some(boost::asio::buffer(
+                buffer_ + total_transferred_, n), *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          if ((!ec && bytes_transferred == 0)
+              || (n = this->check(ec, total_transferred_)) == 0
+              || total_transferred_ == boost::asio::buffer_size(buffer_))
+            break;
+        }
+
         handler_(ec, total_transferred_);
       }
-      else
+    }
+
+  //private:
+    AsyncWriteStream& stream_;
+    boost::asio::mutable_buffer buffer_;
+    std::size_t total_transferred_;
+    WriteHandler handler_;
+    bool start_;
+  };
+
+  template <typename AsyncWriteStream,
+      typename CompletionCondition, typename WriteHandler>
+  class write_op<AsyncWriteStream, boost::asio::const_buffers_1,
+      CompletionCondition, WriteHandler>
+    : detail::base_from_completion_cond<CompletionCondition>
+  {
+  public:
+    write_op(AsyncWriteStream& stream,
+        const boost::asio::const_buffers_1& buffers,
+        CompletionCondition completion_condition,
+        WriteHandler handler)
+      : detail::base_from_completion_cond<
+          CompletionCondition>(completion_condition),
+        stream_(stream),
+        buffer_(buffers),
+        total_transferred_(0),
+        handler_(handler),
+        start_(true)
+    {
+    }
+
+    void operator()(const boost::system::error_code& ec,
+        std::size_t bytes_transferred)
+    {
+      std::size_t n = 0;
+      switch (start_)
       {
-        stream_.async_write_some(buffers_, *this);
+        case true: start_ = false;
+        n = this->check(ec, total_transferred_);
+        for (;;)
+        {
+          stream_.async_write_some(boost::asio::buffer(
+                buffer_ + total_transferred_, n), *this);
+          return; default:
+          total_transferred_ += bytes_transferred;
+          if ((!ec && bytes_transferred == 0)
+              || (n = this->check(ec, total_transferred_)) == 0
+              || total_transferred_ == boost::asio::buffer_size(buffer_))
+            break;
+        }
+
+        handler_(ec, total_transferred_);
       }
     }
 
   //private:
     AsyncWriteStream& stream_;
-    buffers_type buffers_;
+    boost::asio::const_buffer buffer_;
     std::size_t total_transferred_;
-    CompletionCondition completion_condition_;
     WriteHandler handler_;
+    bool start_;
   };
 
   template <typename AsyncWriteStream, typename ConstBufferSequence,
       typename CompletionCondition, typename WriteHandler>
   inline void* asio_handler_allocate(std::size_t size,
-      write_handler<AsyncWriteStream, ConstBufferSequence,
+      write_op<AsyncWriteStream, ConstBufferSequence,
         CompletionCondition, WriteHandler>* this_handler)
   {
     return boost_asio_handler_alloc_helpers::allocate(
@@ -165,7 +279,7 @@
   template <typename AsyncWriteStream, typename ConstBufferSequence,
       typename CompletionCondition, typename WriteHandler>
   inline void asio_handler_deallocate(void* pointer, std::size_t size,
-      write_handler<AsyncWriteStream, ConstBufferSequence,
+      write_op<AsyncWriteStream, ConstBufferSequence,
         CompletionCondition, WriteHandler>* this_handler)
   {
     boost_asio_handler_alloc_helpers::deallocate(
@@ -176,7 +290,7 @@
       typename ConstBufferSequence, typename CompletionCondition,
       typename WriteHandler>
   inline void asio_handler_invoke(const Function& function,
-      write_handler<AsyncWriteStream, ConstBufferSequence,
+      write_op<AsyncWriteStream, ConstBufferSequence,
         CompletionCondition, WriteHandler>* this_handler)
   {
     boost_asio_handler_invoke_helpers::invoke(
@@ -189,24 +303,10 @@
 inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
     CompletionCondition completion_condition, WriteHandler handler)
 {
-  boost::asio::detail::consuming_buffers<
-    const_buffer, ConstBufferSequence> tmp(buffers);
-
-  boost::system::error_code ec;
-  std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
-        completion_condition(ec, total_transferred)));
-  if (tmp.begin() == tmp.end())
-  {
-    s.get_io_service().post(detail::bind_handler(
-          handler, ec, total_transferred));
-    return;
-  }
-
-  s.async_write_some(tmp,
-      detail::write_handler<AsyncWriteStream, ConstBufferSequence,
-        CompletionCondition, WriteHandler>(
-          s, tmp, completion_condition, handler));
+  detail::write_op<AsyncWriteStream, ConstBufferSequence,
+    CompletionCondition, WriteHandler>(
+      s, buffers, completion_condition, handler)(
+        boost::system::error_code(), 0);
 }
 
 template <typename AsyncWriteStream, typename ConstBufferSequence,
Modified: trunk/boost/asio/impl/write_at.ipp
==============================================================================
--- trunk/boost/asio/impl/write_at.ipp	(original)
+++ trunk/boost/asio/impl/write_at.ipp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -38,7 +38,7 @@
   boost::asio::detail::consuming_buffers<
     const_buffer, ConstBufferSequence> tmp(buffers);
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   while (tmp.begin() != tmp.end())
   {
@@ -46,7 +46,7 @@
         offset + total_transferred, tmp, ec);
     tmp.consume(bytes_transferred);
     total_transferred += bytes_transferred;
-    tmp.set_max_size(detail::adapt_completion_condition_result(
+    tmp.prepare(detail::adapt_completion_condition_result(
           completion_condition(ec, total_transferred)));
   }
   return total_transferred;
@@ -142,7 +142,7 @@
     {
       total_transferred_ += bytes_transferred;
       buffers_.consume(bytes_transferred);
-      buffers_.set_max_size(detail::adapt_completion_condition_result(
+      buffers_.prepare(detail::adapt_completion_condition_result(
             completion_condition_(ec, total_transferred_)));
       if (buffers_.begin() == buffers_.end())
       {
@@ -207,7 +207,7 @@
 
   boost::system::error_code ec;
   std::size_t total_transferred = 0;
-  tmp.set_max_size(detail::adapt_completion_condition_result(
+  tmp.prepare(detail::adapt_completion_condition_result(
         completion_condition(ec, total_transferred)));
   if (tmp.begin() == tmp.end())
   {
Modified: trunk/boost/asio/io_service.hpp
==============================================================================
--- trunk/boost/asio/io_service.hpp	(original)
+++ trunk/boost/asio/io_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -26,11 +26,8 @@
 #include <boost/system/error_code.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/detail/dev_poll_reactor_fwd.hpp>
-#include <boost/asio/detail/epoll_reactor_fwd.hpp>
-#include <boost/asio/detail/kqueue_reactor_fwd.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/select_reactor_fwd.hpp>
+#include <boost/asio/detail/reactor_fwd.hpp>
 #include <boost/asio/detail/service_registry_fwd.hpp>
 #include <boost/asio/detail/signal_init.hpp>
 #include <boost/asio/detail/task_io_service_fwd.hpp>
@@ -46,6 +43,12 @@
 template <typename Service> void add_service(io_service& ios, Service* svc);
 template <typename Service> bool has_service(io_service& ios);
 
+#if defined(BOOST_ASIO_HAS_IOCP)
+namespace detail { typedef win_iocp_io_service io_service_impl; }
+#else
+namespace detail { typedef task_io_service<reactor> io_service_impl; }
+#endif
+
 /// Provides core I/O functionality.
 /**
  * The io_service class provides the core I/O functionality for users of the
@@ -178,18 +181,9 @@
   : private noncopyable
 {
 private:
-  // The type of the platform-specific implementation.
+  typedef detail::io_service_impl impl_type;
 #if defined(BOOST_ASIO_HAS_IOCP)
-  typedef detail::win_iocp_io_service impl_type;
   friend class detail::win_iocp_overlapped_ptr;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::task_io_service<detail::epoll_reactor<false> > impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::task_io_service<detail::kqueue_reactor<false> > impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::task_io_service<detail::dev_poll_reactor<false> > impl_type;
-#else
-  typedef detail::task_io_service<detail::select_reactor<false> > impl_type;
 #endif
 
 public:
@@ -606,9 +600,14 @@
   virtual void shutdown_service() = 0;
 
   friend class boost::asio::detail::service_registry;
+  struct key
+  {
+    key() : type_info_(0), id_(0) {}
+    const std::type_info* type_info_;
+    const boost::asio::io_service::id* id_;
+  } key_;
+
   boost::asio::io_service& owner_;
-  const std::type_info* type_info_;
-  const boost::asio::io_service::id* id_;
   service* next_;
 };
 
Modified: trunk/boost/asio/ip/basic_resolver_iterator.hpp
==============================================================================
--- trunk/boost/asio/ip/basic_resolver_iterator.hpp	(original)
+++ trunk/boost/asio/ip/basic_resolver_iterator.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -18,8 +18,7 @@
 #include <boost/asio/detail/push_options.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/iterator/iterator_facade.hpp>
-#include <boost/optional.hpp>
+#include <boost/iterator.hpp>
 #include <boost/shared_ptr.hpp>
 #include <cstring>
 #include <string>
@@ -48,14 +47,18 @@
  */
 template <typename InternetProtocol>
 class basic_resolver_iterator
-  : public boost::iterator_facade<
-        basic_resolver_iterator<InternetProtocol>,
-        const basic_resolver_entry<InternetProtocol>,
-        boost::forward_traversal_tag>
+#if defined(GENERATING_DOCUMENTATION)
+  : public std::iterator<
+#else // defined(GENERATING_DOCUMENTATION)
+  : public boost::iterator<
+#endif // defined(GENERATING_DOCUMENTATION)
+      std::forward_iterator_tag,
+      const basic_resolver_entry<InternetProtocol> >
 {
 public:
   /// Default constructor creates an end iterator.
   basic_resolver_iterator()
+    : index_(0)
   {
   }
 
@@ -91,11 +94,6 @@
       address_info = address_info->ai_next;
     }
 
-    if (iter.values_->size())
-      iter.iter_ = iter.values_->begin();
-    else
-      iter.values_.reset();
-
     return iter;
   }
 
@@ -109,21 +107,58 @@
     iter.values_->push_back(
         basic_resolver_entry<InternetProtocol>(
           endpoint, host_name, service_name));
-    iter.iter_ = iter.values_->begin();
     return iter;
   }
 
-private:
-  friend class boost::iterator_core_access;
+  /// Dereference an iterator.
+  const basic_resolver_entry<InternetProtocol>& operator*() const
+  {
+    return dereference();
+  }
+
+  /// Dereference an iterator.
+  const basic_resolver_entry<InternetProtocol>* operator->() const
+  {
+    return &dereference();
+  }
+
+  /// Increment operator (prefix).
+  basic_resolver_iterator& operator++()
+  {
+    increment();
+    return *this;
+  }
 
+  /// Increment operator (postfix).
+  basic_resolver_iterator operator++(int)
+  {
+    basic_resolver_iterator tmp(*this);
+    ++*this;
+    return tmp;
+  }
+
+  /// Test two iterators for equality.
+  friend bool operator==(const basic_resolver_iterator& a,
+      const basic_resolver_iterator& b)
+  {
+    return a.equal(b);
+  }
+
+  /// Test two iterators for inequality.
+  friend bool operator!=(const basic_resolver_iterator& a,
+      const basic_resolver_iterator& b)
+  {
+    return !a.equal(b);
+  }
+
+private:
   void increment()
   {
-    if (++*iter_ == values_->end())
+    if (++index_ == values_->size())
     {
       // Reset state to match a default constructed end iterator.
       values_.reset();
-      typedef typename values_type::const_iterator values_iterator_type;
-      iter_.reset();
+      index_ = 0;
     }
   }
 
@@ -133,18 +168,17 @@
       return true;
     if (values_ != other.values_)
       return false;
-    return *iter_ == *other.iter_;
+    return index_ == other.index_;
   }
 
   const basic_resolver_entry<InternetProtocol>& dereference() const
   {
-    return **iter_;
+    return (*values_)[index_];
   }
 
   typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
-  typedef typename values_type::const_iterator values_iter_type;
   boost::shared_ptr<values_type> values_;
-  boost::optional<values_iter_type> iter_;
+  std::size_t index_;
 };
 
 } // namespace ip
Modified: trunk/boost/asio/posix/stream_descriptor_service.hpp
==============================================================================
--- trunk/boost/asio/posix/stream_descriptor_service.hpp	(original)
+++ trunk/boost/asio/posix/stream_descriptor_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -35,19 +35,7 @@
 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
   || defined(GENERATING_DOCUMENTATION)
 
-#if defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/reactive_descriptor_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/reactive_descriptor_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/reactive_descriptor_service.hpp>
-#else
-# include <boost/asio/detail/select_reactor.hpp>
-# include <boost/asio/detail/reactive_descriptor_service.hpp>
-#endif
+#include <boost/asio/detail/reactive_descriptor_service.hpp>
 
 namespace boost {
 namespace asio {
@@ -69,19 +57,7 @@
 
 private:
   // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_descriptor_service<
-      detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_descriptor_service<
-      detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_descriptor_service<
-      detail::dev_poll_reactor<false> > service_impl_type;
-#else
-  typedef detail::reactive_descriptor_service<
-      detail::select_reactor<false> > service_impl_type;
-#endif
+  typedef detail::reactive_descriptor_service service_impl_type;
 
 public:
   /// The type of a stream descriptor implementation.
@@ -101,13 +77,14 @@
   /// Construct a new stream descriptor service for the specified io_service.
   explicit stream_descriptor_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<stream_descriptor_service>(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined descriptorr objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new stream descriptor implementation.
@@ -196,8 +173,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace posix
Modified: trunk/boost/asio/raw_socket_service.hpp
==============================================================================
--- trunk/boost/asio/raw_socket_service.hpp	(original)
+++ trunk/boost/asio/raw_socket_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -28,17 +28,7 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
 #else
-# include <boost/asio/detail/select_reactor.hpp>
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
@@ -70,18 +60,8 @@
   // The type of the platform-specific implementation.
 #if defined(BOOST_ASIO_HAS_IOCP)
   typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::dev_poll_reactor<false> > service_impl_type;
 #else
-  typedef detail::reactive_socket_service<
-      Protocol, detail::select_reactor<false> > service_impl_type;
+  typedef detail::reactive_socket_service<Protocol> service_impl_type;
 #endif
 
 public:
@@ -103,13 +83,14 @@
   explicit raw_socket_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         raw_socket_service<Protocol> >(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new raw socket implementation.
@@ -324,8 +305,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Modified: trunk/boost/asio/serial_port_service.hpp
==============================================================================
--- trunk/boost/asio/serial_port_service.hpp	(original)
+++ trunk/boost/asio/serial_port_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -54,18 +54,8 @@
   // The type of the platform-specific implementation.
 #if defined(BOOST_ASIO_HAS_IOCP)
   typedef detail::win_iocp_serial_port_service service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_serial_port_service<
-      detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_serial_port_service<
-      detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_serial_port_service<
-      detail::dev_poll_reactor<false> > service_impl_type;
 #else
-  typedef detail::reactive_serial_port_service<
-      detail::select_reactor<false> > service_impl_type;
+  typedef detail::reactive_serial_port_service service_impl_type;
 #endif
 
 public:
@@ -86,13 +76,14 @@
   /// Construct a new serial port service for the specified io_service.
   explicit serial_port_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<serial_port_service>(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new serial port implementation.
@@ -203,8 +194,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Modified: trunk/boost/asio/socket_acceptor_service.hpp
==============================================================================
--- trunk/boost/asio/socket_acceptor_service.hpp	(original)
+++ trunk/boost/asio/socket_acceptor_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -24,17 +24,7 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
 #else
-# include <boost/asio/detail/select_reactor.hpp>
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
@@ -66,18 +56,8 @@
   // The type of the platform-specific implementation.
 #if defined(BOOST_ASIO_HAS_IOCP)
   typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::dev_poll_reactor<false> > service_impl_type;
 #else
-  typedef detail::reactive_socket_service<
-      Protocol, detail::select_reactor<false> > service_impl_type;
+  typedef detail::reactive_socket_service<Protocol> service_impl_type;
 #endif
 
 public:
@@ -99,13 +79,14 @@
   explicit socket_acceptor_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         socket_acceptor_service<Protocol> >(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new socket acceptor implementation.
@@ -226,8 +207,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Modified: trunk/boost/asio/ssl/detail/openssl_operation.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_operation.hpp	(original)
+++ trunk/boost/asio/ssl/detail/openssl_operation.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -173,7 +173,8 @@
       ((::SSL_get_shutdown( session_ ) & SSL_SENT_SHUTDOWN) ==
             SSL_SENT_SHUTDOWN);
 
-    if (is_shut_down_sent && is_shut_down_received && is_operation_done && !is_write_needed)
+    if (is_shut_down_sent && is_shut_down_received
+        && is_operation_done && !is_write_needed)
       // SSL connection is shut down cleanly
       return handler_(boost::system::error_code(), 1);
 
Modified: trunk/boost/asio/ssl/detail/openssl_stream_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_stream_service.hpp	(original)
+++ trunk/boost/asio/ssl/detail/openssl_stream_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -31,6 +31,7 @@
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/strand.hpp>
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
 #include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/ssl/basic_context.hpp>
 #include <boost/asio/ssl/stream_base.hpp>
@@ -333,13 +334,22 @@
     size_t bytes_transferred = 0;
     try
     {
-      std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+      boost::asio::const_buffer buffer =
+        boost::asio::detail::buffer_sequence_adapter<
+          boost::asio::const_buffer, Const_Buffers>::first(buffers);
+
+      std::size_t buffer_size = boost::asio::buffer_size(buffer);
       if (buffer_size > max_buffer_size)
         buffer_size = max_buffer_size;
+      else if (buffer_size == 0)
+      {
+        ec = boost::system::error_code();
+        return 0;
+      }
 
       boost::function<int (SSL*)> send_func =
         boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),  
-            boost::asio::buffer_cast<const void*>(*buffers.begin()),
+            boost::asio::buffer_cast<const void*>(buffer),
             static_cast<int>(buffer_size));
       openssl_operation<Stream> op(
         send_func,
@@ -367,15 +377,25 @@
   {
     typedef io_handler<Stream, Handler> send_handler;
 
-    send_handler* local_handler = new send_handler(handler, get_io_service());
+    boost::asio::const_buffer buffer =
+      boost::asio::detail::buffer_sequence_adapter<
+        boost::asio::const_buffer, Const_Buffers>::first(buffers);
 
-    std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+    std::size_t buffer_size = boost::asio::buffer_size(buffer);
     if (buffer_size > max_buffer_size)
       buffer_size = max_buffer_size;
+    else if (buffer_size == 0)
+    {
+      get_io_service().post(boost::asio::detail::bind_handler(
+            handler, boost::system::error_code(), 0));
+      return;
+    }
+
+    send_handler* local_handler = new send_handler(handler, get_io_service());
 
     boost::function<int (SSL*)> send_func =
       boost::bind(boost::type<int>(), &::SSL_write, boost::arg<1>(),
-          boost::asio::buffer_cast<const void*>(*buffers.begin()),
+          boost::asio::buffer_cast<const void*>(buffer),
           static_cast<int>(buffer_size));
 
     openssl_operation<Stream>* op = new openssl_operation<Stream>
@@ -407,13 +427,22 @@
     size_t bytes_transferred = 0;
     try
     {
-      std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+      boost::asio::mutable_buffer buffer =
+        boost::asio::detail::buffer_sequence_adapter<
+          boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
+
+      std::size_t buffer_size = boost::asio::buffer_size(buffer);
       if (buffer_size > max_buffer_size)
         buffer_size = max_buffer_size;
+      else if (buffer_size == 0)
+      {
+        ec = boost::system::error_code();
+        return 0;
+      }
 
       boost::function<int (SSL*)> recv_func =
         boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
-            boost::asio::buffer_cast<void*>(*buffers.begin()),
+            boost::asio::buffer_cast<void*>(buffer),
             static_cast<int>(buffer_size));
       openssl_operation<Stream> op(recv_func,
         next_layer,
@@ -441,15 +470,25 @@
   {
     typedef io_handler<Stream, Handler> recv_handler;
 
-    recv_handler* local_handler = new recv_handler(handler, get_io_service());
+    boost::asio::mutable_buffer buffer =
+      boost::asio::detail::buffer_sequence_adapter<
+        boost::asio::mutable_buffer, Mutable_Buffers>::first(buffers);
 
-    std::size_t buffer_size = boost::asio::buffer_size(*buffers.begin());
+    std::size_t buffer_size = boost::asio::buffer_size(buffer);
     if (buffer_size > max_buffer_size)
       buffer_size = max_buffer_size;
+    else if (buffer_size == 0)
+    {
+      get_io_service().post(boost::asio::detail::bind_handler(
+            handler, boost::system::error_code(), 0));
+      return;
+    }
+
+    recv_handler* local_handler = new recv_handler(handler, get_io_service());
 
     boost::function<int (SSL*)> recv_func =
       boost::bind(boost::type<int>(), &::SSL_read, boost::arg<1>(),
-          boost::asio::buffer_cast<void*>(*buffers.begin()),
+          boost::asio::buffer_cast<void*>(buffer),
           static_cast<int>(buffer_size));
 
     openssl_operation<Stream>* op = new openssl_operation<Stream>
Modified: trunk/boost/asio/stream_socket_service.hpp
==============================================================================
--- trunk/boost/asio/stream_socket_service.hpp	(original)
+++ trunk/boost/asio/stream_socket_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -28,17 +28,7 @@
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-# include <boost/asio/detail/epoll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-# include <boost/asio/detail/kqueue_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-# include <boost/asio/detail/dev_poll_reactor.hpp>
-# include <boost/asio/detail/reactive_socket_service.hpp>
 #else
-# include <boost/asio/detail/select_reactor.hpp>
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
@@ -70,18 +60,8 @@
   // The type of the platform-specific implementation.
 #if defined(BOOST_ASIO_HAS_IOCP)
   typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_EPOLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::epoll_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_KQUEUE)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::kqueue_reactor<false> > service_impl_type;
-#elif defined(BOOST_ASIO_HAS_DEV_POLL)
-  typedef detail::reactive_socket_service<
-      Protocol, detail::dev_poll_reactor<false> > service_impl_type;
 #else
-  typedef detail::reactive_socket_service<
-      Protocol, detail::select_reactor<false> > service_impl_type;
+  typedef detail::reactive_socket_service<Protocol> service_impl_type;
 #endif
 
 public:
@@ -103,13 +83,14 @@
   explicit stream_socket_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         stream_socket_service<Protocol> >(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new stream socket implementation.
@@ -287,8 +268,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace asio
Modified: trunk/boost/asio/windows/random_access_handle_service.hpp
==============================================================================
--- trunk/boost/asio/windows/random_access_handle_service.hpp	(original)
+++ trunk/boost/asio/windows/random_access_handle_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -78,13 +78,14 @@
   explicit random_access_handle_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         random_access_handle_service>(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new random-access handle implementation.
@@ -165,8 +166,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace windows
Modified: trunk/boost/asio/windows/stream_handle_service.hpp
==============================================================================
--- trunk/boost/asio/windows/stream_handle_service.hpp	(original)
+++ trunk/boost/asio/windows/stream_handle_service.hpp	2010-03-09 07:50:07 EST (Tue, 09 Mar 2010)
@@ -76,13 +76,14 @@
   /// Construct a new stream handle service for the specified io_service.
   explicit stream_handle_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<stream_handle_service>(io_service),
-      service_impl_(boost::asio::use_service<service_impl_type>(io_service))
+      service_impl_(io_service)
   {
   }
 
   /// Destroy all user-defined handler objects owned by the service.
   void shutdown_service()
   {
+    service_impl_.shutdown_service();
   }
 
   /// Construct a new stream handle implementation.
@@ -163,8 +164,8 @@
   }
 
 private:
-  // The service that provides the platform-specific implementation.
-  service_impl_type& service_impl_;
+  // The platform-specific implementation.
+  service_impl_type service_impl_;
 };
 
 } // namespace windows