Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62499 - in trunk: boost/asio boost/asio/detail boost/asio/detail/impl boost/asio/impl boost/asio/ip boost/asio/ip/detail boost/asio/ip/detail/impl boost/asio/ip/impl boost/asio/local boost/asio/local/detail boost/asio/local/detail/impl boost/asio/posix boost/asio/ssl boost/asio/ssl/detail boost/asio/windows libs/asio/doc libs/asio/example/local libs/asio/test libs/asio/test/ip
From: chris_at_[hidden]
Date: 2010-06-06 20:01:20


Author: chris_kohlhoff
Date: 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
New Revision: 62499
URL: http://svn.boost.org/trac/boost/changeset/62499

Log:
Reworked implementation MkII

Added:
   trunk/boost/asio/basic_streambuf_fwd.hpp (contents, props changed)
   trunk/boost/asio/detail/array_fwd.hpp (contents, props changed)
   trunk/boost/asio/detail/config.hpp (contents, props changed)
   trunk/boost/asio/detail/descriptor_read_op.hpp (contents, props changed)
   trunk/boost/asio/detail/descriptor_write_op.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/
   trunk/boost/asio/detail/impl/descriptor_ops.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/dev_poll_reactor.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/dev_poll_reactor.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/epoll_reactor.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/epoll_reactor.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/eventfd_select_interrupter.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/kqueue_reactor.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/kqueue_reactor.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/pipe_select_interrupter.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/posix_event.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/posix_mutex.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/posix_thread.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/posix_tss_ptr.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/reactive_descriptor_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/reactive_serial_port_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/reactive_socket_service_base.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/resolver_service_base.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/select_reactor.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/select_reactor.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/service_registry.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/service_registry.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/socket_ops.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/socket_select_interrupter.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/strand_service.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/strand_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/task_io_service.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/task_io_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/throw_error.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/timer_queue.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/timer_queue_set.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_event.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_iocp_handle_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_iocp_io_service.hpp (contents, props changed)
   trunk/boost/asio/detail/impl/win_iocp_io_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_iocp_serial_port_service.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_iocp_socket_service_base.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_mutex.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_thread.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/win_tss_ptr.ipp (contents, props changed)
   trunk/boost/asio/detail/impl/winsock_init.ipp (contents, props changed)
   trunk/boost/asio/detail/reactive_null_buffers_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_accept_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_connect_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_recv_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_recvfrom_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_send_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_sendto_op.hpp (contents, props changed)
   trunk/boost/asio/detail/reactive_socket_service_base.hpp (contents, props changed)
   trunk/boost/asio/detail/regex_fwd.hpp (contents, props changed)
   trunk/boost/asio/detail/resolve_endpoint_op.hpp (contents, props changed)
   trunk/boost/asio/detail/resolve_op.hpp (contents, props changed)
   trunk/boost/asio/detail/resolver_service_base.hpp (contents, props changed)
   trunk/boost/asio/detail/shared_ptr.hpp (contents, props changed)
   trunk/boost/asio/detail/wait_handler.hpp (contents, props changed)
   trunk/boost/asio/detail/weak_ptr.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_handle_read_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_handle_write_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_null_buffers_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_overlapped_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_socket_accept_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_socket_recv_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_socket_send_op.hpp (contents, props changed)
   trunk/boost/asio/detail/win_iocp_socket_service_base.hpp (contents, props changed)
   trunk/boost/asio/impl/error.ipp (contents, props changed)
   trunk/boost/asio/impl/io_service.hpp (contents, props changed)
   trunk/boost/asio/impl/read.hpp (contents, props changed)
   trunk/boost/asio/impl/read_at.hpp (contents, props changed)
   trunk/boost/asio/impl/read_until.hpp (contents, props changed)
   trunk/boost/asio/impl/serial_port_base.hpp (contents, props changed)
   trunk/boost/asio/impl/src.cpp (contents, props changed)
   trunk/boost/asio/impl/write.hpp (contents, props changed)
   trunk/boost/asio/impl/write_at.hpp (contents, props changed)
   trunk/boost/asio/ip/detail/endpoint.hpp (contents, props changed)
   trunk/boost/asio/ip/detail/impl/
   trunk/boost/asio/ip/detail/impl/endpoint.ipp (contents, props changed)
   trunk/boost/asio/ip/impl/
   trunk/boost/asio/ip/impl/address.hpp (contents, props changed)
   trunk/boost/asio/ip/impl/address.ipp (contents, props changed)
   trunk/boost/asio/ip/impl/address_v4.hpp (contents, props changed)
   trunk/boost/asio/ip/impl/address_v4.ipp (contents, props changed)
   trunk/boost/asio/ip/impl/address_v6.hpp (contents, props changed)
   trunk/boost/asio/ip/impl/address_v6.ipp (contents, props changed)
   trunk/boost/asio/ip/impl/basic_endpoint.hpp (contents, props changed)
   trunk/boost/asio/ip/impl/host_name.ipp (contents, props changed)
   trunk/boost/asio/local/detail/
   trunk/boost/asio/local/detail/endpoint.hpp (contents, props changed)
   trunk/boost/asio/local/detail/impl/
   trunk/boost/asio/local/detail/impl/endpoint.ipp (contents, props changed)
Removed:
   trunk/boost/asio/detail/null_buffers_op.hpp
   trunk/boost/asio/detail/service_base.hpp
   trunk/boost/asio/detail/service_id.hpp
   trunk/boost/asio/impl/read.ipp
   trunk/boost/asio/impl/read_at.ipp
   trunk/boost/asio/impl/read_until.ipp
   trunk/boost/asio/impl/write.ipp
   trunk/boost/asio/impl/write_at.ipp
Text files modified:
   trunk/boost/asio/basic_datagram_socket.hpp | 11
   trunk/boost/asio/basic_deadline_timer.hpp | 11
   trunk/boost/asio/basic_io_object.hpp | 7
   trunk/boost/asio/basic_raw_socket.hpp | 13
   trunk/boost/asio/basic_serial_port.hpp | 18
   trunk/boost/asio/basic_socket.hpp | 11
   trunk/boost/asio/basic_socket_acceptor.hpp | 7
   trunk/boost/asio/basic_socket_iostream.hpp | 15
   trunk/boost/asio/basic_socket_streambuf.hpp | 17
   trunk/boost/asio/basic_stream_socket.hpp | 11
   trunk/boost/asio/basic_streambuf.hpp | 36
   trunk/boost/asio/buffer.hpp | 20
   trunk/boost/asio/buffered_read_stream.hpp | 13
   trunk/boost/asio/buffered_read_stream_fwd.hpp | 4
   trunk/boost/asio/buffered_stream.hpp | 11
   trunk/boost/asio/buffered_stream_fwd.hpp | 4
   trunk/boost/asio/buffered_write_stream.hpp | 15
   trunk/boost/asio/buffered_write_stream_fwd.hpp | 4
   trunk/boost/asio/buffers_iterator.hpp | 9
   trunk/boost/asio/completion_condition.hpp | 6
   trunk/boost/asio/datagram_socket_service.hpp | 10
   trunk/boost/asio/deadline_timer.hpp | 8
   trunk/boost/asio/deadline_timer_service.hpp | 12
   trunk/boost/asio/detail/base_from_completion_cond.hpp | 15
   trunk/boost/asio/detail/bind_handler.hpp | 9
   trunk/boost/asio/detail/buffer_resize_guard.hpp | 10
   trunk/boost/asio/detail/buffer_sequence_adapter.hpp | 14
   trunk/boost/asio/detail/buffered_stream_storage.hpp | 12
   trunk/boost/asio/detail/call_stack.hpp | 9
   trunk/boost/asio/detail/completion_handler.hpp | 32
   trunk/boost/asio/detail/consuming_buffers.hpp | 14
   trunk/boost/asio/detail/deadline_timer_service.hpp | 71
   trunk/boost/asio/detail/descriptor_ops.hpp | 169 -
   trunk/boost/asio/detail/dev_poll_reactor.hpp | 362 ---
   trunk/boost/asio/detail/dev_poll_reactor_fwd.hpp | 17
   trunk/boost/asio/detail/epoll_reactor.hpp | 397 ----
   trunk/boost/asio/detail/epoll_reactor_fwd.hpp | 24
   trunk/boost/asio/detail/event.hpp | 12
   trunk/boost/asio/detail/eventfd_select_interrupter.hpp | 118 -
   trunk/boost/asio/detail/fd_set_adapter.hpp | 13
   trunk/boost/asio/detail/fenced_block.hpp | 12
   trunk/boost/asio/detail/gcc_fenced_block.hpp | 16
   trunk/boost/asio/detail/gcc_x86_fenced_block.hpp | 16
   trunk/boost/asio/detail/handler_alloc_helpers.hpp | 238 --
   trunk/boost/asio/detail/handler_invoke_helpers.hpp | 12
   trunk/boost/asio/detail/hash_map.hpp | 33
   trunk/boost/asio/detail/io_control.hpp | 12
   trunk/boost/asio/detail/kqueue_reactor.hpp | 381 ---
   trunk/boost/asio/detail/kqueue_reactor_fwd.hpp | 21
   trunk/boost/asio/detail/local_free_on_block_exit.hpp | 16
   trunk/boost/asio/detail/macos_fenced_block.hpp | 18
   trunk/boost/asio/detail/mutex.hpp | 12
   trunk/boost/asio/detail/noncopyable.hpp | 12
   trunk/boost/asio/detail/null_event.hpp | 16
   trunk/boost/asio/detail/null_fenced_block.hpp | 4
   trunk/boost/asio/detail/null_mutex.hpp | 16
   trunk/boost/asio/detail/null_signal_blocker.hpp | 16
   trunk/boost/asio/detail/null_thread.hpp | 29
   trunk/boost/asio/detail/null_tss_ptr.hpp | 16
   trunk/boost/asio/detail/old_win_sdk_compat.hpp | 16
   trunk/boost/asio/detail/op_queue.hpp | 8
   trunk/boost/asio/detail/operation.hpp | 13
   trunk/boost/asio/detail/pipe_select_interrupter.hpp | 76
   trunk/boost/asio/detail/pop_options.hpp | 4
   trunk/boost/asio/detail/posix_event.hpp | 42
   trunk/boost/asio/detail/posix_fd_set_adapter.hpp | 17
   trunk/boost/asio/detail/posix_mutex.hpp | 41
   trunk/boost/asio/detail/posix_signal_blocker.hpp | 21
   trunk/boost/asio/detail/posix_thread.hpp | 78
   trunk/boost/asio/detail/posix_tss_ptr.hpp | 42
   trunk/boost/asio/detail/push_options.hpp | 4
   trunk/boost/asio/detail/reactive_descriptor_service.hpp | 547 -----
   trunk/boost/asio/detail/reactive_serial_port_service.hpp | 184 -
   trunk/boost/asio/detail/reactive_socket_service.hpp | 1578 +-----------------
   trunk/boost/asio/detail/reactor.hpp | 8
   trunk/boost/asio/detail/reactor_fwd.hpp | 28
   trunk/boost/asio/detail/reactor_op.hpp | 9
   trunk/boost/asio/detail/reactor_op_queue.hpp | 11
   trunk/boost/asio/detail/resolver_service.hpp | 397 ----
   trunk/boost/asio/detail/scoped_lock.hpp | 8
   trunk/boost/asio/detail/select_interrupter.hpp | 15
   trunk/boost/asio/detail/select_reactor.hpp | 304 --
   trunk/boost/asio/detail/select_reactor_fwd.hpp | 9
   trunk/boost/asio/detail/service_registry.hpp | 190 -
   trunk/boost/asio/detail/service_registry_fwd.hpp | 8
   trunk/boost/asio/detail/signal_blocker.hpp | 12
   trunk/boost/asio/detail/signal_init.hpp | 18
   trunk/boost/asio/detail/socket_holder.hpp | 15
   trunk/boost/asio/detail/socket_ops.hpp | 1977 ++--------------------
   trunk/boost/asio/detail/socket_option.hpp | 12
   trunk/boost/asio/detail/socket_select_interrupter.hpp | 150 -
   trunk/boost/asio/detail/socket_types.hpp | 61
   trunk/boost/asio/detail/solaris_fenced_block.hpp | 18
   trunk/boost/asio/detail/strand_service.hpp | 202 --
   trunk/boost/asio/detail/task_io_service.hpp | 381 ---
   trunk/boost/asio/detail/task_io_service_fwd.hpp | 9
   trunk/boost/asio/detail/task_io_service_operation.hpp | 18
   trunk/boost/asio/detail/thread.hpp | 12
   trunk/boost/asio/detail/throw_error.hpp | 33
   trunk/boost/asio/detail/timer_op.hpp | 9
   trunk/boost/asio/detail/timer_queue.hpp | 72
   trunk/boost/asio/detail/timer_queue_base.hpp | 9
   trunk/boost/asio/detail/timer_queue_fwd.hpp | 8
   trunk/boost/asio/detail/timer_queue_set.hpp | 83
   trunk/boost/asio/detail/timer_scheduler.hpp | 9
   trunk/boost/asio/detail/timer_scheduler_fwd.hpp | 26
   trunk/boost/asio/detail/tss_ptr.hpp | 12
   trunk/boost/asio/detail/win_event.hpp | 38
   trunk/boost/asio/detail/win_fd_set_adapter.hpp | 14
   trunk/boost/asio/detail/win_fenced_block.hpp | 16
   trunk/boost/asio/detail/win_iocp_handle_service.hpp | 573 -----
   trunk/boost/asio/detail/win_iocp_io_service.hpp | 596 +-----
   trunk/boost/asio/detail/win_iocp_io_service_fwd.hpp | 28
   trunk/boost/asio/detail/win_iocp_operation.hpp | 17
   trunk/boost/asio/detail/win_iocp_overlapped_ptr.hpp | 70
   trunk/boost/asio/detail/win_iocp_serial_port_service.hpp | 212 -
   trunk/boost/asio/detail/win_iocp_socket_service.hpp | 1808 +-------------------
   trunk/boost/asio/detail/win_mutex.hpp | 67
   trunk/boost/asio/detail/win_signal_blocker.hpp | 16
   trunk/boost/asio/detail/win_thread.hpp | 151 -
   trunk/boost/asio/detail/win_tss_ptr.hpp | 42
   trunk/boost/asio/detail/wince_thread.hpp | 30
   trunk/boost/asio/detail/winsock_init.hpp | 118
   trunk/boost/asio/detail/wrapped_handler.hpp | 16
   trunk/boost/asio/error.hpp | 143 -
   trunk/boost/asio/handler_alloc_hook.hpp | 6
   trunk/boost/asio/handler_invoke_hook.hpp | 2
   trunk/boost/asio/impl/io_service.ipp | 141 -
   trunk/boost/asio/impl/serial_port_base.ipp | 93
   trunk/boost/asio/io_service.hpp | 103
   trunk/boost/asio/ip/address.hpp | 205 -
   trunk/boost/asio/ip/address_v4.hpp | 173 -
   trunk/boost/asio/ip/address_v6.hpp | 303 --
   trunk/boost/asio/ip/basic_endpoint.hpp | 233 --
   trunk/boost/asio/ip/basic_resolver.hpp | 11
   trunk/boost/asio/ip/basic_resolver_entry.hpp | 9
   trunk/boost/asio/ip/basic_resolver_iterator.hpp | 16
   trunk/boost/asio/ip/basic_resolver_query.hpp | 13
   trunk/boost/asio/ip/detail/socket_option.hpp | 15
   trunk/boost/asio/ip/host_name.hpp | 42
   trunk/boost/asio/ip/icmp.hpp | 11
   trunk/boost/asio/ip/multicast.hpp | 13
   trunk/boost/asio/ip/resolver_query_base.hpp | 13
   trunk/boost/asio/ip/resolver_service.hpp | 21
   trunk/boost/asio/ip/tcp.hpp | 13
   trunk/boost/asio/ip/udp.hpp | 11
   trunk/boost/asio/ip/unicast.hpp | 13
   trunk/boost/asio/ip/v6_only.hpp | 9
   trunk/boost/asio/is_read_buffered.hpp | 9
   trunk/boost/asio/is_write_buffered.hpp | 9
   trunk/boost/asio/local/basic_endpoint.hpp | 141 -
   trunk/boost/asio/local/connect_pair.hpp | 28
   trunk/boost/asio/local/datagram_protocol.hpp | 18
   trunk/boost/asio/local/stream_protocol.hpp | 18
   trunk/boost/asio/placeholders.hpp | 7
   trunk/boost/asio/posix/basic_descriptor.hpp | 18
   trunk/boost/asio/posix/basic_stream_descriptor.hpp | 22
   trunk/boost/asio/posix/descriptor_base.hpp | 17
   trunk/boost/asio/posix/stream_descriptor.hpp | 12
   trunk/boost/asio/posix/stream_descriptor_service.hpp | 30
   trunk/boost/asio/raw_socket_service.hpp | 10
   trunk/boost/asio/read.hpp | 15
   trunk/boost/asio/read_at.hpp | 15
   trunk/boost/asio/read_until.hpp | 19
   trunk/boost/asio/serial_port.hpp | 8
   trunk/boost/asio/serial_port_base.hpp | 69
   trunk/boost/asio/serial_port_service.hpp | 21
   trunk/boost/asio/socket_acceptor_service.hpp | 6
   trunk/boost/asio/socket_base.hpp | 9
   trunk/boost/asio/ssl/basic_context.hpp | 14
   trunk/boost/asio/ssl/context.hpp | 9
   trunk/boost/asio/ssl/context_base.hpp | 13
   trunk/boost/asio/ssl/context_service.hpp | 13
   trunk/boost/asio/ssl/detail/openssl_context_service.hpp | 13
   trunk/boost/asio/ssl/detail/openssl_init.hpp | 13
   trunk/boost/asio/ssl/detail/openssl_operation.hpp | 18
   trunk/boost/asio/ssl/detail/openssl_stream_service.hpp | 24
   trunk/boost/asio/ssl/detail/openssl_types.hpp | 14
   trunk/boost/asio/ssl/stream.hpp | 15
   trunk/boost/asio/ssl/stream_base.hpp | 9
   trunk/boost/asio/ssl/stream_service.hpp | 16
   trunk/boost/asio/strand.hpp | 7
   trunk/boost/asio/stream_socket_service.hpp | 10
   trunk/boost/asio/streambuf.hpp | 8
   trunk/boost/asio/time_traits.hpp | 4
   trunk/boost/asio/version.hpp | 2
   trunk/boost/asio/windows/basic_handle.hpp | 20
   trunk/boost/asio/windows/basic_random_access_handle.hpp | 22
   trunk/boost/asio/windows/basic_stream_handle.hpp | 20
   trunk/boost/asio/windows/overlapped_ptr.hpp | 24
   trunk/boost/asio/windows/random_access_handle.hpp | 12
   trunk/boost/asio/windows/random_access_handle_service.hpp | 28
   trunk/boost/asio/windows/stream_handle.hpp | 12
   trunk/boost/asio/windows/stream_handle_service.hpp | 29
   trunk/boost/asio/write.hpp | 15
   trunk/boost/asio/write_at.hpp | 15
   trunk/libs/asio/doc/reference.qbk | 518 ++++-
   trunk/libs/asio/doc/reference.xsl | 56
   trunk/libs/asio/example/local/iostream_client.cpp | 7
   trunk/libs/asio/test/Jamfile | 1
   trunk/libs/asio/test/Jamfile.v2 | 1
   trunk/libs/asio/test/buffer.cpp | 1
   trunk/libs/asio/test/buffered_read_stream.cpp | 1
   trunk/libs/asio/test/buffered_stream.cpp | 1
   trunk/libs/asio/test/buffered_write_stream.cpp | 1
   trunk/libs/asio/test/buffers_iterator.cpp | 25
   trunk/libs/asio/test/ip/multicast.cpp | 8
   trunk/libs/asio/test/ip/tcp.cpp | 69
   trunk/libs/asio/test/ip/udp.cpp | 63
   trunk/libs/asio/test/ip/unicast.cpp | 2
   trunk/libs/asio/test/ip/v6_only.cpp | 6
   trunk/libs/asio/test/read.cpp | 363 ++--
   trunk/libs/asio/test/read_at.cpp | 3429 +++++++++++++++++++++++++++++++++++----
   trunk/libs/asio/test/serial_port_base.cpp | 11
   trunk/libs/asio/test/socket_base.cpp | 48
   trunk/libs/asio/test/write.cpp | 362 ++--
   trunk/libs/asio/test/write_at.cpp | 2940 +++++++++++++++++++++++++++++++---
   217 files changed, 9634 insertions(+), 13874 deletions(-)

Modified: trunk/boost/asio/basic_datagram_socket.hpp
==============================================================================
--- trunk/boost/asio/basic_datagram_socket.hpp (original)
+++ trunk/boost/asio/basic_datagram_socket.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_socket.hpp>
 #include <boost/asio/datagram_socket_service.hpp>
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_deadline_timer.hpp
==============================================================================
--- trunk/boost/asio/basic_deadline_timer.hpp (original)
+++ trunk/boost/asio/basic_deadline_timer.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_io_object.hpp>
 #include <boost/asio/deadline_timer_service.hpp>
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_io_object.hpp
==============================================================================
--- trunk/boost/asio/basic_io_object.hpp (original)
+++ trunk/boost/asio/basic_io_object.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,10 +15,11 @@
 # 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/config.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_raw_socket.hpp
==============================================================================
--- trunk/boost/asio/basic_raw_socket.hpp (original)
+++ trunk/boost/asio/basic_raw_socket.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_socket.hpp>
-#include <boost/asio/raw_socket_service.hpp>
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/raw_socket_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_serial_port.hpp
==============================================================================
--- trunk/boost/asio/basic_serial_port.hpp (original)
+++ trunk/boost/asio/basic_serial_port.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,21 +16,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <string>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+ || defined(GENERATING_DOCUMENTATION)
 
+#include <string>
 #include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/serial_port_base.hpp>
 #include <boost/asio/serial_port_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
 
-#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -616,9 +614,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP

Modified: trunk/boost/asio/basic_socket.hpp
==============================================================================
--- trunk/boost/asio/basic_socket.hpp (original)
+++ trunk/boost/asio/basic_socket.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,13 @@
 # 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>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_socket_acceptor.hpp
==============================================================================
--- trunk/boost/asio/basic_socket_acceptor.hpp (original)
+++ trunk/boost/asio/basic_socket_acceptor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,14 +15,15 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_io_object.hpp>
 #include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/socket_acceptor_service.hpp>
 #include <boost/asio/socket_base.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_socket_iostream.hpp
==============================================================================
--- trunk/boost/asio/basic_socket_iostream.hpp (original)
+++ trunk/boost/asio/basic_socket_iostream.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,22 +15,15 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <boost/preprocessor/arithmetic/inc.hpp>
 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/utility/base_from_member.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_socket_streambuf.hpp>
 #include <boost/asio/stream_socket_service.hpp>
 
@@ -79,6 +72,8 @@
   } \
   /**/
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -148,11 +143,11 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #undef BOOST_ASIO_PRIVATE_CTR_DEF
 #undef BOOST_ASIO_PRIVATE_CONNECT_DEF
 
 #endif // defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BASIC_SOCKET_IOSTREAM_HPP

Modified: trunk/boost/asio/basic_socket_streambuf.hpp
==============================================================================
--- trunk/boost/asio/basic_socket_streambuf.hpp (original)
+++ trunk/boost/asio/basic_socket_streambuf.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,15 +15,10 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <streambuf>
 #include <boost/array.hpp>
 #include <boost/preprocessor/arithmetic/inc.hpp>
@@ -31,12 +26,10 @@
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/utility/base_from_member.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/stream_socket_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
 
 #if !defined(BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY)
 #define BOOST_ASIO_SOCKET_STREAMBUF_MAX_ARITY 5
@@ -74,6 +67,8 @@
   } \
   /**/
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -288,10 +283,10 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #undef BOOST_ASIO_PRIVATE_CONNECT_DEF
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BASIC_SOCKET_STREAMBUF_HPP

Modified: trunk/boost/asio/basic_stream_socket.hpp
==============================================================================
--- trunk/boost/asio/basic_stream_socket.hpp (original)
+++ trunk/boost/asio/basic_stream_socket.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_socket.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/stream_socket_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/basic_streambuf.hpp
==============================================================================
--- trunk/boost/asio/basic_streambuf.hpp (original)
+++ trunk/boost/asio/basic_streambuf.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,28 +15,23 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <algorithm>
 #include <cstring>
-#include <memory>
 #include <stdexcept>
 #include <streambuf>
 #include <vector>
 #include <boost/limits.hpp>
 #include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/basic_streambuf_fwd.hpp>
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -108,7 +103,11 @@
  * is >> s;
  * @endcode
  */
+#if defined(GENERATING_DOCUMENTATION)
 template <typename Allocator = std::allocator<char> >
+#else
+template <typename Allocator>
+#endif
 class basic_streambuf
   : public std::streambuf,
     private noncopyable
@@ -338,8 +337,27 @@
 private:
   std::size_t max_size_;
   std::vector<char_type, Allocator> buffer_;
+
+ // Helper function to get the preferred size for reading data.
+ friend std::size_t read_size_helper(
+ basic_streambuf& sb, std::size_t max_size)
+ {
+ return std::min<std::size_t>(
+ std::max<std::size_t>(512, sb.buffer_.capacity() - sb.size()),
+ std::min<std::size_t>(max_size, sb.max_size() - sb.size()));
+ }
 };
 
+// Helper function to get the preferred size for reading data. Used for any
+// user-provided specialisations of basic_streambuf.
+template <typename Allocator>
+inline std::size_t read_size_helper(
+ basic_streambuf<Allocator>& sb, std::size_t max_size)
+{
+ return std::min<std::size_t>(512,
+ std::min<std::size_t>(max_size, sb.max_size() - sb.size()));
+}
+
 } // namespace asio
 } // namespace boost
 

Added: trunk/boost/asio/basic_streambuf_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/basic_streambuf_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,35 @@
+//
+// basic_streambuf_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_BASIC_STREAMBUF_FWD_HPP
+#define BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#include <memory>
+
+namespace boost {
+namespace asio {
+
+template <typename Allocator = std::allocator<char> >
+class basic_streambuf;
+
+} // namespace asio
+} // namespace boost
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_BASIC_STREAMBUF_FWD_HPP

Modified: trunk/boost/asio/buffer.hpp
==============================================================================
--- trunk/boost/asio/buffer.hpp (original)
+++ trunk/boost/asio/buffer.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,12 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/array.hpp>
-#include <boost/type_traits/is_const.hpp>
 #include <string>
 #include <vector>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/asio/detail/array_fwd.hpp>
 
 #if defined(BOOST_MSVC)
 # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
@@ -43,11 +39,17 @@
 #endif // defined(__GNUC__)
 
 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
-# include <boost/asio/detail/push_options.hpp>
 # include <boost/function.hpp>
-# include <boost/asio/detail/pop_options.hpp>
 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
 
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
+ || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+# include <boost/type_traits/is_const.hpp>
+#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
+ // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/buffered_read_stream.hpp
==============================================================================
--- trunk/boost/asio/buffered_read_stream.hpp (original)
+++ trunk/boost/asio/buffered_read_stream.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,23 +15,20 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <cstring>
-#include <boost/config.hpp>
 #include <boost/type_traits/remove_reference.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffered_read_stream_fwd.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_resize_guard.hpp>
 #include <boost/asio/detail/buffered_stream_storage.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/buffered_read_stream_fwd.hpp
==============================================================================
--- trunk/boost/asio/buffered_read_stream_fwd.hpp (original)
+++ trunk/boost/asio/buffered_read_stream_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,8 +15,6 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 
@@ -26,6 +24,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BUFFERED_READ_STREAM_FWD_HPP

Modified: trunk/boost/asio/buffered_stream.hpp
==============================================================================
--- trunk/boost/asio/buffered_stream.hpp (original)
+++ trunk/boost/asio/buffered_stream.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,19 +15,16 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffered_read_stream.hpp>
 #include <boost/asio/buffered_write_stream.hpp>
 #include <boost/asio/buffered_stream_fwd.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/buffered_stream_fwd.hpp
==============================================================================
--- trunk/boost/asio/buffered_stream_fwd.hpp (original)
+++ trunk/boost/asio/buffered_stream_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,8 +15,6 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 
@@ -26,6 +24,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BUFFERED_STREAM_FWD_HPP

Modified: trunk/boost/asio/buffered_write_stream.hpp
==============================================================================
--- trunk/boost/asio/buffered_write_stream.hpp (original)
+++ trunk/boost/asio/buffered_write_stream.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,24 +15,21 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <cstring>
-#include <boost/config.hpp>
 #include <boost/type_traits/remove_reference.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffered_write_stream_fwd.hpp>
 #include <boost/asio/buffer.hpp>
 #include <boost/asio/completion_condition.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/write.hpp>
 #include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/buffered_stream_storage.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/write.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/buffered_write_stream_fwd.hpp
==============================================================================
--- trunk/boost/asio/buffered_write_stream_fwd.hpp (original)
+++ trunk/boost/asio/buffered_write_stream_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,8 +15,6 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 
@@ -26,6 +24,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_BUFFERED_WRITE_STREAM_FWD_HPP

Modified: trunk/boost/asio/buffers_iterator.hpp
==============================================================================
--- trunk/boost/asio/buffers_iterator.hpp (original)
+++ trunk/boost/asio/buffers_iterator.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,20 +15,17 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <boost/assert.hpp>
-#include <boost/config.hpp>
 #include <boost/detail/workaround.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>
-
 #include <boost/asio/buffer.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/completion_condition.hpp
==============================================================================
--- trunk/boost/asio/completion_condition.hpp (original)
+++ trunk/boost/asio/completion_condition.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,12 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/datagram_socket_service.hpp
==============================================================================
--- trunk/boost/asio/datagram_socket_service.hpp (original)
+++ trunk/boost/asio/datagram_socket_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,10 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
@@ -32,6 +26,8 @@
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/deadline_timer.hpp
==============================================================================
--- trunk/boost/asio/deadline_timer.hpp (original)
+++ trunk/boost/asio/deadline_timer.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/socket_types.hpp> // Must come before posix_time.
+#include <boost/asio/basic_deadline_timer.hpp>
 
 #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/basic_deadline_timer.hpp>
-
 namespace boost {
 namespace asio {
 
@@ -34,6 +32,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DEADLINE_TIMER_HPP

Modified: trunk/boost/asio/deadline_timer_service.hpp
==============================================================================
--- trunk/boost/asio/deadline_timer_service.hpp (original)
+++ trunk/boost/asio/deadline_timer_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/deadline_timer_service.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/time_traits.hpp>
-#include <boost/asio/detail/deadline_timer_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Added: trunk/boost/asio/detail/array_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/array_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,25 @@
+//
+// detail/array_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_ARRAY_FWD_HPP
+#define BOOST_ASIO_DETAIL_ARRAY_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+namespace boost {
+
+template<class T, std::size_t N>
+class array;
+
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_ARRAY_FWD_HPP

Modified: trunk/boost/asio/detail/base_from_completion_cond.hpp
==============================================================================
--- trunk/boost/asio/detail/base_from_completion_cond.hpp (original)
+++ trunk/boost/asio/detail/base_from_completion_cond.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// base_from_completion_cond.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/base_from_completion_cond.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/completion_condition.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -32,7 +33,8 @@
   {
   }
 
- std::size_t check(const boost::system::error_code& ec,
+ std::size_t check_for_completion(
+ const boost::system::error_code& ec,
       std::size_t total_transferred)
   {
     return detail::adapt_completion_condition_result(
@@ -51,7 +53,8 @@
   {
   }
 
- static std::size_t check(const boost::system::error_code& ec,
+ static std::size_t check_for_completion(
+ const boost::system::error_code& ec,
       std::size_t total_transferred)
   {
     return transfer_all_t()(ec, total_transferred);

Modified: trunk/boost/asio/detail/bind_handler.hpp
==============================================================================
--- trunk/boost/asio/detail/bind_handler.hpp (original)
+++ trunk/boost/asio/detail/bind_handler.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// bind_handler.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/bind_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,12 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/buffer_resize_guard.hpp
==============================================================================
--- trunk/boost/asio/detail/buffer_resize_guard.hpp (original)
+++ trunk/boost/asio/detail/buffer_resize_guard.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// buffer_resize_guard.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// detail/buffer_resize_guard.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,12 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <boost/limits.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/limits.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/detail/buffer_sequence_adapter.hpp
==============================================================================
--- trunk/boost/asio/detail/buffer_sequence_adapter.hpp (original)
+++ trunk/boost/asio/detail/buffer_sequence_adapter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// buffer_sequence_adapter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/buffer_sequence_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,9 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/buffer.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -33,14 +35,14 @@
       const boost::asio::mutable_buffer& buffer)
   {
     buf.buf = boost::asio::buffer_cast<char*>(buffer);
- buf.len = boost::asio::buffer_size(buffer);
+ buf.len = static_cast<ULONG>(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);
+ buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer));
   }
 #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
   typedef iovec native_buffer_type;

Modified: trunk/boost/asio/detail/buffered_stream_storage.hpp
==============================================================================
--- trunk/boost/asio/detail/buffered_stream_storage.hpp (original)
+++ trunk/boost/asio/detail/buffered_stream_storage.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// buffered_stream_storage.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/buffered_stream_storage.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,13 @@
 # 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/config.hpp>
 #include <cassert>
 #include <cstddef>
 #include <cstring>
 #include <vector>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/detail/call_stack.hpp
==============================================================================
--- trunk/boost/asio/detail/call_stack.hpp (original)
+++ trunk/boost/asio/detail/call_stack.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// call_stack.hpp
-// ~~~~~~~~~~~~~~
+// detail/call_stack.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,12 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/tss_ptr.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/completion_handler.hpp
==============================================================================
--- trunk/boost/asio/detail/completion_handler.hpp (original)
+++ trunk/boost/asio/detail/completion_handler.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// completion_handler.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/completion_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.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>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -30,6 +31,8 @@
 class completion_handler : public operation
 {
 public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(completion_handler);
+
   completion_handler(Handler h)
     : operation(&completion_handler::do_complete),
       handler_(h)
@@ -41,20 +44,21 @@
   {
     // 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);
+ ptr p = { boost::addressof(h->handler_), h, h };
+
+ // 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_);
+ p.h = boost::addressof(handler);
+ p.reset();
 
     // 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);
     }

Added: trunk/boost/asio/detail/config.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/config.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,203 @@
+//
+// detail/config.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_CONFIG_HPP
+#define BOOST_ASIO_DETAIL_CONFIG_HPP
+
+#include <boost/config.hpp>
+
+// Default to a header-only implementation. The user must specifically request
+// separate compilation by defining either BOOST_ASIO_SEPARATE_COMPILATION or
+// BOOST_ASIO_DYN_LINK (as a DLL/shared library implies separate compilation).
+#if !defined(BOOST_ASIO_HEADER_ONLY)
+# if !defined(BOOST_ASIO_SEPARATE_COMPILATION)
+# if !defined(BOOST_ASIO_DYN_LINK)
+# define BOOST_ASIO_HEADER_ONLY
+# endif // !defined(BOOST_ASIO_DYN_LINK)
+# endif // !defined(BOOST_ASIO_SEPARATE_COMPILATION)
+#endif // !defined(BOOST_ASIO_HEADER_ONLY)
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# define BOOST_ASIO_DECL inline
+#else // defined(BOOST_ASIO_HEADER_ONLY)
+# if defined(BOOST_HAS_DECLSPEC)
+// We need to import/export our code only if the user has specifically asked
+// for it by defining BOOST_ASIO_DYN_LINK.
+# if defined(BOOST_ASIO_DYN_LINK)
+// Export if this is our own source, otherwise import.
+# if defined(BOOST_ASIO_SOURCE)
+# define BOOST_ASIO_DECL __declspec(dllexport)
+# else // defined(BOOST_ASIO_SOURCE)
+# define BOOST_ASIO_DECL __declspec(dllimport)
+# endif // defined(BOOST_ASIO_SOURCE)
+# endif // defined(BOOST_ASIO_DYN_LINK)
+# endif // defined(BOOST_HAS_DECLSPEC)
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+// If BOOST_ASIO_DECL isn't defined yet define it now.
+#if !defined(BOOST_ASIO_DECL)
+# define BOOST_ASIO_DECL
+#endif // !defined(BOOST_ASIO_DECL)
+
+// Windows: target OS version.
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+# pragma message( \
+ "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
+ "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
+ "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
+ "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
+# else // defined(_MSC_VER) || defined(__BORLANDC__)
+# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
+# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
+# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
+# endif // defined(_MSC_VER) || defined(__BORLANDC__)
+# define _WIN32_WINNT 0x0501
+# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
+# if defined(_MSC_VER)
+# if defined(_WIN32) && !defined(WIN32)
+# if !defined(_WINSOCK2API_)
+# define WIN32 // Needed for correct types in winsock2.h
+# else // !defined(_WINSOCK2API_)
+# error Please define the macro WIN32 in your compiler options
+# endif // !defined(_WINSOCK2API_)
+# endif // defined(_WIN32) && !defined(WIN32)
+# endif // defined(_MSC_VER)
+# if defined(__BORLANDC__)
+# if defined(__WIN32__) && !defined(WIN32)
+# if !defined(_WINSOCK2API_)
+# define WIN32 // Needed for correct types in winsock2.h
+# else // !defined(_WINSOCK2API_)
+# error Please define the macro WIN32 in your compiler options
+# endif // !defined(_WINSOCK2API_)
+# endif // defined(__WIN32__) && !defined(WIN32)
+# endif // defined(__BORLANDC__)
+# if defined(__CYGWIN__)
+# if !defined(__USE_W32_SOCKETS)
+# error You must add -D__USE_W32_SOCKETS to your compiler options.
+# endif // !defined(__USE_W32_SOCKETS)
+# endif // defined(__CYGWIN__)
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: minimise header inclusion.
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
+# if !defined(WIN32_LEAN_AND_MEAN)
+# define WIN32_LEAN_AND_MEAN
+# endif // !defined(WIN32_LEAN_AND_MEAN)
+# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: suppress definition of "min" and "max" macros.
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if !defined(BOOST_ASIO_NO_NOMINMAX)
+# if !defined(NOMINMAX)
+# define NOMINMAX 1
+# endif // !defined(NOMINMAX)
+# endif // !defined(BOOST_ASIO_NO_NOMINMAX)
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+// Windows: IO Completion Ports.
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+# if !defined(UNDER_CE)
+# if !defined(BOOST_ASIO_DISABLE_IOCP)
+# define BOOST_ASIO_HAS_IOCP 1
+# endif // !defined(BOOST_ASIO_DISABLE_IOCP)
+# endif // !defined(UNDER_CE)
+# endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+// Linux: epoll, eventfd and timerfd.
+#if defined(__linux__)
+# include <linux/version.h>
+# if !defined(BOOST_ASIO_DISABLE_EPOLL)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
+# define BOOST_ASIO_HAS_EPOLL 1
+# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,45)
+# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD)
+# if !defined(BOOST_ASIO_DISABLE_EVENTFD)
+# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+# define BOOST_ASIO_HAS_EVENTFD 1
+# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD)
+# if defined(BOOST_ASIO_HAS_EPOLL)
+# if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+# define BOOST_ASIO_HAS_TIMERFD 1
+# endif // (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)
+# endif // defined(BOOST_ASIO_HAS_EPOLL)
+#endif // defined(__linux__)
+
+// Mac OS X, FreeBSD, NetBSD, OpenBSD: kqueue.
+#if (defined(__MACH__) && defined(__APPLE__)) \
+ || defined(__FreeBSD__) \
+ || defined(__NetBSD__) \
+ || defined(__OpenBSD__)
+# if !defined(BOOST_ASIO_DISABLE_KQUEUE)
+# define BOOST_ASIO_HAS_KQUEUE 1
+# endif // !defined(BOOST_ASIO_DISABLE_KQUEUE)
+#endif // (defined(__MACH__) && defined(__APPLE__))
+ // || defined(__FreeBSD__)
+ // || defined(__NetBSD__)
+ // || defined(__OpenBSD__)
+
+// Solaris: /dev/poll.
+#if defined(__sun)
+# if !defined(BOOST_ASIO_DISABLE_DEV_POLL)
+# define BOOST_ASIO_HAS_DEV_POLL 1
+# endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL)
+#endif // defined(__sun)
+
+// Serial ports.
+#if defined(BOOST_ASIO_HAS_IOCP) \
+ || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+# if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
+# define BOOST_ASIO_HAS_SERIAL_PORT 1
+# endif // !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ // || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+// Windows: stream handles.
+#if !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
+# if defined(BOOST_ASIO_HAS_IOCP)
+# define BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE 1
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
+
+// Windows: random access handles.
+#if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+# if defined(BOOST_ASIO_HAS_IOCP)
+# define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
+
+// Windows: OVERLAPPED wrapper.
+#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+# if defined(BOOST_ASIO_HAS_IOCP)
+# define BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1
+# endif // defined(BOOST_ASIO_HAS_IOCP)
+#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
+
+// POSIX: stream-oriented file descriptors.
+#if !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
+# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1
+# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#endif // !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
+
+// UNIX domain sockets.
+#if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
+# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+# define BOOST_ASIO_HAS_LOCAL_SOCKETS 1
+# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
+
+#endif // BOOST_ASIO_DETAIL_CONFIG_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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// consuming_buffers.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// detail/consuming_buffers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,18 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <algorithm>
+#include <boost/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <boost/iterator.hpp>
 #include <boost/limits.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffer.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// deadline_timer_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/deadline_timer_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,8 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.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>
@@ -33,6 +27,13 @@
 #include <boost/asio/detail/timer_op.hpp>
 #include <boost/asio/detail/timer_queue.hpp>
 #include <boost/asio/detail/timer_scheduler.hpp>
+#include <boost/asio/detail/wait_handler.hpp>
+
+#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/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -152,59 +153,21 @@
     ec = boost::system::error_code();
   }
 
- template <typename Handler>
- class wait_handler : public timer_op
- {
- public:
- wait_handler(Handler handler)
- : timer_op(&wait_handler::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.
- 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:
- 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);
+ typedef wait_handler<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
 
     impl.might_have_pending_waits = true;
 
- scheduler_.schedule_timer(timer_queue_, impl.expiry, ptr.get(), &impl);
- ptr.release();
+ scheduler_.schedule_timer(timer_queue_, impl.expiry, p.p, &impl);
+ p.v = p.p = 0;
   }
 
 private:

Modified: trunk/boost/asio/detail/descriptor_ops.hpp
==============================================================================
--- trunk/boost/asio/detail/descriptor_ops.hpp (original)
+++ trunk/boost/asio/detail/descriptor_ops.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// descriptor_ops.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/descriptor_ops.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,28 +15,35 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <cerrno>
-#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
-#include <boost/asio/error.hpp>
+#include <cstddef>
+#include <boost/system/error_code.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
-#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 namespace descriptor_ops {
 
-inline void clear_error(boost::system::error_code& ec)
+// Descriptor state bits.
+enum
 {
- errno = 0;
- ec = boost::system::error_code();
-}
+ // The user wants a non-blocking descriptor.
+ user_set_non_blocking = 1,
+
+ // The descriptor has been set non-blocking.
+ internal_non_blocking = 2,
+
+ // Helper "state" used to determine whether the descriptor is non-blocking.
+ non_blocking = user_set_non_blocking | internal_non_blocking
+};
+
+typedef unsigned char state_type;
 
 template <typename ReturnType>
 inline ReturnType error_wrapper(ReturnType return_value,
@@ -47,132 +54,54 @@
   return return_value;
 }
 
-inline int open(const char* path, int flags, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::open(path, flags), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int open(const char* path, int flags,
+ boost::system::error_code& ec);
 
-inline int close(int d, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::close(d), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int close(int d, state_type& state,
+ boost::system::error_code& ec);
 
-inline void init_buf_iov_base(void*& base, void* addr)
-{
- base = addr;
-}
-
-template <typename T>
-inline void init_buf_iov_base(T& base, void* addr)
-{
- base = static_cast<T>(addr);
-}
+BOOST_ASIO_DECL bool set_internal_non_blocking(int d,
+ state_type& state, boost::system::error_code& ec);
 
 typedef iovec buf;
 
-inline void init_buf(buf& b, void* data, size_t size)
-{
- init_buf_iov_base(b.iov_base, data);
- b.iov_len = size;
-}
+BOOST_ASIO_DECL std::size_t sync_read(int d, state_type state, buf* bufs,
+ std::size_t count, bool all_empty, boost::system::error_code& ec);
 
-inline void init_buf(buf& b, const void* data, size_t size)
-{
- init_buf_iov_base(b.iov_base, const_cast<void*>(data));
- b.iov_len = size;
-}
+BOOST_ASIO_DECL bool non_blocking_read(int d, buf* bufs, std::size_t count,
+ boost::system::error_code& ec, std::size_t& bytes_transferred);
 
-inline int scatter_read(int d, buf* bufs, size_t count,
- boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL std::size_t sync_write(int d, state_type state,
+ const buf* bufs, std::size_t count, bool all_empty,
+ boost::system::error_code& ec);
 
-inline int gather_write(int d, const buf* bufs, size_t count,
- boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL bool non_blocking_write(int d,
+ const buf* bufs, std::size_t count,
+ boost::system::error_code& ec, std::size_t& bytes_transferred);
 
-inline int ioctl(int d, long cmd, ioctl_arg_type* arg,
- boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::ioctl(d, cmd, arg), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int ioctl(int d, state_type& state, long cmd,
+ ioctl_arg_type* arg, boost::system::error_code& ec);
 
-inline int fcntl(int d, long cmd, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::fcntl(d, cmd), ec);
- if (result != -1)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int fcntl(int d, long cmd, boost::system::error_code& ec);
 
-inline int fcntl(int d, long cmd, long arg, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::fcntl(d, cmd, arg), ec);
- if (result != -1)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int fcntl(int d, long cmd,
+ long arg, boost::system::error_code& ec);
 
-inline int poll_read(int d, boost::system::error_code& ec)
-{
- clear_error(ec);
- pollfd fds;
- fds.fd = d;
- fds.events = POLLIN;
- fds.revents = 0;
- clear_error(ec);
- int result = error_wrapper(::poll(&fds, 1, -1), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int poll_read(int d, boost::system::error_code& ec);
 
-inline int poll_write(int d, boost::system::error_code& ec)
-{
- clear_error(ec);
- pollfd fds;
- fds.fd = d;
- fds.events = POLLOUT;
- fds.revents = 0;
- clear_error(ec);
- int result = error_wrapper(::poll(&fds, 1, -1), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int poll_write(int d, boost::system::error_code& ec);
 
 } // namespace descriptor_ops
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/descriptor_ops.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_DESCRIPTOR_OPS_HPP

Added: trunk/boost/asio/detail/descriptor_read_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/descriptor_read_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,116 @@
+//
+// detail/descriptor_read_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_DESCRIPTOR_READ_OP_HPP
+#define BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/detail/bind_handler.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/reactor_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class descriptor_read_op_base : public reactor_op
+{
+public:
+ descriptor_read_op_base(int descriptor,
+ const MutableBufferSequence& buffers, func_type complete_func)
+ : reactor_op(&descriptor_read_op_base::do_perform, complete_func),
+ descriptor_(descriptor),
+ buffers_(buffers)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ descriptor_read_op_base* o(static_cast<descriptor_read_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ return descriptor_ops::non_blocking_read(o->descriptor_,
+ bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
+ }
+
+private:
+ int descriptor_;
+ MutableBufferSequence buffers_;
+};
+
+template <typename MutableBufferSequence, typename Handler>
+class descriptor_read_op
+ : public descriptor_read_op_base<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
+
+ descriptor_read_op(int descriptor,
+ const MutableBufferSequence& buffers, Handler handler)
+ : descriptor_read_op_base<MutableBufferSequence>(
+ descriptor, buffers, &descriptor_read_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.
+ descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_READ_OP_HPP

Added: trunk/boost/asio/detail/descriptor_write_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/descriptor_write_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,116 @@
+//
+// detail/descriptor_write_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_DESCRIPTOR_WRITE_OP_HPP
+#define BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/detail/bind_handler.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/reactor_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence>
+class descriptor_write_op_base : public reactor_op
+{
+public:
+ descriptor_write_op_base(int descriptor,
+ const ConstBufferSequence& buffers, func_type complete_func)
+ : reactor_op(&descriptor_write_op_base::do_perform, complete_func),
+ descriptor_(descriptor),
+ buffers_(buffers)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ descriptor_write_op_base* o(static_cast<descriptor_write_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(o->buffers_);
+
+ return descriptor_ops::non_blocking_write(o->descriptor_,
+ bufs.buffers(), bufs.count(), o->ec_, o->bytes_transferred_);
+ }
+
+private:
+ int descriptor_;
+ ConstBufferSequence buffers_;
+};
+
+template <typename ConstBufferSequence, typename Handler>
+class descriptor_write_op
+ : public descriptor_write_op_base<ConstBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
+
+ descriptor_write_op(int descriptor,
+ const ConstBufferSequence& buffers, Handler handler)
+ : descriptor_write_op_base<ConstBufferSequence>(
+ descriptor, buffers, &descriptor_write_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.
+ descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_DESCRIPTOR_WRITE_OP_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// dev_poll_reactor.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/dev_poll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,36 +15,28 @@
 # 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/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_DEV_POLL)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
 #include <vector>
-#include <boost/config.hpp>
-#include <boost/date_time/posix_time/posix_time_types.hpp>
-#include <boost/throw_exception.hpp>
 #include <sys/devpoll.h>
-#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/dev_poll_reactor_fwd.hpp>
 #include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/mutex.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/socket_types.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/io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -63,358 +55,91 @@
   };
 
   // Constructor.
- dev_poll_reactor(boost::asio::io_service& 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()),
- interrupter_(),
- shutdown_(false)
- {
- // Add the interrupter's descriptor to /dev/poll.
- ::pollfd ev = { 0 };
- ev.fd = interrupter_.read_descriptor();
- ev.events = POLLIN | POLLERR;
- ev.revents = 0;
- ::write(dev_poll_fd_, &ev, sizeof(ev));
- }
+ BOOST_ASIO_DECL dev_poll_reactor(boost::asio::io_service& io_service);
 
   // Destructor.
- ~dev_poll_reactor()
- {
- shutdown_service();
- ::close(dev_poll_fd_);
- }
+ BOOST_ASIO_DECL ~dev_poll_reactor();
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- shutdown_ = true;
- lock.unlock();
-
- 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);
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task.
- void init_task()
- {
- io_service_.init_task();
- }
+ BOOST_ASIO_DECL void 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&)
+ BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&);
+
+ // Post a reactor operation for immediate completion.
+ void post_immediate_completion(reactor_op* op)
   {
- return 0;
+ io_service_.post_immediate_completion(op);
   }
 
   // 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)
- {
- if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor))
- {
- if (!op_queue_[op_type].has_operation(descriptor))
- {
- if (op->perform())
- {
- lock.unlock();
- io_service_.post_immediate_completion(op);
- return;
- }
- }
- }
- }
-
- 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 = POLLERR | POLLHUP;
- if (op_type == read_op
- || op_queue_[read_op].has_operation(descriptor))
- ev.events |= POLLIN;
- if (op_type == write_op
- || op_queue_[write_op].has_operation(descriptor))
- ev.events |= POLLOUT;
- if (op_type == except_op
- || op_queue_[except_op].has_operation(descriptor))
- ev.events |= POLLPRI;
- interrupter_.interrupt();
- }
- }
+ BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
+ per_descriptor_data&, reactor_op* op, bool allow_speculative);
 
   // 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&)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
- }
+ BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
 
   // 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&)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- // Remove the descriptor from /dev/poll.
- ::pollfd& ev = add_pending_event_change(descriptor);
- ev.events = POLLREMOVE;
- interrupter_.interrupt();
-
- // Cancel any outstanding operations associated with the descriptor.
- cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
- }
+ BOOST_ASIO_DECL void close_descriptor(
+ socket_type descriptor, per_descriptor_data&);
 
   // 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_.insert(&timer_queue);
- }
+ void add_timer_queue(timer_queue<Time_Traits>& 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_);
- timer_queues_.erase(&timer_queue);
- }
+ void remove_timer_queue(timer_queue<Time_Traits>& queue);
 
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
- void schedule_timer(timer_queue<Time_Traits>& timer_queue,
- const typename Time_Traits::time_type& time, timer_op* op, void* token)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (!shutdown_)
- {
- bool earliest = timer_queue.enqueue_timer(time, op, token);
- io_service_.work_started();
- if (earliest)
- interrupter_.interrupt();
- }
- }
+ void schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token);
 
   // 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_);
- op_queue<operation> ops;
- std::size_t n = timer_queue.cancel_timer(token, ops);
- lock.unlock();
- io_service_.post_deferred_completions(ops);
- return n;
- }
+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
 
   // Run /dev/poll once until interrupted or events are ready to be dispatched.
- void run(bool block, op_queue<operation>& ops)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- // We can return immediately if there's no work to do and the reactor is
- // not supposed to block.
- 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();
- if (events_size > 0)
- {
- errno = 0;
- int result = ::write(dev_poll_fd_,
- &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;
- for (int j = 0; j < max_ops; ++j)
- op_queue_[j].cancel_operations(descriptor, ops, ec);
- }
- }
- pending_event_changes_.clear();
- pending_event_change_index_.clear();
- }
-
- int timeout = block ? get_timeout() : 0;
- lock.unlock();
-
- // Block on the /dev/poll descriptor.
- ::pollfd events[128] = { { 0 } };
- ::dvpoll dp = { 0 };
- dp.dp_fds = events;
- dp.dp_nfds = 128;
- dp.dp_timeout = timeout;
- int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp);
-
- lock.lock();
-
- // Dispatch the waiting events.
- for (int i = 0; i < num_events; ++i)
- {
- int descriptor = events[i].fd;
- if (descriptor == interrupter_.read_descriptor())
- {
- interrupter_.reset();
- }
- else
- {
- bool more_reads = false;
- bool more_writes = false;
- bool more_except = false;
-
- // 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 =
- op_queue_[except_op].perform_operations(descriptor, ops);
- else
- more_except = op_queue_[except_op].has_operation(descriptor);
-
- if (events[i].events & (POLLIN | POLLERR | POLLHUP))
- more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
- else
- more_reads = op_queue_[read_op].has_operation(descriptor);
-
- if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
- more_writes = op_queue_[write_op].perform_operations(descriptor, ops);
- else
- more_writes = op_queue_[write_op].has_operation(descriptor);
-
- if ((events[i].events & (POLLERR | POLLHUP)) != 0
- && !more_except && !more_reads && !more_writes)
- {
- // If we have an event and no operations associated with the
- // descriptor then we need to delete the descriptor from /dev/poll.
- // The poll operation can produce POLLHUP or POLLERR events when there
- // is no operation pending, so if we do not remove the descriptor we
- // can end up in a tight polling loop.
- ::pollfd ev = { 0 };
- ev.fd = descriptor;
- ev.events = POLLREMOVE;
- ev.revents = 0;
- ::write(dev_poll_fd_, &ev, sizeof(ev));
- }
- else
- {
- ::pollfd ev = { 0 };
- ev.fd = descriptor;
- ev.events = POLLERR | POLLHUP;
- if (more_reads)
- ev.events |= POLLIN;
- if (more_writes)
- ev.events |= POLLOUT;
- if (more_except)
- ev.events |= POLLPRI;
- ev.revents = 0;
- int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
- if (result != sizeof(ev))
- {
- boost::system::error_code ec(errno,
- boost::asio::error::get_system_category());
- for (int j = 0; j < max_ops; ++j)
- op_queue_[j].cancel_operations(descriptor, ops, ec);
- }
- }
- }
- }
- timer_queues_.get_ready_timers(ops);
- }
+ BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
   // Interrupt the select loop.
- void interrupt()
- {
- interrupter_.interrupt();
- }
+ BOOST_ASIO_DECL void interrupt();
 
 private:
   // Create the /dev/poll file descriptor. Throws an exception if the descriptor
   // cannot be created.
- static int do_dev_poll_create()
- {
- int fd = ::open("/dev/poll", O_RDWR);
- if (fd == -1)
- {
- boost::throw_exception(
- boost::system::system_error(
- boost::system::error_code(errno,
- boost::asio::error::get_system_category()),
- "/dev/poll"));
- }
- return fd;
- }
+ BOOST_ASIO_DECL static int do_dev_poll_create();
+
+ // Helper function to add a new timer queue.
+ BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+ // Helper function to remove a timer queue.
+ BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
 
   // 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()
- {
- // 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.
- return timer_queues_.wait_duration_msec(5 * 60 * 1000);
- }
+ BOOST_ASIO_DECL int get_timeout();
 
   // 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,
- 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();
- }
+ BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor,
+ const boost::system::error_code& ec);
 
   // Add a pending event entry for the given descriptor.
- ::pollfd& add_pending_event_change(int descriptor)
- {
- hash_map<int, std::size_t>::iterator iter
- = pending_event_change_index_.find(descriptor);
- if (iter == pending_event_change_index_.end())
- {
- std::size_t index = pending_event_changes_.size();
- pending_event_changes_.reserve(pending_event_changes_.size() + 1);
- pending_event_change_index_.insert(std::make_pair(descriptor, index));
- pending_event_changes_.push_back(::pollfd());
- pending_event_changes_[index].fd = descriptor;
- pending_event_changes_[index].revents = 0;
- return pending_event_changes_[index];
- }
- else
- {
- return pending_event_changes_[iter->second];
- }
- }
+ BOOST_ASIO_DECL ::pollfd& add_pending_event_change(int descriptor);
 
   // The io_service implementation used to post completions.
   io_service_impl& io_service_;
@@ -448,8 +173,13 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/dev_poll_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/dev_poll_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
 #endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// dev_poll_reactor_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/dev_poll_reactor_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,9 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_DEV_POLL)
-#if defined(__sun) // This service is only supported on Solaris.
-
-// Define this to indicate that /dev/poll is supported on the target platform.
-#define BOOST_ASIO_HAS_DEV_POLL 1
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
 
 namespace boost {
 namespace asio {
@@ -33,9 +29,6 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(__sun)
-#endif // !defined(BOOST_ASIO_DISABLE_DEV_POLL)
-
-#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
 
 #endif // BOOST_ASIO_DETAIL_DEV_POLL_REACTOR_FWD_HPP

Modified: trunk/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/epoll_reactor.hpp (original)
+++ trunk/boost/asio/detail/epoll_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// epoll_reactor.hpp
-// ~~~~~~~~~~~~~~~~~
+// detail/epoll_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,43 +15,24 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/epoll_reactor_fwd.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_EPOLL)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <sys/epoll.h>
-#include <boost/config.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/epoll_reactor_fwd.hpp>
 #include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/mutex.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/socket_types.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)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -80,342 +61,69 @@
   typedef descriptor_state* per_descriptor_data;
 
   // Constructor.
- epoll_reactor(boost::asio::io_service& 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()),
-#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_(),
- shutdown_(false)
- {
- // Add the interrupter's descriptor to epoll.
- epoll_event ev = { 0, { 0 } };
- 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);
- }
- }
+ BOOST_ASIO_DECL epoll_reactor(boost::asio::io_service& io_service);
 
   // Destructor.
- ~epoll_reactor()
- {
- close(epoll_fd_);
- if (timer_fd_ != -1)
- close(timer_fd_);
- }
+ BOOST_ASIO_DECL ~epoll_reactor();
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- mutex::scoped_lock lock(mutex_);
- shutdown_ = true;
- lock.unlock();
-
- op_queue<operation> ops;
-
- descriptor_map::iterator iter = registered_descriptors_.begin();
- descriptor_map::iterator end = registered_descriptors_.end();
- while (iter != end)
- {
- for (int i = 0; i < max_ops; ++i)
- ops.push(iter->second.op_queue_[i]);
- iter->second.shutdown_ = true;
- ++iter;
- }
-
- timer_queues_.get_all_timers(ops);
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task.
- void init_task()
- {
- io_service_.init_task();
- }
+ BOOST_ASIO_DECL void init_task();
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type descriptor,
- per_descriptor_data& descriptor_data)
- {
- mutex::scoped_lock lock(registered_descriptors_mutex_);
-
- descriptor_map::iterator new_entry = registered_descriptors_.insert(
- std::make_pair(descriptor, descriptor_state())).first;
- descriptor_data = &new_entry->second;
-
- epoll_event ev = { 0, { 0 } };
- 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;
+ BOOST_ASIO_DECL int register_descriptor(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
- descriptor_data->shutdown_ = false;
-
- return 0;
+ // Post a reactor operation for immediate completion.
+ void post_immediate_completion(reactor_op* op)
+ {
+ io_service_.post_immediate_completion(op);
   }
 
   // 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,
+ BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
       per_descriptor_data& descriptor_data,
- reactor_op* op, bool allow_speculative)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
- if (descriptor_data->shutdown_)
- return;
-
- if (descriptor_data->op_queue_[op_type].empty())
- {
- if (allow_speculative
- && (op_type != read_op
- || descriptor_data->op_queue_[except_op].empty()))
- {
- if (op->perform())
- {
- descriptor_lock.unlock();
- io_service_.post_immediate_completion(op);
- return;
- }
- }
- else
- {
- 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);
- }
- }
-
- descriptor_data->op_queue_[op_type].push(op);
- io_service_.work_started();
- }
+ reactor_op* op, bool allow_speculative);
 
   // 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& descriptor_data)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
-
- op_queue<operation> ops;
- for (int i = 0; i < max_ops; ++i)
- {
- while (reactor_op* op = descriptor_data->op_queue_[i].front())
- {
- op->ec_ = boost::asio::error::operation_aborted;
- descriptor_data->op_queue_[i].pop();
- ops.push(op);
- }
- }
-
- descriptor_lock.unlock();
-
- io_service_.post_deferred_completions(ops);
- }
+ BOOST_ASIO_DECL void cancel_ops(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
   // 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& descriptor_data)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
- mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
-
- // Remove the descriptor from the set of known descriptors. The descriptor
- // will be automatically removed from the epoll set when it is closed.
- descriptor_data->shutdown_ = true;
-
- op_queue<operation> ops;
- for (int i = 0; i < max_ops; ++i)
- {
- while (reactor_op* op = descriptor_data->op_queue_[i].front())
- {
- op->ec_ = boost::asio::error::operation_aborted;
- descriptor_data->op_queue_[i].pop();
- ops.push(op);
- }
- }
-
- descriptor_lock.unlock();
-
- registered_descriptors_.erase(descriptor);
-
- descriptors_lock.unlock();
-
- io_service_.post_deferred_completions(ops);
- }
+ BOOST_ASIO_DECL void close_descriptor(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
   // Add a new timer queue to the reactor.
   template <typename Time_Traits>
- void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- mutex::scoped_lock lock(mutex_);
- timer_queues_.insert(&timer_queue);
- }
+ void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
 
   // Remove a timer queue from the reactor.
   template <typename Time_Traits>
- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- mutex::scoped_lock lock(mutex_);
- timer_queues_.erase(&timer_queue);
- }
+ void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
 
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
   void schedule_timer(timer_queue<Time_Traits>& timer_queue,
- const typename Time_Traits::time_type& time, timer_op* op, void* token)
- {
- mutex::scoped_lock lock(mutex_);
- if (!shutdown_)
- {
- 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();
- }
- }
- }
+ const typename Time_Traits::time_type& time, timer_op* op, void* token);
 
   // 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)
- {
- 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;
- }
+ std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token);
 
   // Run epoll once until interrupted or events are ready to be dispatched.
- void run(bool block, op_queue<operation>& ops)
- {
- // Calculate a timeout only if timerfd is not used.
- int timeout;
- if (timer_fd_ != -1)
- timeout = block ? -1 : 0;
- else
- {
- mutex::scoped_lock lock(mutex_);
- timeout = block ? get_timeout() : 0;
- }
-
- // Block on the epoll descriptor.
- epoll_event events[128];
- int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
-
-#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)
- {
- void* ptr = events[i].data.ptr;
- if (ptr == &interrupter_)
- {
- // 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
- {
- 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.
- static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
- for (int j = max_ops - 1; j >= 0; --j)
- {
- if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP))
- {
- while (reactor_op* op = descriptor_data->op_queue_[j].front())
- {
- if (op->perform())
- {
- descriptor_data->op_queue_[j].pop();
- ops.push(op);
- }
- else
- break;
- }
- }
- }
- }
- }
-
- if (check_timers)
- {
- mutex::scoped_lock common_lock(mutex_);
- timer_queues_.get_ready_timers(ops);
-
-#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)
- }
- }
+ BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
   // Interrupt the select loop.
- void 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);
- }
+ BOOST_ASIO_DECL void interrupt();
 
 private:
   // The hint to pass to epoll_create to size its data structures.
@@ -423,44 +131,26 @@
 
   // Create the epoll file descriptor. Throws an exception if the descriptor
   // cannot be created.
- static int do_epoll_create()
- {
- int fd = epoll_create(epoll_size);
- if (fd == -1)
- {
- boost::throw_exception(
- boost::system::system_error(
- boost::system::error_code(errno,
- boost::asio::error::get_system_category()),
- "epoll"));
- }
- return fd;
- }
+ BOOST_ASIO_DECL static int do_epoll_create();
+
+ // Helper function to add a new timer queue.
+ BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+ // Helper function to remove a timer queue.
+ BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
+
+ // Called to recalculate and update the timeout.
+ BOOST_ASIO_DECL void update_timeout();
 
   // 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()
- {
- // 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.
- return timer_queues_.wait_duration_msec(5 * 60 * 1000);
- }
+ BOOST_ASIO_DECL int get_timeout();
 
 #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)
- {
- 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;
- }
+ BOOST_ASIO_DECL int get_timeout(itimerspec& ts);
 #endif // defined(BOOST_ASIO_HAS_TIMERFD)
 
   // The io_service implementation used to post completions.
@@ -502,8 +192,13 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_EPOLL)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/epoll_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/epoll_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
 #endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// epoll_reactor_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// detail/epoll_reactor_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,19 +15,9 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_EPOLL)
-#if defined(__linux__) // This service is only supported on Linux.
-
-#include <boost/asio/detail/push_options.hpp>
-#include <linux/version.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45) // Only kernels >= 2.5.45.
-
-// Define this to indicate that epoll is supported on the target platform.
-#define BOOST_ASIO_HAS_EPOLL 1
+#if defined(BOOST_ASIO_HAS_EPOLL)
 
 namespace boost {
 namespace asio {
@@ -39,10 +29,6 @@
 } // namespace asio
 } // namespace boost
 
-#endif // LINUX_VERSION_CODE >= KERNEL_VERSION (2,5,45)
-#endif // defined(__linux__)
-#endif // !defined(BOOST_ASIO_DISABLE_EPOLL)
-
-#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
 
 #endif // BOOST_ASIO_DETAIL_EPOLL_REACTOR_FWD_HPP

Modified: trunk/boost/asio/detail/event.hpp
==============================================================================
--- trunk/boost/asio/detail/event.hpp (original)
+++ trunk/boost/asio/detail/event.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// event.hpp
-// ~~~~~~~~~
+// detail/event.hpp
+// ~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_event.hpp>
@@ -47,6 +43,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_EVENT_HPP

Modified: trunk/boost/asio/detail/eventfd_select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/eventfd_select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/eventfd_select_interrupter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// eventfd_select_interrupter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/eventfd_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
@@ -16,36 +16,11 @@
 # 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/throw_exception.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#if defined(__linux__)
-# if !defined(BOOST_ASIO_DISABLE_EVENTFD)
-# include <linux/version.h>
-# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-# define BOOST_ASIO_HAS_EVENTFD
-# endif // LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-# endif // !defined(BOOST_ASIO_DISABLE_EVENTFD)
-#endif // defined(__linux__)
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_EVENTFD)
 
 #include <boost/asio/detail/push_options.hpp>
-#include <fcntl.h>
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
-# include <asm/unistd.h>
-#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
-# include <sys/eventfd.h>
-#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_types.hpp>
 
 namespace boost {
 namespace asio {
@@ -55,87 +30,16 @@
 {
 public:
   // Constructor.
- eventfd_select_interrupter()
- {
-#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
- write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
-#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
- write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
-#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
- if (read_descriptor_ != -1)
- {
- ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
- }
- else
- {
- int pipe_fds[2];
- if (pipe(pipe_fds) == 0)
- {
- read_descriptor_ = pipe_fds[0];
- ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
- write_descriptor_ = pipe_fds[1];
- ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
- }
- else
- {
- boost::system::error_code ec(errno,
- boost::asio::error::get_system_category());
- boost::system::system_error e(ec, "eventfd_select_interrupter");
- boost::throw_exception(e);
- }
- }
- }
+ BOOST_ASIO_DECL eventfd_select_interrupter();
 
   // Destructor.
- ~eventfd_select_interrupter()
- {
- if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_)
- ::close(write_descriptor_);
- if (read_descriptor_ != -1)
- ::close(read_descriptor_);
- }
+ BOOST_ASIO_DECL ~eventfd_select_interrupter();
 
   // Interrupt the select call.
- void interrupt()
- {
- uint64_t counter(1UL);
- int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
- (void)result;
- }
+ BOOST_ASIO_DECL void interrupt();
 
   // Reset the select interrupt. Returns true if the call was interrupted.
- bool reset()
- {
- if (write_descriptor_ == read_descriptor_)
- {
- for (;;)
- {
- // Only perform one read. The kernel maintains an atomic counter.
- uint64_t counter(0);
- errno = 0;
- int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
- if (bytes_read < 0 && errno == EINTR)
- continue;
- bool was_interrupted = (bytes_read > 0);
- return was_interrupted;
- }
- }
- else
- {
- for (;;)
- {
- // Clear all data from the pipe.
- char data[1024];
- int bytes_read = ::read(read_descriptor_, data, sizeof(data));
- if (bytes_read < 0 && errno == EINTR)
- continue;
- bool was_interrupted = (bytes_read > 0);
- while (bytes_read == sizeof(data))
- bytes_read = ::read(read_descriptor_, data, sizeof(data));
- return was_interrupted;
- }
- }
- }
+ BOOST_ASIO_DECL bool reset();
 
   // Get the read descriptor to be passed to select.
   int read_descriptor() const
@@ -161,8 +65,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_EVENTFD)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/eventfd_select_interrupter.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_EVENTFD)
+
 #endif // BOOST_ASIO_DETAIL_EVENTFD_SELECT_INTERRUPTER_HPP

Modified: trunk/boost/asio/detail/fd_set_adapter.hpp
==============================================================================
--- trunk/boost/asio/detail/fd_set_adapter.hpp (original)
+++ trunk/boost/asio/detail/fd_set_adapter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// fd_set_adapter.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/fd_set_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,12 +15,7 @@
 # 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>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/posix_fd_set_adapter.hpp>
 #include <boost/asio/detail/win_fd_set_adapter.hpp>
 
@@ -38,6 +33,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_FD_SET_ADAPTER_HPP

Modified: trunk/boost/asio/detail/fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/fenced_block.hpp (original)
+++ trunk/boost/asio/detail/fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// fenced_block.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_fenced_block.hpp>
@@ -67,6 +63,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_FENCED_BLOCK_HPP

Modified: trunk/boost/asio/detail/gcc_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/gcc_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/gcc_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// gcc_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/gcc_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,15 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(__GNUC__) \
   && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)) \
   && !defined(__INTEL_COMPILER) && !defined(__ICL) \
   && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -55,11 +53,11 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(__GNUC__)
        // && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4))
        // && !defined(__INTEL_COMPILER) && !defined(__ICL)
        // && !defined(__ICC) && !defined(__ECC) && !defined(__PATHSCALE__)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_GCC_FENCED_BLOCK_HPP

Modified: trunk/boost/asio/detail/gcc_x86_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/gcc_x86_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/gcc_x86_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// gcc_x86_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/gcc_x86_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,12 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -56,8 +54,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+
 #endif // BOOST_ASIO_DETAIL_GCC_X86_FENCED_BLOCK_HPP

Modified: trunk/boost/asio/detail/handler_alloc_helpers.hpp
==============================================================================
--- trunk/boost/asio/detail/handler_alloc_helpers.hpp (original)
+++ trunk/boost/asio/detail/handler_alloc_helpers.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// handler_alloc_helpers.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/handler_alloc_helpers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/utility/addressof.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/handler_alloc_hook.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/handler_alloc_hook.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 // Calls to asio_handler_allocate and asio_handler_deallocate must be made from
 // a namespace that does not contain any overloads of these functions. The
@@ -56,205 +54,31 @@
 
 } // namespace boost_asio_handler_alloc_helpers
 
-namespace boost {
-namespace asio {
-namespace detail {
-
-// Traits for handler allocation.
-template <typename Handler, typename Object>
-struct handler_alloc_traits
-{
- typedef Handler handler_type;
- typedef Object value_type;
- typedef Object* pointer_type;
- BOOST_STATIC_CONSTANT(std::size_t, value_size = sizeof(Object));
-};
-
-template <typename Alloc_Traits>
-class handler_ptr;
-
-// Helper class to provide RAII on uninitialised handler memory.
-template <typename Alloc_Traits>
-class raw_handler_ptr
- : private noncopyable
-{
-public:
- typedef typename Alloc_Traits::handler_type handler_type;
- typedef typename Alloc_Traits::value_type value_type;
- typedef typename Alloc_Traits::pointer_type pointer_type;
- BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
-
- // Constructor allocates the memory.
- raw_handler_ptr(handler_type& handler)
- : handler_(handler),
- pointer_(static_cast<pointer_type>(
- boost_asio_handler_alloc_helpers::allocate(value_size, handler_)))
- {
- }
-
- // Destructor automatically deallocates memory, unless it has been stolen by
- // a handler_ptr object.
- ~raw_handler_ptr()
- {
- if (pointer_)
- boost_asio_handler_alloc_helpers::deallocate(
- pointer_, value_size, handler_);
- }
-
-private:
- friend class handler_ptr<Alloc_Traits>;
- handler_type& handler_;
- pointer_type pointer_;
-};
-
-// Helper class to provide RAII on uninitialised handler memory.
-template <typename Alloc_Traits>
-class handler_ptr
- : private noncopyable
-{
-public:
- typedef typename Alloc_Traits::handler_type handler_type;
- typedef typename Alloc_Traits::value_type value_type;
- typedef typename Alloc_Traits::pointer_type pointer_type;
- BOOST_STATIC_CONSTANT(std::size_t, value_size = Alloc_Traits::value_size);
- typedef raw_handler_ptr<Alloc_Traits> raw_ptr_type;
-
- // Take ownership of existing memory.
- handler_ptr(handler_type& handler, pointer_type pointer)
- : handler_(handler),
- pointer_(pointer)
- {
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- handler_ptr(raw_ptr_type& raw_ptr)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type)
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
- typename Arg5>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
- Arg5& a5)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
- typename Arg5, typename Arg6>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
- Arg5& a5, Arg6& a6)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
- typename Arg5, typename Arg6, typename Arg7>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
- Arg5& a5, Arg6& a6, Arg7& a7)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(a1, a2, a3, a4, a5, a6, a7))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Construct object in raw memory and take ownership if construction succeeds.
- template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
- typename Arg5, typename Arg6, typename Arg7, typename Arg8>
- handler_ptr(raw_ptr_type& raw_ptr, Arg1& a1, Arg2& a2, Arg3& a3, Arg4& a4,
- Arg5& a5, Arg6& a6, Arg7& a7, Arg8& a8)
- : handler_(raw_ptr.handler_),
- pointer_(new (raw_ptr.pointer_) value_type(
- a1, a2, a3, a4, a5, a6, a7, a8))
- {
- raw_ptr.pointer_ = 0;
- }
-
- // Destructor automatically deallocates memory, unless it has been released.
- ~handler_ptr()
- {
- reset();
- }
-
- // Get the memory.
- pointer_type get() const
- {
- return pointer_;
- }
-
- // Release ownership of the memory.
- pointer_type release()
- {
- pointer_type tmp = pointer_;
- pointer_ = 0;
- return tmp;
- }
-
- // Explicitly destroy and deallocate the memory.
- void reset()
- {
- if (pointer_)
- {
- pointer_->value_type::~value_type();
- boost_asio_handler_alloc_helpers::deallocate(
- pointer_, value_size, handler_);
- pointer_ = 0;
- }
- }
-
-private:
- handler_type& handler_;
- pointer_type pointer_;
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
+#define BOOST_ASIO_DEFINE_HANDLER_PTR(op) \
+ struct ptr \
+ { \
+ Handler* h; \
+ void* v; \
+ op* p; \
+ ~ptr() \
+ { \
+ reset(); \
+ } \
+ void reset() \
+ { \
+ if (p) \
+ { \
+ p->~op(); \
+ p = 0; \
+ } \
+ if (v) \
+ { \
+ boost_asio_handler_alloc_helpers::deallocate(v, sizeof(op), *h); \
+ v = 0; \
+ } \
+ } \
+ } \
+ /**/
 
 #include <boost/asio/detail/pop_options.hpp>
 

Modified: trunk/boost/asio/detail/handler_invoke_helpers.hpp
==============================================================================
--- trunk/boost/asio/detail/handler_invoke_helpers.hpp (original)
+++ trunk/boost/asio/detail/handler_invoke_helpers.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// handler_invoke_helpers.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/handler_invoke_helpers.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <boost/detail/workaround.hpp>
 #include <boost/utility/addressof.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/handler_invoke_hook.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 // Calls to asio_handler_invoke must be made from a namespace that does not
 // contain overloads of this function. The boost_asio_handler_invoke_helpers
 // namespace is defined here for that purpose.

Modified: trunk/boost/asio/detail/hash_map.hpp
==============================================================================
--- trunk/boost/asio/detail/hash_map.hpp (original)
+++ trunk/boost/asio/detail/hash_map.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// hash_map.hpp
-// ~~~~~~~~~~~~
+// detail/hash_map.hpp
+// ~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,34 +15,39 @@
 # 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/asio/detail/config.hpp>
 #include <cassert>
 #include <list>
 #include <utility>
-#include <boost/functional/hash.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/socket_types.hpp>
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# include <boost/asio/detail/socket_types.hpp>
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <typename T>
-inline std::size_t calculate_hash_value(const T& t)
+inline std::size_t calculate_hash_value(int i)
+{
+ return static_cast<std::size_t>(i);
+}
+
+inline std::size_t calculate_hash_value(void* p)
 {
- return boost::hash_value(t);
+ return reinterpret_cast<std::size_t>(p)
+ + (reinterpret_cast<std::size_t>(p) >> 3);
 }
 
-#if defined(_WIN64)
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 inline std::size_t calculate_hash_value(SOCKET s)
 {
   return static_cast<std::size_t>(s);
 }
-#endif // defined(_WIN64)
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
 // Note: assumes K and V are POD types.
 template <typename K, typename V>

Added: trunk/boost/asio/detail/impl/descriptor_ops.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/descriptor_ops.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,357 @@
+//
+// detail/impl/descriptor_ops.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_DESCRIPTOR_OPS_IPP
+#define BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cerrno>
+#include <boost/asio/detail/descriptor_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace descriptor_ops {
+
+int open(const char* path, int flags, boost::system::error_code& ec)
+{
+ errno = 0;
+ int result = error_wrapper(::open(path, flags), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int close(int d, state_type& state, boost::system::error_code& ec)
+{
+ int result = 0;
+ if (d != -1)
+ {
+ if (state & internal_non_blocking)
+ {
+ ioctl_arg_type arg = 0;
+ ::ioctl(d, FIONBIO, &arg);
+ state &= ~internal_non_blocking;
+ }
+
+ errno = 0;
+ result = error_wrapper(::close(d), ec);
+ }
+
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+bool set_internal_non_blocking(int d,
+ state_type& state, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return false;
+ }
+
+ errno = 0;
+ ioctl_arg_type arg = 1;
+ int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
+
+ if (result >= 0)
+ {
+ ec = boost::system::error_code();
+ state |= internal_non_blocking;
+ return true;
+ }
+
+ return false;
+}
+
+std::size_t sync_read(int d, state_type state, buf* bufs,
+ std::size_t count, bool all_empty, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to read 0 bytes on a stream is a no-op.
+ if (all_empty)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ errno = 0;
+ int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec);
+
+ // Check if operation succeeded.
+ if (bytes > 0)
+ return bytes;
+
+ // Check for EOF.
+ if (bytes == 0)
+ {
+ ec = boost::asio::error::eof;
+ return 0;
+ }
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for descriptor to become ready.
+ if (descriptor_ops::poll_read(d, ec) < 0)
+ return 0;
+ }
+}
+
+bool non_blocking_read(int d, buf* bufs, std::size_t count,
+ boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Read some data.
+ errno = 0;
+ int bytes = error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec);
+
+ // Check for end of stream.
+ if (bytes == 0)
+ {
+ ec = boost::asio::error::eof;
+ return 0;
+ }
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+std::size_t sync_write(int d, state_type state, const buf* bufs,
+ std::size_t count, bool all_empty, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to write 0 bytes on a stream is a no-op.
+ if (all_empty)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // Write some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ errno = 0;
+ int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec);
+
+ // Check if operation succeeded.
+ if (bytes > 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for descriptor to become ready.
+ if (descriptor_ops::poll_write(d, ec) < 0)
+ return 0;
+ }
+}
+
+bool non_blocking_write(int d, const buf* bufs, std::size_t count,
+ boost::system::error_code& ec, std::size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Write some data.
+ errno = 0;
+ int bytes = error_wrapper(::writev(d, bufs, static_cast<int>(count)), ec);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+int ioctl(int d, state_type& state, long cmd,
+ ioctl_arg_type* arg, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return -1;
+ }
+
+ errno = 0;
+ int result = error_wrapper(::ioctl(d, cmd, arg), ec);
+
+ if (result >= 0)
+ {
+ ec = boost::system::error_code();
+
+ // When updating the non-blocking mode we always perform the ioctl syscall,
+ // even if the flags would otherwise indicate that the descriptor is
+ // already in the correct state. This ensures that the underlying
+ // descriptor is put into the state that has been requested by the user. If
+ // the ioctl syscall was successful then we need to update the flags to
+ // match.
+ if (cmd == static_cast<long>(FIONBIO))
+ {
+ if (*arg)
+ {
+ state |= user_set_non_blocking;
+ }
+ else
+ {
+ // Clearing the non-blocking mode always overrides any internally-set
+ // non-blocking flag. Any subsequent asynchronous operations will need
+ // to re-enable non-blocking I/O.
+ state &= ~(user_set_non_blocking | internal_non_blocking);
+ }
+ }
+ }
+
+ return result;
+}
+
+int fcntl(int d, long cmd, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return -1;
+ }
+
+ errno = 0;
+ int result = error_wrapper(::fcntl(d, cmd), ec);
+ if (result != -1)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int fcntl(int d, long cmd, long arg, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return -1;
+ }
+
+ errno = 0;
+ int result = error_wrapper(::fcntl(d, cmd, arg), ec);
+ if (result != -1)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int poll_read(int d, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return -1;
+ }
+
+ pollfd fds;
+ fds.fd = d;
+ fds.events = POLLIN;
+ fds.revents = 0;
+ errno = 0;
+ int result = error_wrapper(::poll(&fds, 1, -1), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int poll_write(int d, boost::system::error_code& ec)
+{
+ if (d == -1)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return -1;
+ }
+
+ pollfd fds;
+ fds.fd = d;
+ fds.events = POLLOUT;
+ fds.revents = 0;
+ errno = 0;
+ int result = error_wrapper(::poll(&fds, 1, -1), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+} // namespace descriptor_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP

Added: trunk/boost/asio/detail/impl/dev_poll_reactor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/dev_poll_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,74 @@
+//
+// detail/impl/dev_poll_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_IMPL_DEV_POLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void dev_poll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_add_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void dev_poll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void dev_poll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!shutdown_)
+ {
+ bool earliest = queue.enqueue_timer(time, op, token);
+ io_service_.work_started();
+ if (earliest)
+ interrupter_.interrupt();
+ }
+}
+
+template <typename Time_Traits>
+std::size_t dev_poll_reactor::cancel_timer(
+ timer_queue<Time_Traits>& queue, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ op_queue<operation> ops;
+ std::size_t n = queue.cancel_timer(token, ops);
+ lock.unlock();
+ io_service_.post_deferred_completions(ops);
+ return n;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_HPP

Added: trunk/boost/asio/detail/impl/dev_poll_reactor.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/dev_poll_reactor.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,337 @@
+//
+// detail/impl/dev_poll_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_DEV_POLL_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#include <boost/asio/detail/dev_poll_reactor.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+dev_poll_reactor::dev_poll_reactor(boost::asio::io_service& 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()),
+ interrupter_(),
+ shutdown_(false)
+{
+ // Add the interrupter's descriptor to /dev/poll.
+ ::pollfd ev = { 0 };
+ ev.fd = interrupter_.read_descriptor();
+ ev.events = POLLIN | POLLERR;
+ ev.revents = 0;
+ ::write(dev_poll_fd_, &ev, sizeof(ev));
+}
+
+dev_poll_reactor::~dev_poll_reactor()
+{
+ shutdown_service();
+ ::close(dev_poll_fd_);
+}
+
+void dev_poll_reactor::shutdown_service()
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+ lock.unlock();
+
+ 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);
+}
+
+void dev_poll_reactor::init_task()
+{
+ io_service_.init_task();
+}
+
+int dev_poll_reactor::register_descriptor(socket_type, per_descriptor_data&)
+{
+ return 0;
+}
+
+void dev_poll_reactor::start_op(int op_type, socket_type descriptor,
+ dev_poll_reactor::per_descriptor_data&,
+ reactor_op* op, bool allow_speculative)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ if (shutdown_)
+ return;
+
+ if (allow_speculative)
+ {
+ if (op_type != read_op || !op_queue_[except_op].has_operation(descriptor))
+ {
+ if (!op_queue_[op_type].has_operation(descriptor))
+ {
+ if (op->perform())
+ {
+ lock.unlock();
+ io_service_.post_immediate_completion(op);
+ return;
+ }
+ }
+ }
+ }
+
+ 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 = POLLERR | POLLHUP;
+ if (op_type == read_op
+ || op_queue_[read_op].has_operation(descriptor))
+ ev.events |= POLLIN;
+ if (op_type == write_op
+ || op_queue_[write_op].has_operation(descriptor))
+ ev.events |= POLLOUT;
+ if (op_type == except_op
+ || op_queue_[except_op].has_operation(descriptor))
+ ev.events |= POLLPRI;
+ interrupter_.interrupt();
+ }
+}
+
+void dev_poll_reactor::cancel_ops(socket_type descriptor,
+ dev_poll_reactor::per_descriptor_data&)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void dev_poll_reactor::close_descriptor(socket_type descriptor,
+ dev_poll_reactor::per_descriptor_data&)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ // Remove the descriptor from /dev/poll.
+ ::pollfd& ev = add_pending_event_change(descriptor);
+ ev.events = POLLREMOVE;
+ interrupter_.interrupt();
+
+ // Cancel any outstanding operations associated with the descriptor.
+ cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void dev_poll_reactor::run(bool block, op_queue<operation>& ops)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ // We can return immediately if there's no work to do and the reactor is
+ // not supposed to block.
+ 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();
+ if (events_size > 0)
+ {
+ errno = 0;
+ int result = ::write(dev_poll_fd_,
+ &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;
+ for (int j = 0; j < max_ops; ++j)
+ op_queue_[j].cancel_operations(descriptor, ops, ec);
+ }
+ }
+ pending_event_changes_.clear();
+ pending_event_change_index_.clear();
+ }
+
+ int timeout = block ? get_timeout() : 0;
+ lock.unlock();
+
+ // Block on the /dev/poll descriptor.
+ ::pollfd events[128] = { { 0 } };
+ ::dvpoll dp = { 0 };
+ dp.dp_fds = events;
+ dp.dp_nfds = 128;
+ dp.dp_timeout = timeout;
+ int num_events = ::ioctl(dev_poll_fd_, DP_POLL, &dp);
+
+ lock.lock();
+
+ // Dispatch the waiting events.
+ for (int i = 0; i < num_events; ++i)
+ {
+ int descriptor = events[i].fd;
+ if (descriptor == interrupter_.read_descriptor())
+ {
+ interrupter_.reset();
+ }
+ else
+ {
+ bool more_reads = false;
+ bool more_writes = false;
+ bool more_except = false;
+
+ // 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 =
+ op_queue_[except_op].perform_operations(descriptor, ops);
+ else
+ more_except = op_queue_[except_op].has_operation(descriptor);
+
+ if (events[i].events & (POLLIN | POLLERR | POLLHUP))
+ more_reads = op_queue_[read_op].perform_operations(descriptor, ops);
+ else
+ more_reads = op_queue_[read_op].has_operation(descriptor);
+
+ if (events[i].events & (POLLOUT | POLLERR | POLLHUP))
+ more_writes = op_queue_[write_op].perform_operations(descriptor, ops);
+ else
+ more_writes = op_queue_[write_op].has_operation(descriptor);
+
+ if ((events[i].events & (POLLERR | POLLHUP)) != 0
+ && !more_except && !more_reads && !more_writes)
+ {
+ // If we have an event and no operations associated with the
+ // descriptor then we need to delete the descriptor from /dev/poll.
+ // The poll operation can produce POLLHUP or POLLERR events when there
+ // is no operation pending, so if we do not remove the descriptor we
+ // can end up in a tight polling loop.
+ ::pollfd ev = { 0 };
+ ev.fd = descriptor;
+ ev.events = POLLREMOVE;
+ ev.revents = 0;
+ ::write(dev_poll_fd_, &ev, sizeof(ev));
+ }
+ else
+ {
+ ::pollfd ev = { 0 };
+ ev.fd = descriptor;
+ ev.events = POLLERR | POLLHUP;
+ if (more_reads)
+ ev.events |= POLLIN;
+ if (more_writes)
+ ev.events |= POLLOUT;
+ if (more_except)
+ ev.events |= POLLPRI;
+ ev.revents = 0;
+ int result = ::write(dev_poll_fd_, &ev, sizeof(ev));
+ if (result != sizeof(ev))
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ for (int j = 0; j < max_ops; ++j)
+ op_queue_[j].cancel_operations(descriptor, ops, ec);
+ }
+ }
+ }
+ }
+ timer_queues_.get_ready_timers(ops);
+}
+
+void dev_poll_reactor::interrupt()
+{
+ interrupter_.interrupt();
+}
+
+int dev_poll_reactor::do_dev_poll_create()
+{
+ int fd = ::open("/dev/poll", O_RDWR);
+ if (fd == -1)
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "/dev/poll");
+ }
+ return fd;
+}
+
+void dev_poll_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.insert(&queue);
+}
+
+void dev_poll_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.erase(&queue);
+}
+
+int dev_poll_reactor::get_timeout()
+{
+ // 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.
+ return timer_queues_.wait_duration_msec(5 * 60 * 1000);
+}
+
+void dev_poll_reactor::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();
+}
+
+::pollfd& dev_poll_reactor::add_pending_event_change(int descriptor)
+{
+ hash_map<int, std::size_t>::iterator iter
+ = pending_event_change_index_.find(descriptor);
+ if (iter == pending_event_change_index_.end())
+ {
+ std::size_t index = pending_event_changes_.size();
+ pending_event_changes_.reserve(pending_event_changes_.size() + 1);
+ pending_event_change_index_.insert(std::make_pair(descriptor, index));
+ pending_event_changes_.push_back(::pollfd());
+ pending_event_changes_[index].fd = descriptor;
+ pending_event_changes_[index].revents = 0;
+ return pending_event_changes_[index];
+ }
+ else
+ {
+ return pending_event_changes_[iter->second];
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_DEV_POLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_DEV_POLL_REACTOR_IPP

Added: trunk/boost/asio/detail/impl/epoll_reactor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/epoll_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,72 @@
+//
+// detail/impl/epoll_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_IMPL_EPOLL_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void epoll_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_add_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void epoll_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void epoll_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token)
+{
+ mutex::scoped_lock lock(mutex_);
+ if (!shutdown_)
+ {
+ bool earliest = queue.enqueue_timer(time, op, token);
+ io_service_.work_started();
+ if (earliest)
+ update_timeout();
+ }
+}
+
+template <typename Time_Traits>
+std::size_t epoll_reactor::cancel_timer(
+ timer_queue<Time_Traits>& queue, void* token)
+{
+ mutex::scoped_lock lock(mutex_);
+ op_queue<operation> ops;
+ std::size_t n = queue.cancel_timer(token, ops);
+ lock.unlock();
+ io_service_.post_deferred_completions(ops);
+ return n;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_HPP

Added: trunk/boost/asio/detail/impl/epoll_reactor.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/epoll_reactor.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,375 @@
+//
+// detail/impl/epoll_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_EPOLL_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EPOLL)
+
+#include <cstddef>
+#include <sys/epoll.h>
+#include <boost/asio/detail/epoll_reactor.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+# include <sys/timerfd.h>
+#endif // defined(BOOST_ASIO_HAS_TIMERFD)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+epoll_reactor::epoll_reactor(boost::asio::io_service& 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()),
+#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_(),
+ shutdown_(false)
+{
+ // Add the interrupter's descriptor to epoll.
+ epoll_event ev = { 0, { 0 } };
+ 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);
+ }
+}
+
+epoll_reactor::~epoll_reactor()
+{
+ close(epoll_fd_);
+ if (timer_fd_ != -1)
+ close(timer_fd_);
+}
+
+void epoll_reactor::shutdown_service()
+{
+ mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+ lock.unlock();
+
+ op_queue<operation> ops;
+
+ descriptor_map::iterator iter = registered_descriptors_.begin();
+ descriptor_map::iterator end = registered_descriptors_.end();
+ while (iter != end)
+ {
+ for (int i = 0; i < max_ops; ++i)
+ ops.push(iter->second.op_queue_[i]);
+ iter->second.shutdown_ = true;
+ ++iter;
+ }
+
+ timer_queues_.get_all_timers(ops);
+}
+
+void epoll_reactor::init_task()
+{
+ io_service_.init_task();
+}
+
+int epoll_reactor::register_descriptor(socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock lock(registered_descriptors_mutex_);
+
+ descriptor_map::iterator new_entry = registered_descriptors_.insert(
+ std::make_pair(descriptor, descriptor_state())).first;
+ descriptor_data = &new_entry->second;
+
+ descriptor_data->shutdown_ = false;
+
+ lock.unlock();
+
+ epoll_event ev = { 0, { 0 } };
+ 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;
+}
+
+void epoll_reactor::start_op(int op_type, socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data,
+ reactor_op* op, bool allow_speculative)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+ if (descriptor_data->shutdown_)
+ return;
+
+ if (descriptor_data->op_queue_[op_type].empty())
+ {
+ if (allow_speculative
+ && (op_type != read_op
+ || descriptor_data->op_queue_[except_op].empty()))
+ {
+ if (op->perform())
+ {
+ descriptor_lock.unlock();
+ io_service_.post_immediate_completion(op);
+ return;
+ }
+ }
+ else
+ {
+ 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);
+ }
+ }
+
+ descriptor_data->op_queue_[op_type].push(op);
+ io_service_.work_started();
+}
+
+void epoll_reactor::cancel_ops(socket_type,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ op_queue<operation> ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_lock.unlock();
+
+ io_service_.post_deferred_completions(ops);
+}
+
+void epoll_reactor::close_descriptor(socket_type descriptor,
+ epoll_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+ mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+
+ // Remove the descriptor from the set of known descriptors. The descriptor
+ // will be automatically removed from the epoll set when it is closed.
+ descriptor_data->shutdown_ = true;
+
+ op_queue<operation> ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_lock.unlock();
+
+ registered_descriptors_.erase(descriptor);
+
+ descriptors_lock.unlock();
+
+ io_service_.post_deferred_completions(ops);
+}
+
+void epoll_reactor::run(bool block, op_queue<operation>& ops)
+{
+ // Calculate a timeout only if timerfd is not used.
+ int timeout;
+ if (timer_fd_ != -1)
+ timeout = block ? -1 : 0;
+ else
+ {
+ mutex::scoped_lock lock(mutex_);
+ timeout = block ? get_timeout() : 0;
+ }
+
+ // Block on the epoll descriptor.
+ epoll_event events[128];
+ int num_events = epoll_wait(epoll_fd_, events, 128, timeout);
+
+#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)
+ {
+ void* ptr = events[i].data.ptr;
+ if (ptr == &interrupter_)
+ {
+ // 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
+ {
+ 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.
+ static const int flag[max_ops] = { EPOLLIN, EPOLLOUT, EPOLLPRI };
+ for (int j = max_ops - 1; j >= 0; --j)
+ {
+ if (events[i].events & (flag[j] | EPOLLERR | EPOLLHUP))
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[j].front())
+ {
+ if (op->perform())
+ {
+ descriptor_data->op_queue_[j].pop();
+ ops.push(op);
+ }
+ else
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (check_timers)
+ {
+ mutex::scoped_lock common_lock(mutex_);
+ timer_queues_.get_ready_timers(ops);
+
+#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)
+ }
+}
+
+void epoll_reactor::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);
+}
+
+int epoll_reactor::do_epoll_create()
+{
+ int fd = epoll_create(epoll_size);
+ if (fd == -1)
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "epoll");
+ }
+ return fd;
+}
+
+void epoll_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.insert(&queue);
+}
+
+void epoll_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.erase(&queue);
+}
+
+void epoll_reactor::update_timeout()
+{
+#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();
+}
+
+int epoll_reactor::get_timeout()
+{
+ // 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.
+ return timer_queues_.wait_duration_msec(5 * 60 * 1000);
+}
+
+#if defined(BOOST_ASIO_HAS_TIMERFD)
+int epoll_reactor::get_timeout(itimerspec& ts)
+{
+ 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)
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EPOLL)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EPOLL_REACTOR_IPP

Added: trunk/boost/asio/detail/impl/eventfd_select_interrupter.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/eventfd_select_interrupter.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,127 @@
+//
+// detail/impl/eventfd_select_interrupter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail 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_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_EVENTFD)
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <asm/unistd.h>
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+# include <sys/eventfd.h>
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+#include <boost/asio/detail/eventfd_select_interrupter.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+eventfd_select_interrupter::eventfd_select_interrupter()
+{
+#if __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+ write_descriptor_ = read_descriptor_ = syscall(__NR_eventfd, 0);
+#else // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+ write_descriptor_ = read_descriptor_ = ::eventfd(0, 0);
+#endif // __GLIBC__ == 2 && __GLIBC_MINOR__ < 8
+ if (read_descriptor_ != -1)
+ {
+ ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+ }
+ else
+ {
+ int pipe_fds[2];
+ if (pipe(pipe_fds) == 0)
+ {
+ read_descriptor_ = pipe_fds[0];
+ ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+ write_descriptor_ = pipe_fds[1];
+ ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+ }
+ else
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "eventfd_select_interrupter");
+ }
+ }
+}
+
+eventfd_select_interrupter::~eventfd_select_interrupter()
+{
+ if (write_descriptor_ != -1 && write_descriptor_ != read_descriptor_)
+ ::close(write_descriptor_);
+ if (read_descriptor_ != -1)
+ ::close(read_descriptor_);
+}
+
+void eventfd_select_interrupter::interrupt()
+{
+ uint64_t counter(1UL);
+ int result = ::write(write_descriptor_, &counter, sizeof(uint64_t));
+ (void)result;
+}
+
+bool eventfd_select_interrupter::reset()
+{
+ if (write_descriptor_ == read_descriptor_)
+ {
+ for (;;)
+ {
+ // Only perform one read. The kernel maintains an atomic counter.
+ uint64_t counter(0);
+ errno = 0;
+ int bytes_read = ::read(read_descriptor_, &counter, sizeof(uint64_t));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ bool was_interrupted = (bytes_read > 0);
+ return was_interrupted;
+ }
+ }
+ else
+ {
+ for (;;)
+ {
+ // Clear all data from the pipe.
+ char data[1024];
+ int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ bool was_interrupted = (bytes_read > 0);
+ while (bytes_read == sizeof(data))
+ bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ return was_interrupted;
+ }
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_EVENTFD)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_EVENTFD_SELECT_INTERRUPTER_IPP

Added: trunk/boost/asio/detail/impl/kqueue_reactor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/kqueue_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,76 @@
+//
+// detail/impl/kqueue_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005 Stefan Arentz (stefan at soze 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_IMPL_KQUEUE_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_KQUEUE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void kqueue_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_add_timer_queue(queue);
+}
+
+// Remove a timer queue from the reactor.
+template <typename Time_Traits>
+void kqueue_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void kqueue_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!shutdown_)
+ {
+ bool earliest = queue.enqueue_timer(time, op, token);
+ io_service_.work_started();
+ if (earliest)
+ interrupter_.interrupt();
+ }
+}
+
+template <typename Time_Traits>
+std::size_t kqueue_reactor::cancel_timer(
+ timer_queue<Time_Traits>& queue, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ op_queue<operation> ops;
+ std::size_t n = queue.cancel_timer(token, ops);
+ lock.unlock();
+ io_service_.post_deferred_completions(ops);
+ return n;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_HPP

Added: trunk/boost/asio/detail/impl/kqueue_reactor.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/kqueue_reactor.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,355 @@
+//
+// detail/impl/kqueue_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005 Stefan Arentz (stefan at soze 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_IMPL_KQUEUE_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_KQUEUE)
+
+#include <boost/asio/detail/kqueue_reactor.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+kqueue_reactor::kqueue_reactor(boost::asio::io_service& 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()),
+ interrupter_(),
+ shutdown_(false)
+{
+ // The interrupter is put into a permanently readable state. Whenever we
+ // want to interrupt the blocked kevent call we register a one-shot read
+ // operation against the descriptor.
+ interrupter_.interrupt();
+}
+
+kqueue_reactor::~kqueue_reactor()
+{
+ close(kqueue_fd_);
+}
+
+void kqueue_reactor::shutdown_service()
+{
+ mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+ lock.unlock();
+
+ op_queue<operation> ops;
+
+ descriptor_map::iterator iter = registered_descriptors_.begin();
+ descriptor_map::iterator end = registered_descriptors_.end();
+ while (iter != end)
+ {
+ for (int i = 0; i < max_ops; ++i)
+ ops.push(iter->second.op_queue_[i]);
+ iter->second.shutdown_ = true;
+ ++iter;
+ }
+
+ timer_queues_.get_all_timers(ops);
+}
+
+void kqueue_reactor::init_task()
+{
+ io_service_.init_task();
+}
+
+int kqueue_reactor::register_descriptor(socket_type descriptor,
+ kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock lock(registered_descriptors_mutex_);
+
+ descriptor_map::iterator new_entry = registered_descriptors_.insert(
+ std::make_pair(descriptor, descriptor_state())).first;
+ descriptor_data = &new_entry->second;
+
+ descriptor_data->shutdown_ = false;
+
+ return 0;
+}
+
+void kqueue_reactor::start_op(int op_type, socket_type descriptor,
+ kqueue_reactor::per_descriptor_data& descriptor_data,
+ reactor_op* op, bool allow_speculative)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+ if (descriptor_data->shutdown_)
+ return;
+
+ bool first = descriptor_data->op_queue_[op_type].empty();
+ if (first)
+ {
+ if (allow_speculative)
+ {
+ if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
+ {
+ if (op->perform())
+ {
+ descriptor_lock.unlock();
+ io_service_.post_immediate_completion(op);
+ return;
+ }
+ }
+ }
+ }
+
+ descriptor_data->op_queue_[op_type].push(op);
+ io_service_.work_started();
+
+ if (first)
+ {
+ struct kevent event;
+ switch (op_type)
+ {
+ case read_op:
+ EV_SET(&event, descriptor, EVFILT_READ,
+ EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
+ break;
+ case write_op:
+ EV_SET(&event, descriptor, EVFILT_WRITE,
+ EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
+ break;
+ case except_op:
+ if (!descriptor_data->op_queue_[read_op].empty())
+ return; // Already registered for read events.
+ EV_SET(&event, descriptor, EVFILT_READ,
+ EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data);
+ break;
+ }
+
+ if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
+ {
+ op->ec_ = boost::system::error_code(errno,
+ boost::asio::error::get_system_category());
+ descriptor_data->op_queue_[op_type].pop();
+ io_service_.post_deferred_completion(op);
+ }
+ }
+}
+
+void kqueue_reactor::cancel_ops(socket_type,
+ kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+
+ op_queue<operation> ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_lock.unlock();
+
+ io_service_.post_deferred_completions(ops);
+}
+
+void kqueue_reactor::close_descriptor(socket_type descriptor,
+ kqueue_reactor::per_descriptor_data& descriptor_data)
+{
+ mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
+ mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
+
+ // Remove the descriptor from the set of known descriptors. The descriptor
+ // will be automatically removed from the kqueue set when it is closed.
+ descriptor_data->shutdown_ = true;
+
+ op_queue<operation> ops;
+ for (int i = 0; i < max_ops; ++i)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[i].front())
+ {
+ op->ec_ = boost::asio::error::operation_aborted;
+ descriptor_data->op_queue_[i].pop();
+ ops.push(op);
+ }
+ }
+
+ descriptor_lock.unlock();
+
+ registered_descriptors_.erase(descriptor);
+
+ descriptors_lock.unlock();
+
+ io_service_.post_deferred_completions(ops);
+}
+
+void kqueue_reactor::run(bool block, op_queue<operation>& ops)
+{
+ mutex::scoped_lock lock(mutex_);
+
+ // Determine how long to block while waiting for events.
+ timespec timeout_buf = { 0, 0 };
+ timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf;
+
+ lock.unlock();
+
+ // Block on the kqueue descriptor.
+ struct kevent events[128];
+ int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout);
+
+ // Dispatch the waiting events.
+ for (int i = 0; i < num_events; ++i)
+ {
+ int descriptor = events[i].ident;
+ void* ptr = events[i].udata;
+ if (ptr == &interrupter_)
+ {
+ // No need to reset the interrupter since we're leaving the descriptor
+ // in a ready-to-read state and relying on one-shot notifications.
+ }
+ else
+ {
+ 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.
+ static const int filter[max_ops] =
+ { EVFILT_READ, EVFILT_WRITE, EVFILT_READ };
+ for (int j = max_ops - 1; j >= 0; --j)
+ {
+ if (events[i].filter == filter[j])
+ {
+ if (j != except_op || events[i].flags & EV_OOBAND)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[j].front())
+ {
+ if (events[i].flags & EV_ERROR)
+ {
+ op->ec_ = boost::system::error_code(events[i].data,
+ boost::asio::error::get_system_category());
+ descriptor_data->op_queue_[j].pop();
+ ops.push(op);
+ }
+ if (op->perform())
+ {
+ descriptor_data->op_queue_[j].pop();
+ ops.push(op);
+ }
+ else
+ break;
+ }
+ }
+ }
+ }
+
+ // Renew registration for event notifications.
+ struct kevent event;
+ switch (events[i].filter)
+ {
+ case EVFILT_READ:
+ if (!descriptor_data->op_queue_[read_op].empty())
+ EV_SET(&event, descriptor, EVFILT_READ,
+ EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
+ else if (!descriptor_data->op_queue_[except_op].empty())
+ EV_SET(&event, descriptor, EVFILT_READ,
+ EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data);
+ else
+ continue;
+ case EVFILT_WRITE:
+ if (!descriptor_data->op_queue_[write_op].empty())
+ EV_SET(&event, descriptor, EVFILT_WRITE,
+ EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
+ else
+ continue;
+ default:
+ break;
+ }
+ if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
+ {
+ boost::system::error_code error(errno,
+ boost::asio::error::get_system_category());
+ for (int j = 0; j < max_ops; ++j)
+ {
+ while (reactor_op* op = descriptor_data->op_queue_[j].front())
+ {
+ op->ec_ = error;
+ descriptor_data->op_queue_[j].pop();
+ ops.push(op);
+ }
+ }
+ }
+ }
+ }
+
+ lock.lock();
+ timer_queues_.get_ready_timers(ops);
+}
+
+void kqueue_reactor::interrupt()
+{
+ struct kevent event;
+ EV_SET(&event, interrupter_.read_descriptor(),
+ EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &interrupter_);
+ ::kevent(kqueue_fd_, &event, 1, 0, 0, 0);
+}
+
+int kqueue_reactor::do_kqueue_create()
+{
+ int fd = ::kqueue();
+ if (fd == -1)
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "kqueue");
+ }
+ return fd;
+}
+
+void kqueue_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.insert(&queue);
+}
+
+void kqueue_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.erase(&queue);
+}
+
+timespec* kqueue_reactor::get_timeout(timespec& ts)
+{
+ // 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.
+ long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+ ts.tv_sec = usec / 1000000;
+ ts.tv_nsec = (usec % 1000000) * 1000;
+ return &ts;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_KQUEUE_REACTOR_IPP

Added: trunk/boost/asio/detail/impl/pipe_select_interrupter.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/pipe_select_interrupter.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,94 @@
+//
+// detail/impl/pipe_select_interrupter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_PIPE_SELECT_INTERRUPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#if !defined(BOOST_ASIO_HAS_EVENTFD)
+
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <boost/asio/detail/pipe_select_interrupter.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+pipe_select_interrupter::pipe_select_interrupter()
+{
+ int pipe_fds[2];
+ if (pipe(pipe_fds) == 0)
+ {
+ read_descriptor_ = pipe_fds[0];
+ ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
+ write_descriptor_ = pipe_fds[1];
+ ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
+ }
+ else
+ {
+ boost::system::error_code ec(errno,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "pipe_select_interrupter");
+ }
+}
+
+pipe_select_interrupter::~pipe_select_interrupter()
+{
+ if (read_descriptor_ != -1)
+ ::close(read_descriptor_);
+ if (write_descriptor_ != -1)
+ ::close(write_descriptor_);
+}
+
+void pipe_select_interrupter::interrupt()
+{
+ char byte = 0;
+ int result = ::write(write_descriptor_, &byte, 1);
+ (void)result;
+}
+
+bool pipe_select_interrupter::reset()
+{
+ for (;;)
+ {
+ char data[1024];
+ int bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ if (bytes_read < 0 && errno == EINTR)
+ continue;
+ bool was_interrupted = (bytes_read > 0);
+ while (bytes_read == sizeof(data))
+ bytes_read = ::read(read_descriptor_, data, sizeof(data));
+ return was_interrupted;
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_EVENTFD)
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_PIPE_SELECT_INTERRUPTER_IPP

Added: trunk/boost/asio/detail/impl/posix_event.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/posix_event.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,48 @@
+//
+// detail/impl/posix_event.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_POSIX_EVENT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#include <boost/asio/detail/posix_event.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_event::posix_event()
+ : signalled_(false)
+{
+ int error = ::pthread_cond_init(&cond_, 0);
+ boost::system::error_code ec(error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "event");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_EVENT_IPP

Added: trunk/boost/asio/detail/impl/posix_mutex.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/posix_mutex.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,48 @@
+//
+// detail/impl/posix_mutex.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_POSIX_MUTEX_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#include <boost/asio/detail/posix_mutex.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_mutex::posix_mutex()
+{
+ int error = ::pthread_mutex_init(&mutex_, 0);
+ boost::system::error_code ec(error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "mutex");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_MUTEX_IPP

Added: trunk/boost/asio/detail/impl/posix_thread.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/posix_thread.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,76 @@
+//
+// detail/impl/posix_thread.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_POSIX_THREAD_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#include <boost/asio/detail/posix_thread.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+posix_thread::~posix_thread()
+{
+ if (!joined_)
+ ::pthread_detach(thread_);
+}
+
+void posix_thread::join()
+{
+ if (!joined_)
+ {
+ ::pthread_join(thread_, 0);
+ joined_ = true;
+ }
+}
+
+void posix_thread::start_thread(func_base* arg)
+{
+ int error = ::pthread_create(&thread_, 0,
+ boost_asio_detail_posix_thread_function, arg);
+ if (error != 0)
+ {
+ delete arg;
+ boost::system::error_code ec(error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread");
+ }
+}
+
+void* boost_asio_detail_posix_thread_function(void* arg)
+{
+ posix_thread::auto_func_base_ptr func = {
+ static_cast<posix_thread::func_base*>(arg) };
+ func.ptr->run();
+ return 0;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_THREAD_IPP

Added: trunk/boost/asio/detail/impl/posix_tss_ptr.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/posix_tss_ptr.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,48 @@
+//
+// detail/impl/posix_tss_ptr.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_POSIX_TSS_PTR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#include <boost/asio/detail/posix_tss_ptr.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+void posix_tss_ptr_create(pthread_key_t& key)
+{
+ int error = ::pthread_key_create(&key, 0);
+ boost::system::error_code ec(error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "tss");
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_POSIX_TSS_PTR_IPP

Added: trunk/boost/asio/detail/impl/reactive_descriptor_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/reactive_descriptor_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,138 @@
+//
+// detail/impl/reactive_descriptor_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <boost/asio/error.hpp>
+#include <boost/asio/detail/reactive_descriptor_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_descriptor_service::reactive_descriptor_service(
+ boost::asio::io_service& io_service)
+ : reactor_(boost::asio::use_service<reactor>(io_service))
+{
+ reactor_.init_task();
+}
+
+void reactive_descriptor_service::shutdown_service()
+{
+}
+
+void reactive_descriptor_service::construct(
+ reactive_descriptor_service::implementation_type& impl)
+{
+ impl.descriptor_ = -1;
+ impl.state_ = 0;
+}
+
+void reactive_descriptor_service::destroy(
+ reactive_descriptor_service::implementation_type& impl)
+{
+ if (is_open(impl))
+ reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
+
+ boost::system::error_code ignored_ec;
+ descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
+}
+
+boost::system::error_code reactive_descriptor_service::assign(
+ reactive_descriptor_service::implementation_type& impl,
+ const native_type& native_descriptor, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ if (int err = reactor_.register_descriptor(
+ native_descriptor, impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.descriptor_ = native_descriptor;
+ impl.state_ = 0;
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_descriptor_service::close(
+ reactive_descriptor_service::implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
+
+ if (descriptor_ops::close(impl.descriptor_, impl.state_, ec) == 0)
+ construct(impl);
+
+ return ec;
+}
+
+boost::system::error_code reactive_descriptor_service::cancel(
+ reactive_descriptor_service::implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return ec;
+ }
+
+ reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_);
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void reactive_descriptor_service::start_op(
+ reactive_descriptor_service::implementation_type& impl,
+ int op_type, reactor_op* op, bool non_blocking, bool noop)
+{
+ if (!noop)
+ {
+ if ((impl.state_ & descriptor_ops::non_blocking) ||
+ descriptor_ops::set_internal_non_blocking(
+ impl.descriptor_, impl.state_, op->ec_))
+ {
+ reactor_.start_op(op_type, impl.descriptor_,
+ impl.reactor_data_, op, non_blocking);
+ return;
+ }
+ }
+
+ reactor_.post_immediate_completion(op);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_DESCRIPTOR_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/reactive_serial_port_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/reactive_serial_port_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,153 @@
+//
+// detail/impl/reactive_serial_port_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT)
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+#include <cstring>
+#include <boost/asio/detail/reactive_serial_port_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_serial_port_service::reactive_serial_port_service(
+ boost::asio::io_service& io_service)
+ : descriptor_service_(io_service)
+{
+}
+
+void reactive_serial_port_service::shutdown_service()
+{
+ descriptor_service_.shutdown_service();
+}
+
+boost::system::error_code reactive_serial_port_service::open(
+ reactive_serial_port_service::implementation_type& impl,
+ const std::string& device, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ descriptor_ops::state_type state = 0;
+ int fd = descriptor_ops::open(device.c_str(),
+ O_RDWR | O_NONBLOCK | O_NOCTTY, ec);
+ if (fd < 0)
+ return ec;
+
+ int s = descriptor_ops::fcntl(fd, F_GETFL, ec);
+ if (s >= 0)
+ s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec);
+ if (s < 0)
+ {
+ boost::system::error_code ignored_ec;
+ descriptor_ops::close(fd, state, ignored_ec);
+ return ec;
+ }
+
+ // Set up default serial port options.
+ termios ios;
+ errno = 0;
+ s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec);
+ if (s >= 0)
+ {
+#if defined(_BSD_SOURCE)
+ ::cfmakeraw(&ios);
+#else
+ ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK
+ | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
+ ios.c_oflag &= ~OPOST;
+ ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ ios.c_cflag &= ~(CSIZE | PARENB);
+ ios.c_cflag |= CS8;
+#endif
+ ios.c_iflag |= IGNPAR;
+ ios.c_cflag |= CREAD | CLOCAL;
+ errno = 0;
+ s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec);
+ }
+ if (s < 0)
+ {
+ boost::system::error_code ignored_ec;
+ descriptor_ops::close(fd, state, ignored_ec);
+ return ec;
+ }
+
+ // We're done. Take ownership of the serial port descriptor.
+ if (descriptor_service_.assign(impl, fd, ec))
+ {
+ boost::system::error_code ignored_ec;
+ descriptor_ops::close(fd, state, ignored_ec);
+ }
+
+ return ec;
+}
+
+boost::system::error_code reactive_serial_port_service::do_set_option(
+ reactive_serial_port_service::implementation_type& impl,
+ reactive_serial_port_service::store_function_type store,
+ const void* option, boost::system::error_code& ec)
+{
+ termios ios;
+ errno = 0;
+ descriptor_ops::error_wrapper(::tcgetattr(
+ descriptor_service_.native(impl), &ios), ec);
+ if (ec)
+ return ec;
+
+ if (store(option, ios, ec))
+ return ec;
+
+ errno = 0;
+ descriptor_ops::error_wrapper(::tcsetattr(
+ descriptor_service_.native(impl), TCSANOW, &ios), ec);
+ return ec;
+}
+
+boost::system::error_code reactive_serial_port_service::do_get_option(
+ const reactive_serial_port_service::implementation_type& impl,
+ reactive_serial_port_service::load_function_type load,
+ void* option, boost::system::error_code& ec) const
+{
+ termios ios;
+ errno = 0;
+ descriptor_ops::error_wrapper(::tcgetattr(
+ descriptor_service_.native(impl), &ios), ec);
+ if (ec)
+ return ec;
+
+ return load(option, ios, ec);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SERIAL_PORT_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/reactive_socket_service_base.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/reactive_socket_service_base.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,214 @@
+//
+// detail/reactive_socket_service_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/reactive_socket_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+reactive_socket_service_base::reactive_socket_service_base(
+ boost::asio::io_service& io_service)
+ : reactor_(use_service<reactor>(io_service))
+{
+ reactor_.init_task();
+}
+
+void reactive_socket_service_base::shutdown_service()
+{
+}
+
+void reactive_socket_service_base::construct(
+ reactive_socket_service_base::base_implementation_type& impl)
+{
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+}
+
+void reactive_socket_service_base::destroy(
+ reactive_socket_service_base::base_implementation_type& impl)
+{
+ if (impl.socket_ != invalid_socket)
+ {
+ reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
+
+ boost::system::error_code ignored_ec;
+ socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+ }
+}
+
+boost::system::error_code reactive_socket_service_base::close(
+ reactive_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
+
+ if (socket_ops::close(impl.socket_, impl.state_, true, ec) == 0)
+ construct(impl);
+
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base::cancel(
+ reactive_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return ec;
+ }
+
+ reactor_.cancel_ops(impl.socket_, impl.reactor_data_);
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base::do_open(
+ reactive_socket_service_base::base_implementation_type& impl,
+ int af, int type, int protocol, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ socket_holder sock(socket_ops::socket(af, type, protocol, ec));
+ if (sock.get() == invalid_socket)
+ return ec;
+
+ if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = sock.release();
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code reactive_socket_service_base::do_assign(
+ reactive_socket_service_base::base_implementation_type& impl, int type,
+ const reactive_socket_service_base::native_type& native_socket,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ if (int err = reactor_.register_descriptor(
+ native_socket, impl.reactor_data_))
+ {
+ ec = boost::system::error_code(err,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.socket_ = native_socket;
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void reactive_socket_service_base::start_op(
+ reactive_socket_service_base::base_implementation_type& impl,
+ int op_type, reactor_op* op, bool non_blocking, bool noop)
+{
+ if (!noop)
+ {
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, op->ec_))
+ {
+ reactor_.start_op(op_type, impl.socket_,
+ impl.reactor_data_, op, non_blocking);
+ return;
+ }
+ }
+
+ reactor_.post_immediate_completion(op);
+}
+
+void reactive_socket_service_base::start_accept_op(
+ reactive_socket_service_base::base_implementation_type& impl,
+ reactor_op* op, bool peer_is_open)
+{
+ if (!peer_is_open)
+ start_op(impl, reactor::read_op, op, true, false);
+ else
+ {
+ op->ec_ = boost::asio::error::already_open;
+ reactor_.post_immediate_completion(op);
+ }
+}
+
+void reactive_socket_service_base::start_connect_op(
+ reactive_socket_service_base::base_implementation_type& impl,
+ reactor_op* op, const socket_addr_type* addr, size_t addrlen)
+{
+ if ((impl.state_ & socket_ops::non_blocking)
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, op->ec_))
+ {
+ if (socket_ops::connect(impl.socket_, addr, addrlen, 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, false);
+ return;
+ }
+ }
+ }
+
+ reactor_.post_immediate_completion(op);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_IPP

Added: trunk/boost/asio/detail/impl/resolver_service_base.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/resolver_service_base.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,108 @@
+//
+// detail/impl/resolver_service_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_RESOLVER_SERVICE_BASE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/resolver_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class resolver_service_base::work_io_service_runner
+{
+public:
+ work_io_service_runner(boost::asio::io_service& io_service)
+ : io_service_(io_service) {}
+ void operator()() { io_service_.run(); }
+private:
+ boost::asio::io_service& io_service_;
+};
+
+resolver_service_base::resolver_service_base(
+ boost::asio::io_service& io_service)
+ : 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)
+{
+}
+
+resolver_service_base::~resolver_service_base()
+{
+ shutdown_service();
+}
+
+void resolver_service_base::shutdown_service()
+{
+ work_.reset();
+ if (work_io_service_)
+ {
+ work_io_service_->stop();
+ if (work_thread_)
+ {
+ work_thread_->join();
+ work_thread_.reset();
+ }
+ work_io_service_.reset();
+ }
+}
+
+void resolver_service_base::construct(
+ resolver_service_base::implementation_type& impl)
+{
+ impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
+}
+
+void resolver_service_base::destroy(
+ resolver_service_base::implementation_type&)
+{
+}
+
+void resolver_service_base::cancel(
+ resolver_service_base::implementation_type& impl)
+{
+ impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
+}
+
+void resolver_service_base::start_resolve_op(operation* op)
+{
+ start_work_thread();
+ io_service_impl_.work_started();
+ work_io_service_impl_.post_immediate_completion(op);
+}
+
+void resolver_service_base::start_work_thread()
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!work_thread_)
+ {
+ work_thread_.reset(new boost::asio::detail::thread(
+ work_io_service_runner(*work_io_service_)));
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_RESOLVER_SERVICE_BASE_IPP

Added: trunk/boost/asio/detail/impl/select_reactor.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/select_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,81 @@
+//
+// detail/impl/select_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_IMPL_SELECT_REACTOR_HPP
+#define BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP) \
+ || (!defined(BOOST_ASIO_HAS_DEV_POLL) \
+ && !defined(BOOST_ASIO_HAS_EPOLL) \
+ && !defined(BOOST_ASIO_HAS_KQUEUE))
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Time_Traits>
+void select_reactor::add_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_add_timer_queue(queue);
+}
+
+// Remove a timer queue from the reactor.
+template <typename Time_Traits>
+void select_reactor::remove_timer_queue(timer_queue<Time_Traits>& queue)
+{
+ do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void select_reactor::schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!shutdown_)
+ {
+ bool earliest = queue.enqueue_timer(time, op, token);
+ io_service_.work_started();
+ if (earliest)
+ interrupter_.interrupt();
+ }
+}
+
+template <typename Time_Traits>
+std::size_t select_reactor::cancel_timer(
+ timer_queue<Time_Traits>& queue, void* token)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ op_queue<operation> ops;
+ std::size_t n = queue.cancel_timer(token, ops);
+ lock.unlock();
+ io_service_.post_deferred_completions(ops);
+ return n;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ // || (!defined(BOOST_ASIO_HAS_DEV_POLL)
+ // && !defined(BOOST_ASIO_HAS_EPOLL)
+ // && !defined(BOOST_ASIO_HAS_KQUEUE))
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_HPP

Added: trunk/boost/asio/detail/impl/select_reactor.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/select_reactor.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,271 @@
+//
+// detail/impl/select_reactor.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_SELECT_REACTOR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP) \
+ || (!defined(BOOST_ASIO_HAS_DEV_POLL) \
+ && !defined(BOOST_ASIO_HAS_EPOLL) \
+ && !defined(BOOST_ASIO_HAS_KQUEUE))
+
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/fd_set_adapter.hpp>
+#include <boost/asio/detail/select_reactor.hpp>
+#include <boost/asio/detail/signal_blocker.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+select_reactor::select_reactor(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<select_reactor>(io_service),
+ io_service_(use_service<io_service_impl>(io_service)),
+ mutex_(),
+ interrupter_(),
+#if defined(BOOST_ASIO_HAS_IOCP)
+ stop_thread_(false),
+ thread_(0),
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ shutdown_(false)
+{
+#if defined(BOOST_ASIO_HAS_IOCP)
+ boost::asio::detail::signal_blocker sb;
+ thread_ = new boost::asio::detail::thread(
+ bind_handler(&select_reactor::call_run_thread, this));
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+}
+
+select_reactor::~select_reactor()
+{
+ shutdown_service();
+}
+
+void select_reactor::shutdown_service()
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+#if defined(BOOST_ASIO_HAS_IOCP)
+ stop_thread_ = true;
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ lock.unlock();
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+ if (thread_)
+ {
+ interrupter_.interrupt();
+ thread_->join();
+ delete thread_;
+ thread_ = 0;
+ }
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+ 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);
+}
+
+void select_reactor::init_task()
+{
+ io_service_.init_task();
+}
+
+int select_reactor::register_descriptor(socket_type,
+ select_reactor::per_descriptor_data&)
+{
+ return 0;
+}
+
+void select_reactor::start_op(int op_type, socket_type descriptor,
+ select_reactor::per_descriptor_data&, reactor_op* op, bool)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (!shutdown_)
+ {
+ bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
+ io_service_.work_started();
+ if (first)
+ interrupter_.interrupt();
+ }
+}
+
+void select_reactor::cancel_ops(socket_type descriptor,
+ select_reactor::per_descriptor_data&)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void select_reactor::close_descriptor(socket_type descriptor,
+ select_reactor::per_descriptor_data&)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
+}
+
+void select_reactor::run(bool block, op_queue<operation>& ops)
+{
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+ // Check if the thread is supposed to stop.
+ if (stop_thread_)
+ return;
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+ // 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 && !have_work_to_do)
+ return;
+
+ // Determine how long to block while waiting for events.
+ timeval tv_buf = { 0, 0 };
+ timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
+
+ 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),
+ fds[read_op], fds[write_op], fds[except_op], tv, ec);
+
+ // Reset the interrupter.
+ 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.
+ 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);
+}
+
+void select_reactor::interrupt()
+{
+ interrupter_.interrupt();
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+void select_reactor::run_thread()
+{
+ 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();
+ }
+}
+
+void select_reactor::call_run_thread(select_reactor* reactor)
+{
+ reactor->run_thread();
+}
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+void select_reactor::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.insert(&queue);
+}
+
+void select_reactor::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(mutex_);
+ timer_queues_.erase(&queue);
+}
+
+timeval* select_reactor::get_timeout(timeval& tv)
+{
+ // 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.
+ long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
+ tv.tv_sec = usec / 1000000;
+ tv.tv_usec = usec % 1000000;
+ return &tv;
+}
+
+void select_reactor::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();
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ // || (!defined(BOOST_ASIO_HAS_DEV_POLL)
+ // && !defined(BOOST_ASIO_HAS_EPOLL)
+ // && !defined(BOOST_ASIO_HAS_KQUEUE))
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SELECT_REACTOR_IPP

Added: trunk/boost/asio/detail/impl/service_registry.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/service_registry.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,72 @@
+//
+// detail/impl/service_registry.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_IMPL_SERVICE_REGISTRY_HPP
+#define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_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 Service>
+Service& service_registry::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));
+}
+
+template <typename Service>
+void service_registry::add_service(Service* new_service)
+{
+ boost::asio::io_service::service::key key;
+ init_key(key, Service::id);
+ return do_add_service(key, new_service);
+}
+
+template <typename Service>
+bool service_registry::has_service() const
+{
+ boost::asio::io_service::service::key key;
+ init_key(key, Service::id);
+ return do_has_service(key);
+}
+
+#if !defined(BOOST_ASIO_NO_TYPEID)
+template <typename Service>
+void service_registry::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)
+
+template <typename Service>
+boost::asio::io_service::service* service_registry::create(
+ boost::asio::io_service& owner)
+{
+ return new Service(owner);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_HPP

Added: trunk/boost/asio/detail/impl/service_registry.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/service_registry.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,166 @@
+//
+// detail/impl/service_registry.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_SERVICE_REGISTRY_IPP
+#define BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/detail/service_registry.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+service_registry::service_registry(boost::asio::io_service& o)
+ : owner_(o),
+ first_service_(0)
+{
+}
+
+service_registry::~service_registry()
+{
+ // Shutdown all services. This must be done in a separate loop before the
+ // services are destroyed since the destructors of user-defined handler
+ // objects may try to access other service objects.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ service->shutdown_service();
+ service = service->next_;
+ }
+
+ // Destroy all services.
+ while (first_service_)
+ {
+ boost::asio::io_service::service* next_service = first_service_->next_;
+ destroy(first_service_);
+ first_service_ = next_service;
+ }
+}
+
+void service_registry::init_key(boost::asio::io_service::service::key& key,
+ const boost::asio::io_service::id& id)
+{
+ key.type_info_ = 0;
+ key.id_ = &id;
+}
+
+bool service_registry::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;
+}
+
+void service_registry::destroy(boost::asio::io_service::service* service)
+{
+ delete service;
+}
+
+boost::asio::io_service::service* service_registry::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 with the given key.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ return service;
+ service = service->next_;
+ }
+
+ // Create a new service object. The service registry's mutex is not locked
+ // at this time to allow for nested calls into this function from the new
+ // service's constructor.
+ lock.unlock();
+ 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
+ // while the lock was released.
+ service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ return service;
+ service = service->next_;
+ }
+
+ // Service was successfully initialised, pass ownership to registry.
+ new_service.ptr_->next_ = first_service_;
+ first_service_ = new_service.ptr_;
+ new_service.ptr_ = 0;
+ return first_service_;
+}
+
+void service_registry::do_add_service(
+ const boost::asio::io_service::service::key& key,
+ boost::asio::io_service::service* new_service)
+{
+ if (&owner_ != &new_service->io_service())
+ boost::throw_exception(invalid_service_owner());
+
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ // Check if there is an existing service object with the given key.
+ boost::asio::io_service::service* service = first_service_;
+ while (service)
+ {
+ if (keys_match(service->key_, key))
+ boost::throw_exception(service_already_exists());
+ service = service->next_;
+ }
+
+ // Take ownership of the service object.
+ new_service->key_ = key;
+ new_service->next_ = first_service_;
+ first_service_ = new_service;
+}
+
+bool service_registry::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 (keys_match(service->key_, key))
+ return true;
+ service = service->next_;
+ }
+
+ return false;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SERVICE_REGISTRY_IPP

Added: trunk/boost/asio/detail/impl/socket_ops.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/socket_ops.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,2828 @@
+//
+// detail/impl/socket_ops.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_SOCKET_OPS_IPP
+#define BOOST_ASIO_DETAIL_SOCKET_OPS_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/assert.hpp>
+#include <boost/detail/workaround.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cerrno>
+#include <new>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+namespace socket_ops {
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+struct msghdr { int msg_namelen; };
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#if defined(__hpux)
+// HP-UX doesn't declare these functions extern "C", so they are declared again
+// here to avoid linker errors about undefined symbols.
+extern "C" char* if_indextoname(unsigned int, char*);
+extern "C" unsigned int if_nametoindex(const char*);
+#endif // defined(__hpux)
+
+inline void clear_last_error()
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ WSASetLastError(0);
+#else
+ errno = 0;
+#endif
+}
+
+template <typename ReturnType>
+inline ReturnType error_wrapper(ReturnType return_value,
+ boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ ec = boost::system::error_code(WSAGetLastError(),
+ boost::asio::error::get_system_category());
+#else
+ ec = boost::system::error_code(errno,
+ boost::asio::error::get_system_category());
+#endif
+ return return_value;
+}
+
+template <typename SockLenType>
+inline socket_type call_accept(SockLenType msghdr::*,
+ socket_type s, socket_addr_type* addr, std::size_t* addrlen)
+{
+ SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
+ socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
+ if (addrlen)
+ *addrlen = (std::size_t)tmp_addrlen;
+ return result;
+}
+
+socket_type accept(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return invalid_socket;
+ }
+
+ clear_last_error();
+
+ socket_type new_s = error_wrapper(call_accept(
+ &msghdr::msg_namelen, s, addr, addrlen), ec);
+ if (new_s == invalid_socket)
+ return new_s;
+
+#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
+ int optval = 1;
+ int result = error_wrapper(::setsockopt(new_s,
+ SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
+ if (result != 0)
+ {
+ ::close(new_s);
+ return invalid_socket;
+ }
+#endif
+
+ ec = boost::system::error_code();
+ return new_s;
+}
+
+socket_type sync_accept(socket_type s, state_type state,
+ socket_addr_type* addr, std::size_t* addrlen, boost::system::error_code& ec)
+{
+ // Accept a socket.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ socket_type new_socket = socket_ops::accept(s, addr, addrlen, ec);
+
+ // Check if operation succeeded.
+ if (new_socket >= 0)
+ return new_socket;
+
+ // Operation failed.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ {
+ if (state & user_set_non_blocking)
+ return invalid_socket;
+ // Fall through to retry operation.
+ }
+ else if (ec == boost::asio::error::connection_aborted)
+ {
+ if (state & enable_connection_aborted)
+ return invalid_socket;
+ // Fall through to retry operation.
+ }
+#if defined(EPROTO)
+ else if (ec.value() == EPROTO)
+ {
+ if (state & enable_connection_aborted)
+ return invalid_socket;
+ // Fall through to retry operation.
+ }
+#endif // defined(EPROTO)
+ else
+ return invalid_socket;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_read(s, ec) < 0)
+ return invalid_socket;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_accept(socket_type s,
+ void* output_buffer, DWORD address_length,
+ socket_addr_type* addr, std::size_t* addrlen,
+ socket_type new_socket, boost::system::error_code& ec)
+{
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_aborted;
+
+ if (!ec)
+ {
+ // Get the address of the peer.
+ if (addr && addrlen)
+ {
+ LPSOCKADDR local_addr = 0;
+ int local_addr_length = 0;
+ LPSOCKADDR remote_addr = 0;
+ int remote_addr_length = 0;
+ GetAcceptExSockaddrs(output_buffer, 0, address_length,
+ address_length, &local_addr, &local_addr_length,
+ &remote_addr, &remote_addr_length);
+ if (static_cast<std::size_t>(remote_addr_length) > *addrlen)
+ {
+ ec = boost::asio::error::invalid_argument;
+ }
+ else
+ {
+ using namespace std; // For memcpy.
+ memcpy(addr, remote_addr, remote_addr_length);
+ *addrlen = 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.
+ SOCKET update_ctx_param = s;
+ socket_ops::state_type state = 0;
+ socket_ops::setsockopt(new_socket, state,
+ SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
+ &update_ctx_param, sizeof(SOCKET), ec);
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_accept(socket_type s,
+ state_type state, socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, socket_type& new_socket)
+{
+ for (;;)
+ {
+ // Accept the waiting connection.
+ new_socket = socket_ops::accept(s, addr, addrlen, ec);
+
+ // Check if operation succeeded.
+ if (new_socket >= 0)
+ return true;
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Operation failed.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ {
+ if (state & user_set_non_blocking)
+ return true;
+ // Fall through to retry operation.
+ }
+ else if (ec == boost::asio::error::connection_aborted)
+ {
+ if (state & enable_connection_aborted)
+ return true;
+ // Fall through to retry operation.
+ }
+#if defined(EPROTO)
+ else if (ec.value() == EPROTO)
+ {
+ if (state & enable_connection_aborted)
+ return true;
+ // Fall through to retry operation.
+ }
+#endif // defined(EPROTO)
+ else
+ return true;
+
+ return false;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+template <typename SockLenType>
+inline int call_bind(SockLenType msghdr::*,
+ socket_type s, const socket_addr_type* addr, std::size_t addrlen)
+{
+ return ::bind(s, addr, (SockLenType)addrlen);
+}
+
+int bind(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+ int result = error_wrapper(call_bind(
+ &msghdr::msg_namelen, s, addr, addrlen), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int close(socket_type s, state_type& state,
+ bool destruction, boost::system::error_code& ec)
+{
+ int result = 0;
+ if (s != invalid_socket)
+ {
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if ((state & non_blocking) && (state & user_set_linger))
+ {
+ ioctl_arg_type arg = 0;
+ ::ioctlsocket(s, FIONBIO, &arg);
+ state &= ~non_blocking;
+ }
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (state & non_blocking)
+ {
+ ioctl_arg_type arg = 0;
+ ::ioctl(s, FIONBIO, &arg);
+ state &= ~non_blocking;
+ }
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+ if (destruction && (state & user_set_linger))
+ {
+ ::linger opt;
+ opt.l_onoff = 0;
+ opt.l_linger = 0;
+ boost::system::error_code ignored_ec;
+ socket_ops::setsockopt(s, state, SOL_SOCKET,
+ SO_LINGER, &opt, sizeof(opt), ignored_ec);
+ }
+
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::closesocket(s), ec);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::close(s), ec);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (result == 0)
+ ec = boost::system::error_code();
+ }
+
+ return result;
+}
+
+bool set_internal_non_blocking(socket_type s,
+ state_type& state, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return false;
+ }
+
+ clear_last_error();
+ ioctl_arg_type arg = 1;
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctlsocket(s, FIONBIO, &arg), ec);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctl(s, FIONBIO, &arg), ec);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+ if (result >= 0)
+ {
+ ec = boost::system::error_code();
+ state |= internal_non_blocking;
+ return true;
+ }
+
+ return false;
+}
+
+int shutdown(socket_type s, int what, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+ int result = error_wrapper(::shutdown(s, what), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+template <typename SockLenType>
+inline int call_connect(SockLenType msghdr::*,
+ socket_type s, const socket_addr_type* addr, std::size_t addrlen)
+{
+ return ::connect(s, addr, (SockLenType)addrlen);
+}
+
+int connect(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+ int result = error_wrapper(call_connect(
+ &msghdr::msg_namelen, s, addr, addrlen), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+void sync_connect(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec)
+{
+ // Perform the connect operation.
+ socket_ops::connect(s, addr, addrlen, ec);
+ if (ec != boost::asio::error::in_progress
+ && ec != boost::asio::error::would_block)
+ {
+ // The connect operation finished immediately.
+ return;
+ }
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_connect(s, ec) < 0)
+ return;
+
+ // Get the error code from the connect operation.
+ int connect_error = 0;
+ size_t connect_error_len = sizeof(connect_error);
+ if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
+ &connect_error, &connect_error_len, ec) == socket_error_retval)
+ return;
+
+ // Return the result of the connect operation.
+ ec = boost::system::error_code(connect_error,
+ boost::asio::error::get_system_category());
+}
+
+bool non_blocking_connect(socket_type s, boost::system::error_code& ec)
+{
+ // Get the error code from the connect operation.
+ int connect_error = 0;
+ size_t connect_error_len = sizeof(connect_error);
+ if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_ERROR,
+ &connect_error, &connect_error_len, ec) == 0)
+ {
+ if (connect_error)
+ {
+ ec = boost::system::error_code(connect_error,
+ boost::asio::error::get_system_category());
+ }
+ else
+ ec = boost::system::error_code();
+ }
+
+ return true;
+}
+
+int socketpair(int af, int type, int protocol,
+ socket_type sv[2], boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ (void)(af);
+ (void)(type);
+ (void)(protocol);
+ (void)(sv);
+ ec = boost::asio::error::operation_not_supported;
+ return socket_error_retval;
+#else
+ clear_last_error();
+ int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+#endif
+}
+
+bool sockatmark(socket_type s, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return false;
+ }
+
+#if defined(SIOCATMARK)
+ ioctl_arg_type value = 0;
+# if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctlsocket(s, SIOCATMARK, &value), ec);
+# else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctl(s, SIOCATMARK, &value), ec);
+# endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (result == 0)
+ ec = boost::system::error_code();
+# if defined(ENOTTY)
+ if (ec.value() == ENOTTY)
+ ec = boost::asio::error::not_socket;
+# endif // defined(ENOTTY)
+#else // defined(SIOCATMARK)
+ int value = error_wrapper(::sockatmark(s), ec);
+ if (value != -1)
+ ec = boost::system::error_code();
+#endif // defined(SIOCATMARK)
+
+ return ec ? false : value != 0;
+}
+
+size_t available(socket_type s, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ ioctl_arg_type value = 0;
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctlsocket(s, FIONREAD, &value), ec);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctl(s, FIONREAD, &value), ec);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (result == 0)
+ ec = boost::system::error_code();
+#if defined(ENOTTY)
+ if (ec.value() == ENOTTY)
+ ec = boost::asio::error::not_socket;
+#endif // defined(ENOTTY)
+
+ return ec ? static_cast<size_t>(0) : static_cast<size_t>(value);
+}
+
+int listen(socket_type s, int backlog, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+ int result = error_wrapper(::listen(s, backlog), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+inline void init_buf_iov_base(void*& base, void* addr)
+{
+ base = addr;
+}
+
+template <typename T>
+inline void init_buf_iov_base(T& base, void* addr)
+{
+ base = static_cast<T>(addr);
+}
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+typedef WSABUF buf;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+typedef iovec buf;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+void init_buf(buf& b, void* data, size_t size)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ b.buf = static_cast<char*>(data);
+ b.len = static_cast<u_long>(size);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ init_buf_iov_base(b.iov_base, data);
+ b.iov_len = size;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+void init_buf(buf& b, const void* data, size_t size)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ b.buf = static_cast<char*>(const_cast<void*>(data));
+ b.len = static_cast<u_long>(size);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ init_buf_iov_base(b.iov_base, const_cast<void*>(data));
+ b.iov_len = size;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
+{
+ name = addr;
+}
+
+inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
+{
+ name = const_cast<socket_addr_type*>(addr);
+}
+
+template <typename T>
+inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
+{
+ name = reinterpret_cast<T>(addr);
+}
+
+template <typename T>
+inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
+{
+ name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
+}
+
+int recv(socket_type s, buf* bufs, size_t count, int flags,
+ boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ // Receive some data.
+ DWORD recv_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ DWORD recv_flags = flags;
+ int result = error_wrapper(::WSARecv(s, bufs,
+ recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec = boost::system::error_code();
+ return bytes_transferred;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ msg.msg_iov = bufs;
+ msg.msg_iovlen = count;
+ int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_recv(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, bool all_empty, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to read 0 bytes on a stream is a no-op.
+ if (all_empty && (state & stream_oriented))
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ int bytes = socket_ops::recv(s, bufs, count, flags, ec);
+
+ // Check if operation succeeded.
+ if (bytes > 0)
+ return bytes;
+
+ // Check for EOF.
+ if ((state & stream_oriented) && bytes == 0)
+ {
+ ec = boost::asio::error::eof;
+ return 0;
+ }
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_read(s, ec) < 0)
+ return 0;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_recv(state_type state,
+ const weak_cancel_token_type& cancel_token, bool all_empty,
+ boost::system::error_code& ec, size_t bytes_transferred)
+{
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ {
+ if (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
+ && (state & stream_oriented) != 0
+ && !all_empty)
+ {
+ ec = boost::asio::error::eof;
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_recv(socket_type s,
+ buf* bufs, size_t count, int flags, bool is_stream,
+ boost::system::error_code& ec, size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Read some data.
+ int bytes = socket_ops::recv(s, bufs, count, flags, ec);
+
+ // Check for end of stream.
+ if (is_stream && bytes == 0)
+ {
+ ec = boost::asio::error::eof;
+ return true;
+ }
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ // Receive some data.
+ DWORD recv_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ DWORD recv_flags = flags;
+ int tmp_addrlen = (int)*addrlen;
+ int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
+ &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
+ *addrlen = (std::size_t)tmp_addrlen;
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec = boost::system::error_code();
+ return bytes_transferred;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ init_msghdr_msg_name(msg.msg_name, addr);
+ msg.msg_namelen = *addrlen;
+ msg.msg_iov = bufs;
+ msg.msg_iovlen = count;
+ int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
+ *addrlen = msg.msg_namelen;
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_recvfrom(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec);
+
+ // Check if operation succeeded.
+ if (bytes >= 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_read(s, ec) < 0)
+ return 0;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec)
+{
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ {
+ if (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;
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Read some data.
+ int bytes = socket_ops::recvfrom(s, bufs, count, flags, addr, addrlen, ec);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+int send(socket_type s, const buf* bufs, size_t count, int flags,
+ boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ // Send the data.
+ DWORD send_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ DWORD send_flags = flags;
+ int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs),
+ send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec = boost::system::error_code();
+ return bytes_transferred;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ msg.msg_iov = const_cast<buf*>(bufs);
+ msg.msg_iovlen = count;
+#if defined(__linux__)
+ flags |= MSG_NOSIGNAL;
+#endif // defined(__linux__)
+ int result = error_wrapper(::sendmsg(s, &msg, flags), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_send(socket_type s, state_type state, const buf* bufs,
+ size_t count, int flags, bool all_empty, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to write 0 bytes to a stream is a no-op.
+ if (all_empty && (state & stream_oriented))
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // Read some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ int bytes = socket_ops::send(s, bufs, count, flags, ec);
+
+ // Check if operation succeeded.
+ if (bytes >= 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_write(s, ec) < 0)
+ return 0;
+ }
+}
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+void complete_iocp_send(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec)
+{
+ // Map non-portable errors to their portable counterparts.
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ {
+ if (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;
+ }
+}
+
+#else // defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_send(socket_type s,
+ const buf* bufs, size_t count, int flags,
+ boost::system::error_code& ec, size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Write some data.
+ int bytes = socket_ops::send(s, bufs, count, flags, ec);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+int sendto(socket_type s, const buf* bufs, size_t count, int flags,
+ const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ // Send the data.
+ DWORD send_buf_count = static_cast<DWORD>(count);
+ DWORD bytes_transferred = 0;
+ int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
+ send_buf_count, &bytes_transferred, flags, addr,
+ static_cast<int>(addrlen), 0, 0), ec);
+ if (ec.value() == ERROR_NETNAME_DELETED)
+ ec = boost::asio::error::connection_reset;
+ else if (ec.value() == ERROR_PORT_UNREACHABLE)
+ ec = boost::asio::error::connection_refused;
+ if (result != 0)
+ return socket_error_retval;
+ ec = boost::system::error_code();
+ return bytes_transferred;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ msghdr msg = msghdr();
+ init_msghdr_msg_name(msg.msg_name, addr);
+ msg.msg_namelen = addrlen;
+ msg.msg_iov = const_cast<buf*>(bufs);
+ msg.msg_iovlen = count;
+#if defined(__linux__)
+ flags |= MSG_NOSIGNAL;
+#endif // defined(__linux__)
+ int result = error_wrapper(::sendmsg(s, &msg, flags), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+size_t sync_sendto(socket_type s, state_type state, const buf* bufs,
+ size_t count, int flags, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // Write some data.
+ for (;;)
+ {
+ // Try to complete the operation without blocking.
+ int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec);
+
+ // Check if operation succeeded.
+ if (bytes >= 0)
+ return bytes;
+
+ // Operation failed.
+ if ((state & user_set_non_blocking)
+ || (ec != boost::asio::error::would_block
+ && ec != boost::asio::error::try_again))
+ return 0;
+
+ // Wait for socket to become ready.
+ if (socket_ops::poll_write(s, ec) < 0)
+ return 0;
+ }
+}
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+bool non_blocking_sendto(socket_type s,
+ const buf* bufs, size_t count, int flags,
+ const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred)
+{
+ for (;;)
+ {
+ // Write some data.
+ int bytes = socket_ops::sendto(s, bufs, count, flags, addr, addrlen, ec);
+
+ // Retry operation if interrupted by signal.
+ if (ec == boost::asio::error::interrupted)
+ continue;
+
+ // Check if we need to run the operation again.
+ if (ec == boost::asio::error::would_block
+ || ec == boost::asio::error::try_again)
+ return false;
+
+ // Operation is complete.
+ if (bytes >= 0)
+ {
+ ec = boost::system::error_code();
+ bytes_transferred = bytes;
+ }
+ else
+ bytes_transferred = 0;
+
+ return true;
+ }
+}
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+socket_type socket(int af, int type, int protocol,
+ boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0,
+ WSA_FLAG_OVERLAPPED), ec);
+ if (s == invalid_socket)
+ return s;
+
+ if (af == AF_INET6)
+ {
+ // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to
+ // false. This will only succeed on Windows Vista and later versions of
+ // Windows, where a dual-stack IPv4/v6 implementation is available.
+ DWORD optval = 0;
+ ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
+ reinterpret_cast<const char*>(&optval), sizeof(optval));
+ }
+
+ ec = boost::system::error_code();
+
+ return s;
+#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
+ socket_type s = error_wrapper(::socket(af, type, protocol), ec);
+ if (s == invalid_socket)
+ return s;
+
+ int optval = 1;
+ int result = error_wrapper(::setsockopt(s,
+ SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
+ if (result != 0)
+ {
+ ::close(s);
+ return invalid_socket;
+ }
+
+ return s;
+#else
+ int s = error_wrapper(::socket(af, type, protocol), ec);
+ if (s >= 0)
+ ec = boost::system::error_code();
+ return s;
+#endif
+}
+
+template <typename SockLenType>
+inline int call_setsockopt(SockLenType msghdr::*,
+ socket_type s, int level, int optname,
+ const void* optval, std::size_t optlen)
+{
+ return ::setsockopt(s, level, optname,
+ (const char*)optval, (SockLenType)optlen);
+}
+
+int setsockopt(socket_type s, state_type& state, int level, int optname,
+ const void* optval, std::size_t optlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ if (level == custom_socket_option_level && optname == always_fail_option)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return socket_error_retval;
+ }
+
+ if (level == custom_socket_option_level
+ && optname == enable_connection_aborted_option)
+ {
+ if (optlen != sizeof(int))
+ {
+ ec = boost::asio::error::invalid_argument;
+ return socket_error_retval;
+ }
+
+ if (*static_cast<const int*>(optval))
+ state |= enable_connection_aborted;
+ else
+ state &= ~enable_connection_aborted;
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ if (level == SOL_SOCKET && optname == SO_LINGER)
+ state |= user_set_linger;
+
+#if defined(__BORLANDC__)
+ // Mysteriously, using the getsockopt and setsockopt functions directly with
+ // Borland C++ results in incorrect values being set and read. The bug can be
+ // worked around by using function addresses resolved with GetProcAddress.
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);
+ if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))
+ {
+ clear_last_error();
+ return error_wrapper(sso(s, level, optname,
+ reinterpret_cast<const char*>(optval),
+ static_cast<int>(optlen)), ec);
+ }
+ }
+ ec = boost::asio::error::fault;
+ return socket_error_retval;
+#else // defined(__BORLANDC__)
+ clear_last_error();
+ int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
+ s, level, optname, optval, optlen), ec);
+ if (result == 0)
+ {
+ ec = boost::system::error_code();
+
+#if defined(__MACH__) && defined(__APPLE__) \
+ || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ // To implement portable behaviour for SO_REUSEADDR with UDP sockets we
+ // need to also set SO_REUSEPORT on BSD-based platforms.
+ if ((state & datagram_oriented)
+ && level == SOL_SOCKET && optname == SO_REUSEADDR)
+ {
+ call_setsockopt(&msghdr::msg_namelen, s,
+ SOL_SOCKET, SO_REUSEPORT, optval, optlen);
+ }
+#endif
+ }
+
+ return result;
+#endif // defined(__BORLANDC__)
+}
+
+template <typename SockLenType>
+inline int call_getsockopt(SockLenType msghdr::*,
+ socket_type s, int level, int optname,
+ void* optval, std::size_t* optlen)
+{
+ SockLenType tmp_optlen = (SockLenType)*optlen;
+ int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
+ *optlen = (std::size_t)tmp_optlen;
+ return result;
+}
+
+int getsockopt(socket_type s, state_type state, int level, int optname,
+ void* optval, size_t* optlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ if (level == custom_socket_option_level && optname == always_fail_option)
+ {
+ ec = boost::asio::error::invalid_argument;
+ return socket_error_retval;
+ }
+
+ if (level == custom_socket_option_level
+ && optname == enable_connection_aborted_option)
+ {
+ if (*optlen != sizeof(int))
+ {
+ ec = boost::asio::error::invalid_argument;
+ return socket_error_retval;
+ }
+
+ *static_cast<int*>(optval) = (state & enable_connection_aborted) ? 1 : 0;
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+#if defined(__BORLANDC__)
+ // Mysteriously, using the getsockopt and setsockopt functions directly with
+ // Borland C++ results in incorrect values being set and read. The bug can be
+ // worked around by using function addresses resolved with GetProcAddress.
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);
+ if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))
+ {
+ clear_last_error();
+ int tmp_optlen = static_cast<int>(*optlen);
+ int result = error_wrapper(gso(s, level, optname,
+ reinterpret_cast<char*>(optval), &tmp_optlen), ec);
+ *optlen = static_cast<size_t>(tmp_optlen);
+ if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
+ && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
+ {
+ // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are
+ // only supported on Windows Vista and later. To simplify program logic
+ // we will fake success of getting this option and specify that the
+ // value is non-zero (i.e. true). This corresponds to the behavior of
+ // IPv6 sockets on Windows platforms pre-Vista.
+ *static_cast<DWORD*>(optval) = 1;
+ ec = boost::system::error_code();
+ }
+ return result;
+ }
+ }
+ ec = boost::asio::error::fault;
+ return socket_error_retval;
+#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ clear_last_error();
+ int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
+ s, level, optname, optval, optlen), ec);
+ if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
+ && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
+ {
+ // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only
+ // supported on Windows Vista and later. To simplify program logic we will
+ // fake success of getting this option and specify that the value is
+ // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets
+ // on Windows platforms pre-Vista.
+ *static_cast<DWORD*>(optval) = 1;
+ ec = boost::system::error_code();
+ }
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ clear_last_error();
+ int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
+ s, level, optname, optval, optlen), ec);
+#if defined(__linux__)
+ if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
+ && (optname == SO_SNDBUF || optname == SO_RCVBUF))
+ {
+ // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
+ // to set the buffer size to N*2. Linux puts additional stuff into the
+ // buffers so that only about half is actually available to the application.
+ // The retrieved value is divided by 2 here to make it appear as though the
+ // correct value has been set.
+ *static_cast<int*>(optval) /= 2;
+ }
+#endif // defined(__linux__)
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+template <typename SockLenType>
+inline int call_getpeername(SockLenType msghdr::*,
+ socket_type s, socket_addr_type* addr, std::size_t* addrlen)
+{
+ SockLenType tmp_addrlen = (SockLenType)*addrlen;
+ int result = ::getpeername(s, addr, &tmp_addrlen);
+ *addrlen = (std::size_t)tmp_addrlen;
+ return result;
+}
+
+int getpeername(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, bool cached, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (cached)
+ {
+ // Check if socket is still connected.
+ DWORD connect_time = 0;
+ size_t connect_time_len = sizeof(connect_time);
+ if (socket_ops::getsockopt(s, 0, SOL_SOCKET, SO_CONNECT_TIME,
+ &connect_time, &connect_time_len, ec) == socket_error_retval)
+ {
+ return socket_error_retval;
+ }
+ if (connect_time == 0xFFFFFFFF)
+ {
+ ec = boost::asio::error::not_connected;
+ return socket_error_retval;
+ }
+
+ // The cached value is still valid.
+ ec = boost::system::error_code();
+ return 0;
+ }
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ (void)cached;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+ clear_last_error();
+ int result = error_wrapper(call_getpeername(
+ &msghdr::msg_namelen, s, addr, addrlen), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+template <typename SockLenType>
+inline int call_getsockname(SockLenType msghdr::*,
+ socket_type s, socket_addr_type* addr, std::size_t* addrlen)
+{
+ SockLenType tmp_addrlen = (SockLenType)*addrlen;
+ int result = ::getsockname(s, addr, &tmp_addrlen);
+ *addrlen = (std::size_t)tmp_addrlen;
+ return result;
+}
+
+int getsockname(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+ int result = error_wrapper(call_getsockname(
+ &msghdr::msg_namelen, s, addr, addrlen), ec);
+ if (result == 0)
+ ec = boost::system::error_code();
+ return result;
+}
+
+int ioctl(socket_type s, state_type& state, long cmd,
+ ioctl_arg_type* arg, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::ioctl(s, cmd, arg), ec);
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (result >= 0)
+ {
+ ec = boost::system::error_code();
+
+ // When updating the non-blocking mode we always perform the ioctl syscall,
+ // even if the flags would otherwise indicate that the socket is already in
+ // the correct state. This ensures that the underlying socket is put into
+ // the state that has been requested by the user. If the ioctl syscall was
+ // successful then we need to update the flags to match.
+ if (cmd == static_cast<long>(FIONBIO))
+ {
+ if (*arg)
+ {
+ state |= user_set_non_blocking;
+ }
+ else
+ {
+ // Clearing the non-blocking mode always overrides any internally-set
+ // non-blocking flag. Any subsequent asynchronous operations will need
+ // to re-enable non-blocking I/O.
+ state &= ~(user_set_non_blocking | internal_non_blocking);
+ }
+ }
+ }
+
+ return result;
+}
+
+int select(int nfds, fd_set* readfds, fd_set* writefds,
+ fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ if (!readfds && !writefds && !exceptfds && timeout)
+ {
+ DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
+ if (milliseconds == 0)
+ milliseconds = 1; // Force context switch.
+ ::Sleep(milliseconds);
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ // The select() call allows timeout values measured in microseconds, but the
+ // system clock (as wrapped by boost::posix_time::microsec_clock) typically
+ // has a resolution of 10 milliseconds. This can lead to a spinning select
+ // reactor, meaning increased CPU usage, when waiting for the earliest
+ // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight
+ // spin we'll use a minimum timeout of 1 millisecond.
+ if (timeout && timeout->tv_sec == 0
+ && timeout->tv_usec > 0 && timeout->tv_usec < 1000)
+ timeout->tv_usec = 1000;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#if defined(__hpux) && defined(__HP_aCC)
+ timespec ts;
+ ts.tv_sec = timeout ? timeout->tv_sec : 0;
+ ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
+ return error_wrapper(::pselect(nfds, readfds,
+ writefds, exceptfds, timeout ? &ts : 0, 0), ec);
+#else
+ int result = error_wrapper(::select(nfds, readfds,
+ writefds, exceptfds, timeout), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif
+}
+
+int poll_read(socket_type s, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ FD_SET fds;
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ clear_last_error();
+ int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ pollfd fds;
+ fds.fd = s;
+ fds.events = POLLIN;
+ fds.revents = 0;
+ clear_last_error();
+ int result = error_wrapper(::poll(&fds, 1, -1), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+int poll_write(socket_type s, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ FD_SET fds;
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+ clear_last_error();
+ int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ pollfd fds;
+ fds.fd = s;
+ fds.events = POLLOUT;
+ fds.revents = 0;
+ clear_last_error();
+ int result = error_wrapper(::poll(&fds, 1, -1), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+int poll_connect(socket_type s, boost::system::error_code& ec)
+{
+ if (s == invalid_socket)
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return socket_error_retval;
+ }
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ FD_SET write_fds;
+ FD_ZERO(&write_fds);
+ FD_SET(s, &write_fds);
+ FD_SET except_fds;
+ FD_ZERO(&except_fds);
+ FD_SET(s, &except_fds);
+ clear_last_error();
+ int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ pollfd fds;
+ fds.fd = s;
+ fds.events = POLLOUT;
+ fds.revents = 0;
+ clear_last_error();
+ int result = error_wrapper(::poll(&fds, 1, -1), ec);
+ if (result >= 0)
+ ec = boost::system::error_code();
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+const char* inet_ntop(int af, const void* src, char* dest, size_t length,
+ unsigned long scope_id, boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ using namespace std; // For memcpy.
+
+ if (af != AF_INET && af != AF_INET6)
+ {
+ ec = boost::asio::error::address_family_not_supported;
+ return 0;
+ }
+
+ union
+ {
+ socket_addr_type base;
+ sockaddr_storage_type storage;
+ sockaddr_in4_type v4;
+ sockaddr_in6_type v6;
+ } address;
+ DWORD address_length;
+ if (af == AF_INET)
+ {
+ address_length = sizeof(sockaddr_in4_type);
+ address.v4.sin_family = AF_INET;
+ address.v4.sin_port = 0;
+ memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type));
+ }
+ else // AF_INET6
+ {
+ address_length = sizeof(sockaddr_in6_type);
+ address.v6.sin6_family = AF_INET6;
+ address.v6.sin6_port = 0;
+ address.v6.sin6_flowinfo = 0;
+ address.v6.sin6_scope_id = scope_id;
+ memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type));
+ }
+
+ DWORD string_length = static_cast<DWORD>(length);
+#if defined(BOOST_NO_ANSI_APIS)
+ LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
+ int result = error_wrapper(::WSAAddressToStringW(&address.base,
+ address_length, 0, string_buffer, &string_length), ec);
+ ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
+#else
+ int result = error_wrapper(::WSAAddressToStringA(
+ &address.base, address_length, 0, dest, &string_length), ec);
+#endif
+
+ // Windows may set error code on success.
+ if (result != socket_error_retval)
+ ec = boost::system::error_code();
+
+ // Windows may not set an error code on failure.
+ else if (result == socket_error_retval && !ec)
+ ec = boost::asio::error::invalid_argument;
+
+ return result == socket_error_retval ? 0 : dest;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec);
+ if (result == 0 && !ec)
+ ec = boost::asio::error::invalid_argument;
+ if (result != 0 && af == AF_INET6 && scope_id != 0)
+ {
+ using namespace std; // For strcat and sprintf.
+ char if_name[IF_NAMESIZE + 1] = "%";
+ const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
+ bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);
+ if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0)
+ sprintf(if_name + 1, "%lu", scope_id);
+ strcat(dest, if_name);
+ }
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+int inet_pton(int af, const char* src, void* dest,
+ unsigned long* scope_id, boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ using namespace std; // For memcpy and strcmp.
+
+ if (af != AF_INET && af != AF_INET6)
+ {
+ ec = boost::asio::error::address_family_not_supported;
+ return -1;
+ }
+
+ union
+ {
+ socket_addr_type base;
+ sockaddr_storage_type storage;
+ sockaddr_in4_type v4;
+ sockaddr_in6_type v6;
+ } address;
+ int address_length = sizeof(sockaddr_storage_type);
+#if defined(BOOST_NO_ANSI_APIS)
+ int num_wide_chars = strlen(src) + 1;
+ LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
+ ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
+ int result = error_wrapper(::WSAStringToAddressW(
+ wide_buffer, af, 0, &address.base, &address_length), ec);
+#else
+ int result = error_wrapper(::WSAStringToAddressA(
+ const_cast<char*>(src), af, 0, &address.base, &address_length), ec);
+#endif
+
+ if (af == AF_INET)
+ {
+ if (result != socket_error_retval)
+ {
+ memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type));
+ ec = boost::system::error_code();
+ }
+ else if (strcmp(src, "255.255.255.255") == 0)
+ {
+ static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;
+ ec = boost::system::error_code();
+ }
+ }
+ else // AF_INET6
+ {
+ if (result != socket_error_retval)
+ {
+ memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type));
+ if (scope_id)
+ *scope_id = address.v6.sin6_scope_id;
+ ec = boost::system::error_code();
+ }
+ }
+
+ // Windows may not set an error code on failure.
+ if (result == socket_error_retval && !ec)
+ ec = boost::asio::error::invalid_argument;
+
+ if (result != socket_error_retval)
+ ec = boost::system::error_code();
+
+ return result == socket_error_retval ? -1 : 1;
+#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ int result = error_wrapper(::inet_pton(af, src, dest), ec);
+ if (result <= 0 && !ec)
+ ec = boost::asio::error::invalid_argument;
+ if (result > 0 && af == AF_INET6 && scope_id)
+ {
+ using namespace std; // For strchr and atoi.
+ *scope_id = 0;
+ if (const char* if_name = strchr(src, '%'))
+ {
+ in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
+ bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);
+ if (is_link_local)
+ *scope_id = if_nametoindex(if_name + 1);
+ if (*scope_id == 0)
+ *scope_id = atoi(if_name + 1);
+ }
+ }
+ return result;
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+}
+
+int gethostname(char* name, int namelen, boost::system::error_code& ec)
+{
+ clear_last_error();
+ int result = error_wrapper(::gethostname(name, namelen), ec);
+#if defined(BOOST_WINDOWS)
+ if (result == 0)
+ ec = boost::system::error_code();
+#endif
+ return result;
+}
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \
+ || defined(__MACH__) && defined(__APPLE__)
+
+// The following functions are only needed for emulation of getaddrinfo and
+// getnameinfo.
+
+inline boost::system::error_code translate_netdb_error(int error)
+{
+ switch (error)
+ {
+ case 0:
+ return boost::system::error_code();
+ case HOST_NOT_FOUND:
+ return boost::asio::error::host_not_found;
+ case TRY_AGAIN:
+ return boost::asio::error::host_not_found_try_again;
+ case NO_RECOVERY:
+ return boost::asio::error::no_recovery;
+ case NO_DATA:
+ return boost::asio::error::no_data;
+ default:
+ BOOST_ASSERT(false);
+ return boost::asio::error::invalid_argument;
+ }
+}
+
+inline hostent* gethostbyaddr(const char* addr, int length, int af,
+ hostent* result, char* buffer, int buflength, boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ (void)(buffer);
+ (void)(buflength);
+ hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
+ if (!retval)
+ return 0;
+ ec = boost::system::error_code();
+ *result = *retval;
+ return retval;
+#elif defined(__sun) || defined(__QNX__)
+ int error = 0;
+ hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result,
+ buffer, buflength, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ return retval;
+#elif defined(__MACH__) && defined(__APPLE__)
+ (void)(buffer);
+ (void)(buflength);
+ int error = 0;
+ hostent* retval = error_wrapper(::getipnodebyaddr(
+ addr, length, af, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ if (!retval)
+ return 0;
+ *result = *retval;
+ return retval;
+#else
+ hostent* retval = 0;
+ int error = 0;
+ error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer,
+ buflength, &retval, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ return retval;
+#endif
+}
+
+inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
+ char* buffer, int buflength, int ai_flags, boost::system::error_code& ec)
+{
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ (void)(buffer);
+ (void)(buflength);
+ (void)(ai_flags);
+ if (af != AF_INET)
+ {
+ ec = boost::asio::error::address_family_not_supported;
+ return 0;
+ }
+ hostent* retval = error_wrapper(::gethostbyname(name), ec);
+ if (!retval)
+ return 0;
+ ec = boost::system::error_code();
+ *result = *retval;
+ return result;
+#elif defined(__sun) || defined(__QNX__)
+ (void)(ai_flags);
+ if (af != AF_INET)
+ {
+ ec = boost::asio::error::address_family_not_supported;
+ return 0;
+ }
+ int error = 0;
+ hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer,
+ buflength, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ return retval;
+#elif defined(__MACH__) && defined(__APPLE__)
+ (void)(buffer);
+ (void)(buflength);
+ int error = 0;
+ hostent* retval = error_wrapper(::getipnodebyname(
+ name, af, ai_flags, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ if (!retval)
+ return 0;
+ *result = *retval;
+ return retval;
+#else
+ (void)(ai_flags);
+ if (af != AF_INET)
+ {
+ ec = boost::asio::error::address_family_not_supported;
+ return 0;
+ }
+ hostent* retval = 0;
+ int error = 0;
+ error_wrapper(::gethostbyname_r(name, result,
+ buffer, buflength, &retval, &error), ec);
+ if (error)
+ ec = translate_netdb_error(error);
+ return retval;
+#endif
+}
+
+inline void freehostent(hostent* h)
+{
+#if defined(__MACH__) && defined(__APPLE__)
+ if (h)
+ ::freehostent(h);
+#else
+ (void)(h);
+#endif
+}
+
+// Emulation of getaddrinfo based on implementation in:
+// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998.
+
+struct gai_search
+{
+ const char* host;
+ int family;
+};
+
+inline int gai_nsearch(const char* host,
+ const addrinfo_type* hints, gai_search (&search)[2])
+{
+ int search_count = 0;
+ if (host == 0 || host[0] == '\0')
+ {
+ if (hints->ai_flags & AI_PASSIVE)
+ {
+ // No host and AI_PASSIVE implies wildcard bind.
+ switch (hints->ai_family)
+ {
+ case AF_INET:
+ search[search_count].host = "0.0.0.0";
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ case AF_INET6:
+ search[search_count].host = "0::0";
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ break;
+ case AF_UNSPEC:
+ search[search_count].host = "0::0";
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ search[search_count].host = "0.0.0.0";
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ // No host and not AI_PASSIVE means connect to local host.
+ switch (hints->ai_family)
+ {
+ case AF_INET:
+ search[search_count].host = "localhost";
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ case AF_INET6:
+ search[search_count].host = "localhost";
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ break;
+ case AF_UNSPEC:
+ search[search_count].host = "localhost";
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ search[search_count].host = "localhost";
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Host is specified.
+ switch (hints->ai_family)
+ {
+ case AF_INET:
+ search[search_count].host = host;
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ case AF_INET6:
+ search[search_count].host = host;
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ break;
+ case AF_UNSPEC:
+ search[search_count].host = host;
+ search[search_count].family = AF_INET6;
+ ++search_count;
+ search[search_count].host = host;
+ search[search_count].family = AF_INET;
+ ++search_count;
+ break;
+ default:
+ break;
+ }
+ }
+ return search_count;
+}
+
+template <typename T>
+inline T* gai_alloc(std::size_t size = sizeof(T))
+{
+ using namespace std;
+ T* p = static_cast<T*>(::operator new(size, std::nothrow));
+ if (p)
+ memset(p, 0, size);
+ return p;
+}
+
+inline void gai_free(void* p)
+{
+ ::operator delete(p);
+}
+
+inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
+{
+ using namespace std;
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
+ strcpy_s(target, max_size, source);
+#else
+ *target = 0;
+ strncat(target, source, max_size);
+#endif
+}
+
+enum { gai_clone_flag = 1 << 30 };
+
+inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
+ const void* addr, int family)
+{
+ using namespace std;
+
+ addrinfo_type* ai = gai_alloc<addrinfo_type>();
+ if (ai == 0)
+ return EAI_MEMORY;
+
+ ai->ai_next = 0;
+ **next = ai;
+ *next = &ai->ai_next;
+
+ ai->ai_canonname = 0;
+ ai->ai_socktype = hints->ai_socktype;
+ if (ai->ai_socktype == 0)
+ ai->ai_flags |= gai_clone_flag;
+ ai->ai_protocol = hints->ai_protocol;
+ ai->ai_family = family;
+
+ switch (ai->ai_family)
+ {
+ case AF_INET:
+ {
+ sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>();
+ if (sinptr == 0)
+ return EAI_MEMORY;
+ sinptr->sin_family = AF_INET;
+ memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type));
+ ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr);
+ ai->ai_addrlen = sizeof(sockaddr_in4_type);
+ break;
+ }
+ case AF_INET6:
+ {
+ sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>();
+ if (sin6ptr == 0)
+ return EAI_MEMORY;
+ sin6ptr->sin6_family = AF_INET6;
+ memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type));
+ ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr);
+ ai->ai_addrlen = sizeof(sockaddr_in6_type);
+ break;
+ }
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+inline addrinfo_type* gai_clone(addrinfo_type* ai)
+{
+ using namespace std;
+
+ addrinfo_type* new_ai = gai_alloc<addrinfo_type>();
+ if (new_ai == 0)
+ return new_ai;
+
+ new_ai->ai_next = ai->ai_next;
+ ai->ai_next = new_ai;
+
+ new_ai->ai_flags = 0;
+ new_ai->ai_family = ai->ai_family;
+ new_ai->ai_socktype = ai->ai_socktype;
+ new_ai->ai_protocol = ai->ai_protocol;
+ new_ai->ai_canonname = 0;
+ new_ai->ai_addrlen = ai->ai_addrlen;
+ new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen);
+ memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen);
+
+ return new_ai;
+}
+
+inline int gai_port(addrinfo_type* aihead, int port, int socktype)
+{
+ int num_found = 0;
+
+ for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next)
+ {
+ if (ai->ai_flags & gai_clone_flag)
+ {
+ if (ai->ai_socktype != 0)
+ {
+ ai = gai_clone(ai);
+ if (ai == 0)
+ return -1;
+ // ai now points to newly cloned entry.
+ }
+ }
+ else if (ai->ai_socktype != socktype)
+ {
+ // Ignore if mismatch on socket type.
+ continue;
+ }
+
+ ai->ai_socktype = socktype;
+
+ switch (ai->ai_family)
+ {
+ case AF_INET:
+ {
+ sockaddr_in4_type* sinptr =
+ reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
+ sinptr->sin_port = port;
+ ++num_found;
+ break;
+ }
+ case AF_INET6:
+ {
+ sockaddr_in6_type* sin6ptr =
+ reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
+ sin6ptr->sin6_port = port;
+ ++num_found;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ return num_found;
+}
+
+inline int gai_serv(addrinfo_type* aihead,
+ const addrinfo_type* hints, const char* serv)
+{
+ using namespace std;
+
+ int num_found = 0;
+
+ if (
+#if defined(AI_NUMERICSERV)
+ (hints->ai_flags & AI_NUMERICSERV) ||
+#endif
+ isdigit(serv[0]))
+ {
+ int port = htons(atoi(serv));
+ if (hints->ai_socktype)
+ {
+ // Caller specifies socket type.
+ int rc = gai_port(aihead, port, hints->ai_socktype);
+ if (rc < 0)
+ return EAI_MEMORY;
+ num_found += rc;
+ }
+ else
+ {
+ // Caller does not specify socket type.
+ int rc = gai_port(aihead, port, SOCK_STREAM);
+ if (rc < 0)
+ return EAI_MEMORY;
+ num_found += rc;
+ rc = gai_port(aihead, port, SOCK_DGRAM);
+ if (rc < 0)
+ return EAI_MEMORY;
+ num_found += rc;
+ }
+ }
+ else
+ {
+ // Try service name with TCP first, then UDP.
+ if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM)
+ {
+ servent* sptr = getservbyname(serv, "tcp");
+ if (sptr != 0)
+ {
+ int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM);
+ if (rc < 0)
+ return EAI_MEMORY;
+ num_found += rc;
+ }
+ }
+ if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM)
+ {
+ servent* sptr = getservbyname(serv, "udp");
+ if (sptr != 0)
+ {
+ int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM);
+ if (rc < 0)
+ return EAI_MEMORY;
+ num_found += rc;
+ }
+ }
+ }
+
+ if (num_found == 0)
+ {
+ if (hints->ai_socktype == 0)
+ {
+ // All calls to getservbyname() failed.
+ return EAI_NONAME;
+ }
+ else
+ {
+ // Service not supported for socket type.
+ return EAI_SERVICE;
+ }
+ }
+
+ return 0;
+}
+
+inline int gai_echeck(const char* host, const char* service,
+ int flags, int family, int socktype, int protocol)
+{
+ (void)(flags);
+ (void)(protocol);
+
+ // Host or service must be specified.
+ if (host == 0 || host[0] == '\0')
+ if (service == 0 || service[0] == '\0')
+ return EAI_NONAME;
+
+ // Check combination of family and socket type.
+ switch (family)
+ {
+ case AF_UNSPEC:
+ break;
+ case AF_INET:
+ case AF_INET6:
+ if (service != 0 && service[0] != '\0')
+ if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
+ return EAI_SOCKTYPE;
+ break;
+ default:
+ return EAI_FAMILY;
+ }
+
+ return 0;
+}
+
+inline void freeaddrinfo_emulation(addrinfo_type* aihead)
+{
+ addrinfo_type* ai = aihead;
+ while (ai)
+ {
+ gai_free(ai->ai_addr);
+ gai_free(ai->ai_canonname);
+ addrinfo_type* ainext = ai->ai_next;
+ gai_free(ai);
+ ai = ainext;
+ }
+}
+
+inline int getaddrinfo_emulation(const char* host, const char* service,
+ const addrinfo_type* hintsp, addrinfo_type** result)
+{
+ // Set up linked list of addrinfo structures.
+ addrinfo_type* aihead = 0;
+ addrinfo_type** ainext = &aihead;
+ char* canon = 0;
+
+ // Supply default hints if not specified by caller.
+ addrinfo_type hints = addrinfo_type();
+ hints.ai_family = AF_UNSPEC;
+ if (hintsp)
+ hints = *hintsp;
+
+ // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED
+ // and AI_ALL flags.
+#if defined(AI_V4MAPPED)
+ if (hints.ai_family != AF_INET6)
+ hints.ai_flags &= ~AI_V4MAPPED;
+#endif
+#if defined(AI_ALL)
+ if (hints.ai_family != AF_INET6)
+ hints.ai_flags &= ~AI_ALL;
+#endif
+
+ // Basic error checking.
+ int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family,
+ hints.ai_socktype, hints.ai_protocol);
+ if (rc != 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ return rc;
+ }
+
+ gai_search search[2];
+ int search_count = gai_nsearch(host, &hints, search);
+ for (gai_search* sptr = search; sptr < search + search_count; ++sptr)
+ {
+ // Check for IPv4 dotted decimal string.
+ in4_addr_type inaddr;
+ boost::system::error_code ec;
+ if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1)
+ {
+ if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ return EAI_FAMILY;
+ }
+ if (sptr->family == AF_INET)
+ {
+ rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET);
+ if (rc != 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ return rc;
+ }
+ }
+ continue;
+ }
+
+ // Check for IPv6 hex string.
+ in6_addr_type in6addr;
+ if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1)
+ {
+ if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ return EAI_FAMILY;
+ }
+ if (sptr->family == AF_INET6)
+ {
+ rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6);
+ if (rc != 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ return rc;
+ }
+ }
+ continue;
+ }
+
+ // Look up hostname.
+ hostent hent;
+ char hbuf[8192] = "";
+ hostent* hptr = socket_ops::gethostbyname(sptr->host,
+ sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec);
+ if (hptr == 0)
+ {
+ if (search_count == 2)
+ {
+ // Failure is OK if there are multiple searches.
+ continue;
+ }
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ if (ec == boost::asio::error::host_not_found)
+ return EAI_NONAME;
+ if (ec == boost::asio::error::host_not_found_try_again)
+ return EAI_AGAIN;
+ if (ec == boost::asio::error::no_recovery)
+ return EAI_FAIL;
+ if (ec == boost::asio::error::no_data)
+ return EAI_NONAME;
+ return EAI_NONAME;
+ }
+
+ // Check for address family mismatch if one was specified.
+ if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ socket_ops::freehostent(hptr);
+ return EAI_FAMILY;
+ }
+
+ // Save canonical name first time.
+ if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
+ && (hints.ai_flags & AI_CANONNAME) && canon == 0)
+ {
+ std::size_t canon_len = strlen(hptr->h_name) + 1;
+ canon = gai_alloc<char>(canon_len);
+ if (canon == 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ socket_ops::freehostent(hptr);
+ return EAI_MEMORY;
+ }
+ gai_strcpy(canon, hptr->h_name, canon_len);
+ }
+
+ // Create an addrinfo structure for each returned address.
+ for (char** ap = hptr->h_addr_list; *ap; ++ap)
+ {
+ rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype);
+ if (rc != 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ gai_free(canon);
+ socket_ops::freehostent(hptr);
+ return EAI_FAMILY;
+ }
+ }
+
+ socket_ops::freehostent(hptr);
+ }
+
+ // Check if we found anything.
+ if (aihead == 0)
+ {
+ gai_free(canon);
+ return EAI_NONAME;
+ }
+
+ // Return canonical name in first entry.
+ if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME))
+ {
+ if (canon)
+ {
+ aihead->ai_canonname = canon;
+ canon = 0;
+ }
+ else
+ {
+ std::size_t canonname_len = strlen(search[0].host) + 1;
+ aihead->ai_canonname = gai_alloc<char>(canonname_len);
+ if (aihead->ai_canonname == 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ return EAI_MEMORY;
+ }
+ gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
+ }
+ }
+ gai_free(canon);
+
+ // Process the service name.
+ if (service != 0 && service[0] != '\0')
+ {
+ rc = gai_serv(aihead, &hints, service);
+ if (rc != 0)
+ {
+ freeaddrinfo_emulation(aihead);
+ return rc;
+ }
+ }
+
+ // Return result to caller.
+ *result = aihead;
+ return 0;
+}
+
+inline boost::system::error_code getnameinfo_emulation(
+ const socket_addr_type* sa, std::size_t salen, char* host,
+ std::size_t hostlen, char* serv, std::size_t servlen, int flags,
+ boost::system::error_code& ec)
+{
+ using namespace std;
+
+ const char* addr;
+ size_t addr_len;
+ unsigned short port;
+ switch (sa->sa_family)
+ {
+ case AF_INET:
+ if (salen != sizeof(sockaddr_in4_type))
+ {
+ return ec = boost::asio::error::invalid_argument;
+ }
+ addr = reinterpret_cast<const char*>(
+ &reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr);
+ addr_len = sizeof(in4_addr_type);
+ port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port;
+ break;
+ case AF_INET6:
+ if (salen != sizeof(sockaddr_in6_type))
+ {
+ return ec = boost::asio::error::invalid_argument;
+ }
+ addr = reinterpret_cast<const char*>(
+ &reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr);
+ addr_len = sizeof(in6_addr_type);
+ port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port;
+ break;
+ default:
+ return ec = boost::asio::error::address_family_not_supported;
+ }
+
+ if (host && hostlen > 0)
+ {
+ if (flags & NI_NUMERICHOST)
+ {
+ if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0)
+ {
+ return ec;
+ }
+ }
+ else
+ {
+ hostent hent;
+ char hbuf[8192] = "";
+ hostent* hptr = socket_ops::gethostbyaddr(addr,
+ static_cast<int>(addr_len), sa->sa_family,
+ &hent, hbuf, sizeof(hbuf), ec);
+ if (hptr && hptr->h_name && hptr->h_name[0] != '\0')
+ {
+ if (flags & NI_NOFQDN)
+ {
+ char* dot = strchr(hptr->h_name, '.');
+ if (dot)
+ {
+ *dot = 0;
+ }
+ }
+ gai_strcpy(host, hptr->h_name, hostlen);
+ socket_ops::freehostent(hptr);
+ }
+ else
+ {
+ socket_ops::freehostent(hptr);
+ if (flags & NI_NAMEREQD)
+ {
+ return ec = boost::asio::error::host_not_found;
+ }
+ if (socket_ops::inet_ntop(sa->sa_family,
+ addr, host, hostlen, 0, ec) == 0)
+ {
+ return ec;
+ }
+ }
+ }
+ }
+
+ if (serv && servlen > 0)
+ {
+ if (flags & NI_NUMERICSERV)
+ {
+ if (servlen < 6)
+ {
+ return ec = boost::asio::error::no_buffer_space;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
+ sprintf_s(serv, servlen, "%u", ntohs(port));
+#else
+ sprintf(serv, "%u", ntohs(port));
+#endif
+ }
+ else
+ {
+#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \
+ && !defined(BOOST_ASIO_DISABLE_THREADS)
+ static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ ::pthread_mutex_lock(&mutex);
+#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
+ // && !defined(BOOST_ASIO_DISABLE_THREADS)
+ servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
+ if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
+ {
+ gai_strcpy(serv, sptr->s_name, servlen);
+ }
+ else
+ {
+ if (servlen < 6)
+ {
+ return ec = boost::asio::error::no_buffer_space;
+ }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
+ sprintf_s(serv, servlen, "%u", ntohs(port));
+#else
+ sprintf(serv, "%u", ntohs(port));
+#endif
+ }
+#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS) \
+ && !defined(BOOST_ASIO_DISABLE_THREADS)
+ ::pthread_mutex_unlock(&mutex);
+#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
+ // && !defined(BOOST_ASIO_DISABLE_THREADS)
+ }
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ // || defined(__MACH__) && defined(__APPLE__)
+
+inline boost::system::error_code translate_addrinfo_error(int error)
+{
+ switch (error)
+ {
+ case 0:
+ return boost::system::error_code();
+ case EAI_AGAIN:
+ return boost::asio::error::host_not_found_try_again;
+ case EAI_BADFLAGS:
+ return boost::asio::error::invalid_argument;
+ case EAI_FAIL:
+ return boost::asio::error::no_recovery;
+ case EAI_FAMILY:
+ return boost::asio::error::address_family_not_supported;
+ case EAI_MEMORY:
+ return boost::asio::error::no_memory;
+ case EAI_NONAME:
+#if defined(EAI_ADDRFAMILY)
+ case EAI_ADDRFAMILY:
+#endif
+#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
+ case EAI_NODATA:
+#endif
+ return boost::asio::error::host_not_found;
+ case EAI_SERVICE:
+ return boost::asio::error::service_not_found;
+ case EAI_SOCKTYPE:
+ return boost::asio::error::socket_type_not_supported;
+ default: // Possibly the non-portable EAI_SYSTEM.
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ return boost::system::error_code(
+ WSAGetLastError(), boost::asio::error::get_system_category());
+#else
+ return boost::system::error_code(
+ errno, boost::asio::error::get_system_category());
+#endif
+ }
+}
+
+boost::system::error_code getaddrinfo(const char* host,
+ const char* service, const addrinfo_type& hints,
+ addrinfo_type** result, boost::system::error_code& ec)
+{
+ host = (host && *host) ? host : 0;
+ clear_last_error();
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
+ // Building for Windows XP, Windows Server 2003, or later.
+ int error = ::getaddrinfo(host, service, &hints, result);
+ return ec = translate_addrinfo_error(error);
+# else
+ // Building for Windows 2000 or earlier.
+ typedef int (WSAAPI *gai_t)(const char*,
+ const char*, const addrinfo_type*, addrinfo_type**);
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo"))
+ {
+ int error = gai(host, service, &hints, result);
+ return ec = translate_addrinfo_error(error);
+ }
+ }
+ int error = getaddrinfo_emulation(host, service, &hints, result);
+ return ec = translate_addrinfo_error(error);
+# endif
+#elif defined(__MACH__) && defined(__APPLE__)
+ int error = getaddrinfo_emulation(host, service, &hints, result);
+ return ec = translate_addrinfo_error(error);
+#else
+ int error = ::getaddrinfo(host, service, &hints, result);
+ return ec = translate_addrinfo_error(error);
+#endif
+}
+
+boost::system::error_code background_getaddrinfo(
+ const weak_cancel_token_type& cancel_token, const char* host,
+ const char* service, const addrinfo_type& hints,
+ addrinfo_type** result, boost::system::error_code& ec)
+{
+ if (cancel_token.expired())
+ ec = boost::asio::error::operation_aborted;
+ else
+ socket_ops::getaddrinfo(host, service, hints, result, ec);
+ return ec;
+}
+
+void freeaddrinfo(addrinfo_type* ai)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
+ // Building for Windows XP, Windows Server 2003, or later.
+ ::freeaddrinfo(ai);
+# else
+ // Building for Windows 2000 or earlier.
+ typedef int (WSAAPI *fai_t)(addrinfo_type*);
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo"))
+ {
+ fai(ai);
+ return;
+ }
+ }
+ freeaddrinfo_emulation(ai);
+# endif
+#elif defined(__MACH__) && defined(__APPLE__)
+ freeaddrinfo_emulation(ai);
+#else
+ ::freeaddrinfo(ai);
+#endif
+}
+
+boost::system::error_code getnameinfo(const socket_addr_type* addr,
+ std::size_t addrlen, char* host, std::size_t hostlen,
+ char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
+{
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
+ // Building for Windows XP, Windows Server 2003, or later.
+ clear_last_error();
+ int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen),
+ host, static_cast<DWORD>(hostlen),
+ serv, static_cast<DWORD>(servlen), flags);
+ return ec = translate_addrinfo_error(error);
+# else
+ // Building for Windows 2000 or earlier.
+ typedef int (WSAAPI *gni_t)(const socket_addr_type*,
+ int, char*, DWORD, char*, DWORD, int);
+ if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
+ {
+ if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
+ {
+ clear_last_error();
+ int error = gni(addr, static_cast<int>(addrlen),
+ host, static_cast<DWORD>(hostlen),
+ serv, static_cast<DWORD>(servlen), flags);
+ return ec = translate_addrinfo_error(error);
+ }
+ }
+ clear_last_error();
+ return getnameinfo_emulation(addr, addrlen,
+ host, hostlen, serv, servlen, flags, ec);
+# endif
+#elif defined(__MACH__) && defined(__APPLE__)
+ using namespace std; // For memcpy.
+ sockaddr_storage_type tmp_addr;
+ memcpy(&tmp_addr, addr, addrlen);
+ tmp_addr.ss_len = addrlen;
+ addr = reinterpret_cast<socket_addr_type*>(&tmp_addr);
+ clear_last_error();
+ return getnameinfo_emulation(addr, addrlen,
+ host, hostlen, serv, servlen, flags, ec);
+#else
+ clear_last_error();
+ int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
+ return ec = translate_addrinfo_error(error);
+#endif
+}
+
+boost::system::error_code sync_getnameinfo(
+ const socket_addr_type* addr, std::size_t addrlen,
+ char* host, std::size_t hostlen, char* serv,
+ std::size_t servlen, int sock_type, boost::system::error_code& ec)
+{
+ // First try resolving with the service name. If that fails try resolving
+ // but allow the service to be returned as a number.
+ int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
+ socket_ops::getnameinfo(addr, addrlen, host,
+ hostlen, serv, servlen, flags, ec);
+ if (ec)
+ {
+ socket_ops::getnameinfo(addr, addrlen, host, hostlen,
+ serv, servlen, flags | NI_NUMERICSERV, ec);
+ }
+
+ return ec;
+}
+
+boost::system::error_code background_getnameinfo(
+ const weak_cancel_token_type& cancel_token,
+ const socket_addr_type* addr, std::size_t addrlen,
+ char* host, std::size_t hostlen, char* serv,
+ std::size_t servlen, int sock_type, boost::system::error_code& ec)
+{
+ if (cancel_token.expired())
+ {
+ ec = boost::asio::error::operation_aborted;
+ }
+ else
+ {
+ // First try resolving with the service name. If that fails try resolving
+ // but allow the service to be returned as a number.
+ int flags = (sock_type == SOCK_DGRAM) ? NI_DGRAM : 0;
+ socket_ops::getnameinfo(addr, addrlen, host,
+ hostlen, serv, servlen, flags, ec);
+ if (ec)
+ {
+ socket_ops::getnameinfo(addr, addrlen, host, hostlen,
+ serv, servlen, flags | NI_NUMERICSERV, ec);
+ }
+ }
+
+ return ec;
+}
+
+u_long_type network_to_host_long(u_long_type value)
+{
+ return ntohl(value);
+}
+
+u_long_type host_to_network_long(u_long_type value)
+{
+ return htonl(value);
+}
+
+u_short_type network_to_host_short(u_short_type value)
+{
+ return ntohs(value);
+}
+
+u_short_type host_to_network_short(u_short_type value)
+{
+ return htons(value);
+}
+
+} // namespace socket_ops
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_IPP

Added: trunk/boost/asio/detail/impl/socket_select_interrupter.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/socket_select_interrupter.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,149 @@
+//
+// detail/impl/socket_select_interrupter.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_SOCKET_SELECT_INTERRUPTER_IPP
+#define BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#include <cstdlib>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/socket_select_interrupter.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+socket_select_interrupter::socket_select_interrupter()
+{
+ boost::system::error_code ec;
+ socket_holder acceptor(socket_ops::socket(
+ AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
+ if (acceptor.get() == invalid_socket)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ int opt = 1;
+ socket_ops::state_type acceptor_state = 0;
+ socket_ops::setsockopt(acceptor.get(), acceptor_state,
+ SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec);
+
+ using namespace std; // For memset.
+ sockaddr_in4_type addr;
+ std::size_t addr_len = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ addr.sin_port = 0;
+ if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
+ addr_len, ec) == socket_error_retval)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
+ &addr_len, ec) == socket_error_retval)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ // Some broken firewalls on Windows will intermittently cause getsockname to
+ // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We
+ // explicitly specify the target address here to work around this problem.
+ addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+
+ if (socket_ops::listen(acceptor.get(),
+ SOMAXCONN, ec) == socket_error_retval)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ socket_holder client(socket_ops::socket(
+ AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
+ if (client.get() == invalid_socket)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
+ addr_len, ec) == socket_error_retval)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));
+ if (server.get() == invalid_socket)
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ ioctl_arg_type non_blocking = 1;
+ socket_ops::state_type client_state = 0;
+ if (socket_ops::ioctl(client.get(), client_state,
+ FIONBIO, &non_blocking, ec))
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ opt = 1;
+ socket_ops::setsockopt(client.get(), client_state,
+ IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
+
+ non_blocking = 1;
+ socket_ops::state_type server_state = 0;
+ if (socket_ops::ioctl(server.get(), server_state,
+ FIONBIO, &non_blocking, ec))
+ boost::asio::detail::throw_error(ec, "socket_select_interrupter");
+
+ opt = 1;
+ socket_ops::setsockopt(server.get(), server_state,
+ IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
+
+ read_descriptor_ = server.release();
+ write_descriptor_ = client.release();
+}
+
+socket_select_interrupter::~socket_select_interrupter()
+{
+ boost::system::error_code ec;
+ socket_ops::state_type state = socket_ops::internal_non_blocking;
+ if (read_descriptor_ != invalid_socket)
+ socket_ops::close(read_descriptor_, state, true, ec);
+ if (write_descriptor_ != invalid_socket)
+ socket_ops::close(write_descriptor_, state, true, ec);
+}
+
+void socket_select_interrupter::interrupt()
+{
+ char byte = 0;
+ socket_ops::buf b;
+ socket_ops::init_buf(b, &byte, 1);
+ boost::system::error_code ec;
+ socket_ops::send(write_descriptor_, &b, 1, 0, ec);
+}
+
+bool socket_select_interrupter::reset()
+{
+ char data[1024];
+ socket_ops::buf b;
+ socket_ops::init_buf(b, data, sizeof(data));
+ boost::system::error_code ec;
+ int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
+ bool was_interrupted = (bytes_read > 0);
+ while (bytes_read == sizeof(data))
+ bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
+ return was_interrupted;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_SOCKET_SELECT_INTERRUPTER_IPP

Added: trunk/boost/asio/detail/impl/strand_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/strand_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,142 @@
+//
+// detail/impl/strand_service.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_IMPL_STRAND_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#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/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+inline strand_service::strand_impl::strand_impl()
+ : operation(&strand_service::do_complete),
+ count_(0)
+{
+}
+
+struct strand_service::on_dispatch_exit
+{
+ io_service_impl* io_service_;
+ strand_impl* impl_;
+
+ ~on_dispatch_exit()
+ {
+ impl_->mutex_.lock();
+ bool more_handlers = (--impl_->count_ > 0);
+ impl_->mutex_.unlock();
+
+ if (more_handlers)
+ io_service_->post_immediate_completion(impl_);
+ }
+};
+
+inline void strand_service::destroy(strand_service::implementation_type& impl)
+{
+ impl = 0;
+}
+
+template <typename Handler>
+void strand_service::dispatch(strand_service::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;
+ }
+
+ // Allocate and construct an operation to wrap the handler.
+ typedef completion_handler<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(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)
+ {
+ // Immediate invocation is allowed.
+ impl->mutex_.unlock();
+
+ // Memory must be releaesed before any upcall is made.
+ p.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(p.p);
+ impl->mutex_.unlock();
+ p.v = p.p = 0;
+
+ // 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.
+template <typename Handler>
+void strand_service::post(strand_service::implementation_type& impl,
+ Handler handler)
+{
+ // Allocate and construct an operation to wrap the handler.
+ typedef completion_handler<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
+
+ // Add the handler to the queue.
+ impl->mutex_.lock();
+ bool first = (++impl->count_ == 1);
+ impl->queue_.push(p.p);
+ impl->mutex_.unlock();
+ p.v = p.p = 0;
+
+ // The first handler to be enqueue is responsible for scheduling the strand.
+ if (first)
+ io_service_.post_immediate_completion(impl);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_HPP

Added: trunk/boost/asio/detail/impl/strand_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/strand_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,108 @@
+//
+// detail/impl/strand_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_STRAND_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/call_stack.hpp>
+#include <boost/asio/detail/strand_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+struct strand_service::on_do_complete_exit
+{
+ io_service_impl* owner_;
+ strand_impl* impl_;
+
+ ~on_do_complete_exit()
+ {
+ impl_->mutex_.lock();
+ bool more_handlers = (--impl_->count_ > 0);
+ impl_->mutex_.unlock();
+
+ if (more_handlers)
+ owner_->post_immediate_completion(impl_);
+ }
+};
+
+strand_service::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)
+{
+}
+
+void strand_service::shutdown_service()
+{
+ op_queue<operation> ops;
+
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ for (std::size_t i = 0; i < num_implementations; ++i)
+ if (strand_impl* impl = implementations_[i].get())
+ ops.push(impl->queue_);
+}
+
+void strand_service::construct(strand_service::implementation_type& impl)
+{
+ std::size_t salt = salt_++;
+ std::size_t index = reinterpret_cast<std::size_t>(&impl);
+ index += (reinterpret_cast<std::size_t>(&impl) >> 3);
+ index ^= salt + 0x9e3779b9 + (index << 6) + (index >> 2);
+ index = index % num_implementations;
+
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+
+ if (!implementations_[index])
+ implementations_[index].reset(new strand_impl);
+ impl = implementations_[index].get();
+}
+
+void strand_service::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);
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_STRAND_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/task_io_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/task_io_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,62 @@
+//
+// detail/impl/task_io_service.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_IMPL_TASK_IO_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#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/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+void task_io_service::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);
+}
+
+template <typename Handler>
+void task_io_service::post(Handler handler)
+{
+ // Allocate and construct an operation to wrap the handler.
+ typedef completion_handler<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
+
+ post_immediate_completion(p.p);
+ p.v = p.p = 0;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_HPP

Added: trunk/boost/asio/detail/impl/task_io_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/task_io_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,356 @@
+//
+// detail/impl/task_io_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_TASK_IO_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/limits.hpp>
+#include <boost/asio/detail/call_stack.hpp>
+#include <boost/asio/detail/event.hpp>
+#include <boost/asio/detail/reactor.hpp>
+#include <boost/asio/detail/task_io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+struct task_io_service::task_cleanup
+{
+ ~task_cleanup()
+ {
+ // 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_);
+ }
+
+ task_io_service* task_io_service_;
+ mutex::scoped_lock* lock_;
+ op_queue<operation>* ops_;
+};
+
+struct task_io_service::work_finished_on_block_exit
+{
+ ~work_finished_on_block_exit()
+ {
+ task_io_service_->work_finished();
+ }
+
+ task_io_service* task_io_service_;
+};
+
+struct task_io_service::idle_thread_info
+{
+ event wakeup_event;
+ idle_thread_info* next;
+};
+
+task_io_service::task_io_service(boost::asio::io_service& io_service)
+ : boost::asio::detail::service_base<task_io_service>(io_service),
+ mutex_(),
+ task_(0),
+ task_interrupted_(true),
+ outstanding_work_(0),
+ stopped_(false),
+ shutdown_(false),
+ first_idle_thread_(0)
+{
+}
+
+void task_io_service::init(std::size_t /*concurrency_hint*/)
+{
+}
+
+void task_io_service::shutdown_service()
+{
+ mutex::scoped_lock lock(mutex_);
+ shutdown_ = true;
+ lock.unlock();
+
+ // Destroy handler objects.
+ while (!op_queue_.empty())
+ {
+ operation* o = op_queue_.front();
+ op_queue_.pop();
+ if (o != &task_operation_)
+ o->destroy();
+ }
+
+ // Reset to initial state.
+ task_ = 0;
+}
+
+void task_io_service::init_task()
+{
+ mutex::scoped_lock lock(mutex_);
+ if (!shutdown_ && !task_)
+ {
+ task_ = &use_service<reactor>(this->get_io_service());
+ op_queue_.push(&task_operation_);
+ wake_one_thread_and_unlock(lock);
+ }
+}
+
+std::size_t task_io_service::run(boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ if (outstanding_work_ == 0)
+ {
+ stop();
+ return 0;
+ }
+
+ call_stack<task_io_service>::context ctx(this);
+
+ idle_thread_info this_idle_thread;
+ this_idle_thread.next = 0;
+
+ mutex::scoped_lock lock(mutex_);
+
+ std::size_t n = 0;
+ for (; do_one(lock, &this_idle_thread); lock.lock())
+ if (n != (std::numeric_limits<std::size_t>::max)())
+ ++n;
+ return n;
+}
+
+std::size_t task_io_service::run_one(boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ if (outstanding_work_ == 0)
+ {
+ stop();
+ return 0;
+ }
+
+ call_stack<task_io_service>::context ctx(this);
+
+ idle_thread_info this_idle_thread;
+ this_idle_thread.next = 0;
+
+ mutex::scoped_lock lock(mutex_);
+
+ return do_one(lock, &this_idle_thread);
+}
+
+std::size_t task_io_service::poll(boost::system::error_code& ec)
+{
+ if (outstanding_work_ == 0)
+ {
+ stop();
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ call_stack<task_io_service>::context ctx(this);
+
+ mutex::scoped_lock lock(mutex_);
+
+ std::size_t n = 0;
+ for (; do_one(lock, 0); lock.lock())
+ if (n != (std::numeric_limits<std::size_t>::max)())
+ ++n;
+ return n;
+}
+
+std::size_t task_io_service::poll_one(boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ if (outstanding_work_ == 0)
+ {
+ stop();
+ return 0;
+ }
+
+ call_stack<task_io_service>::context ctx(this);
+
+ mutex::scoped_lock lock(mutex_);
+
+ return do_one(lock, 0);
+}
+
+void task_io_service::stop()
+{
+ mutex::scoped_lock lock(mutex_);
+ stop_all_threads(lock);
+}
+
+void task_io_service::reset()
+{
+ mutex::scoped_lock lock(mutex_);
+ stopped_ = false;
+}
+
+void task_io_service::post_immediate_completion(task_io_service::operation* op)
+{
+ work_started();
+ post_deferred_completion(op);
+}
+
+void task_io_service::post_deferred_completion(task_io_service::operation* op)
+{
+ mutex::scoped_lock lock(mutex_);
+ op_queue_.push(op);
+ wake_one_thread_and_unlock(lock);
+}
+
+void task_io_service::post_deferred_completions(
+ op_queue<task_io_service::operation>& ops)
+{
+ if (!ops.empty())
+ {
+ mutex::scoped_lock lock(mutex_);
+ op_queue_.push(ops);
+ wake_one_thread_and_unlock(lock);
+ }
+}
+
+std::size_t task_io_service::do_one(mutex::scoped_lock& lock,
+ task_io_service::idle_thread_info* this_idle_thread)
+{
+ bool polling = !this_idle_thread;
+ bool task_has_run = false;
+ while (!stopped_)
+ {
+ if (!op_queue_.empty())
+ {
+ // Prepare to execute first handler from queue.
+ operation* o = op_queue_.front();
+ op_queue_.pop();
+ bool more_handlers = (!op_queue_.empty());
+
+ if (o == &task_operation_)
+ {
+ 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;
+ op_queue_.push(&task_operation_);
+ return 0;
+ }
+ task_has_run = true;
+
+ if (!more_handlers || !wake_one_idle_thread_and_unlock(lock))
+ 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
+ {
+ 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;
+
+ // Complete the operation. May throw an exception.
+ o->complete(*this); // deletes the operation object
+
+ return 1;
+ }
+ }
+ else if (this_idle_thread)
+ {
+ // Nothing to run right now, so just wait for work to do.
+ this_idle_thread->next = first_idle_thread_;
+ first_idle_thread_ = this_idle_thread;
+ this_idle_thread->wakeup_event.clear(lock);
+ this_idle_thread->wakeup_event.wait(lock);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+void task_io_service::stop_all_threads(
+ mutex::scoped_lock& lock)
+{
+ stopped_ = true;
+
+ 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;
+ task_->interrupt();
+ }
+}
+
+bool task_io_service::wake_one_idle_thread_and_unlock(
+ mutex::scoped_lock& lock)
+{
+ if (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_and_unlock(lock);
+ return true;
+ }
+ return false;
+}
+
+void task_io_service::wake_one_thread_and_unlock(
+ mutex::scoped_lock& lock)
+{
+ if (!wake_one_idle_thread_and_unlock(lock))
+ {
+ if (!task_interrupted_ && task_)
+ {
+ task_interrupted_ = true;
+ task_->interrupt();
+ }
+ lock.unlock();
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_TASK_IO_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/throw_error.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/throw_error.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,47 @@
+//
+// detail/impl/throw_error.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_THROW_ERROR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_THROW_ERROR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+void do_throw_error(const boost::system::error_code& err)
+{
+ boost::system::system_error e(err);
+ boost::throw_exception(e);
+}
+
+void do_throw_error(const boost::system::error_code& err, const char* location)
+{
+ boost::system::system_error e(err, location);
+ boost::throw_exception(e);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_THROW_ERROR_IPP

Added: trunk/boost/asio/detail/impl/timer_queue.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/timer_queue.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,87 @@
+//
+// detail/impl/timer_queue.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_TIMER_QUEUE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HEADER_ONLY)
+
+#include <boost/asio/detail/timer_queue.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+timer_queue<time_traits<boost::posix_time::ptime> >::timer_queue()
+{
+}
+
+timer_queue<time_traits<boost::posix_time::ptime> >::~timer_queue()
+{
+}
+
+bool timer_queue<time_traits<boost::posix_time::ptime> >::enqueue_timer(
+ const time_type& time, timer_op* op, void* token)
+{
+ return impl_.enqueue_timer(time, op, token);
+}
+
+bool timer_queue<time_traits<boost::posix_time::ptime> >::empty() const
+{
+ return impl_.empty();
+}
+
+long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_msec(
+ long max_duration) const
+{
+ return impl_.wait_duration_msec(max_duration);
+}
+
+long timer_queue<time_traits<boost::posix_time::ptime> >::wait_duration_usec(
+ long max_duration) const
+{
+ return impl_.wait_duration_usec(max_duration);
+}
+
+void timer_queue<time_traits<boost::posix_time::ptime> >::get_ready_timers(
+ op_queue<operation>& ops)
+{
+ impl_.get_ready_timers(ops);
+}
+
+void timer_queue<time_traits<boost::posix_time::ptime> >::get_all_timers(
+ op_queue<operation>& ops)
+{
+ impl_.get_all_timers(ops);
+}
+
+std::size_t timer_queue<time_traits<boost::posix_time::ptime> >::cancel_timer(
+ void* timer_token, op_queue<operation>& ops)
+{
+ return impl_.cancel_timer(timer_token, ops);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_IPP

Added: trunk/boost/asio/detail/impl/timer_queue_set.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/timer_queue_set.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,103 @@
+//
+// detail/impl/timer_queue_set.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_TIMER_QUEUE_SET_IPP
+#define BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/timer_queue_set.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+timer_queue_set::timer_queue_set()
+ : first_(0)
+{
+}
+
+void timer_queue_set::insert(timer_queue_base* q)
+{
+ q->next_ = first_;
+ first_ = q;
+}
+
+void timer_queue_set::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;
+ }
+ }
+ }
+}
+
+bool timer_queue_set::all_empty() const
+{
+ for (timer_queue_base* p = first_; p; p = p->next_)
+ if (!p->empty())
+ return false;
+ return true;
+}
+
+long timer_queue_set::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;
+}
+
+long timer_queue_set::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;
+}
+
+void timer_queue_set::get_ready_timers(op_queue<operation>& ops)
+{
+ for (timer_queue_base* p = first_; p; p = p->next_)
+ p->get_ready_timers(ops);
+}
+
+void timer_queue_set::get_all_timers(op_queue<operation>& ops)
+{
+ for (timer_queue_base* p = first_; p; p = p->next_)
+ p->get_all_timers(ops);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IMPL_TIMER_QUEUE_SET_IPP

Added: trunk/boost/asio/detail/impl/win_event.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_event.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,52 @@
+//
+// detail/win_event.ipp
+// ~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_EVENT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS)
+
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_event.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_event::win_event()
+ : event_(::CreateEvent(0, true, false, 0))
+{
+ if (!event_)
+ {
+ DWORD last_error = ::GetLastError();
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "event");
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_EVENT_IPP

Added: trunk/boost/asio/detail/impl/win_iocp_handle_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_iocp_handle_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,454 @@
+//
+// detail/impl/win_iocp_handle_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class win_iocp_handle_service::overlapped_wrapper
+ : public OVERLAPPED
+{
+public:
+ explicit overlapped_wrapper(boost::system::error_code& ec)
+ {
+ Internal = 0;
+ InternalHigh = 0;
+ Offset = 0;
+ OffsetHigh = 0;
+
+ // Create a non-signalled manual-reset event, for GetOverlappedResult.
+ hEvent = ::CreateEvent(0, TRUE, FALSE, 0);
+ if (hEvent)
+ {
+ // As documented in GetQueuedCompletionStatus, setting the low order
+ // bit of this event prevents our synchronous writes from being treated
+ // as completion port events.
+ *reinterpret_cast<DWORD_PTR*>(&hEvent) |= 1;
+ }
+ else
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ }
+
+ ~overlapped_wrapper()
+ {
+ if (hEvent)
+ {
+ ::CloseHandle(hEvent);
+ }
+ }
+};
+
+win_iocp_handle_service::win_iocp_handle_service(
+ boost::asio::io_service& io_service)
+ : iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)),
+ mutex_(),
+ impl_list_(0)
+{
+}
+
+void win_iocp_handle_service::shutdown_service()
+{
+ // Close all implementations, causing all operations to complete.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ implementation_type* impl = impl_list_;
+ while (impl)
+ {
+ close_for_destruction(*impl);
+ impl = impl->next_;
+ }
+}
+
+void win_iocp_handle_service::construct(
+ win_iocp_handle_service::implementation_type& impl)
+{
+ impl.handle_ = INVALID_HANDLE_VALUE;
+ impl.safe_cancellation_thread_id_ = 0;
+
+ // Insert implementation into linked list of all implementations.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ impl.next_ = impl_list_;
+ impl.prev_ = 0;
+ if (impl_list_)
+ impl_list_->prev_ = &impl;
+ impl_list_ = &impl;
+}
+
+void win_iocp_handle_service::destroy(
+ win_iocp_handle_service::implementation_type& impl)
+{
+ close_for_destruction(impl);
+
+ // Remove implementation from linked list of all implementations.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (impl_list_ == &impl)
+ impl_list_ = impl.next_;
+ if (impl.prev_)
+ impl.prev_->next_ = impl.next_;
+ if (impl.next_)
+ impl.next_->prev_= impl.prev_;
+ impl.next_ = 0;
+ impl.prev_ = 0;
+}
+
+boost::system::error_code win_iocp_handle_service::assign(
+ win_iocp_handle_service::implementation_type& impl,
+ const native_type& native_handle, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ if (iocp_service_.register_handle(native_handle, ec))
+ return ec;
+
+ impl.handle_ = native_handle;
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code win_iocp_handle_service::close(
+ win_iocp_handle_service::implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ if (!::CloseHandle(impl.handle_))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ impl.handle_ = INVALID_HANDLE_VALUE;
+ impl.safe_cancellation_thread_id_ = 0;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code win_iocp_handle_service::cancel(
+ win_iocp_handle_service::implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ }
+ else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
+ ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
+ {
+ // The version of Windows supports cancellation from any thread.
+ typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
+ cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
+ if (!cancel_io_ex(impl.handle_, 0))
+ {
+ DWORD last_error = ::GetLastError();
+ if (last_error == ERROR_NOT_FOUND)
+ {
+ // ERROR_NOT_FOUND means that there were no operations to be
+ // cancelled. We swallow this error to match the behaviour on other
+ // platforms.
+ ec = boost::system::error_code();
+ }
+ else
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+ }
+ else if (impl.safe_cancellation_thread_id_ == 0)
+ {
+ // No operations have been started, so there's nothing to cancel.
+ ec = boost::system::error_code();
+ }
+ else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId())
+ {
+ // Asynchronous operations have been started from the current thread only,
+ // so it is safe to try to cancel them using CancelIo.
+ if (!::CancelIo(impl.handle_))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+ }
+ else
+ {
+ // Asynchronous operations have been started from more than one thread,
+ // so cancellation is not safe.
+ ec = boost::asio::error::operation_not_supported;
+ }
+
+ return ec;
+}
+
+size_t win_iocp_handle_service::do_write(
+ win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset,
+ const boost::asio::const_buffer& buffer, boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to write 0 bytes on a handle is a no-op.
+ if (boost::asio::buffer_size(buffer) == 0)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ overlapped_wrapper overlapped(ec);
+ if (ec)
+ {
+ return 0;
+ }
+
+ // Write the data.
+ overlapped.Offset = offset & 0xFFFFFFFF;
+ overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
+ BOOL ok = ::WriteFile(impl.handle_,
+ boost::asio::buffer_cast<LPCVOID>(buffer),
+ static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
+ if (!ok)
+ {
+ DWORD last_error = ::GetLastError();
+ if (last_error != ERROR_IO_PENDING)
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return 0;
+ }
+ }
+
+ // Wait for the operation to complete.
+ DWORD bytes_transferred = 0;
+ ok = ::GetOverlappedResult(impl.handle_,
+ &overlapped, &bytes_transferred, TRUE);
+ if (!ok)
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return 0;
+ }
+
+ ec = boost::system::error_code();
+ return bytes_transferred;
+}
+
+void win_iocp_handle_service::start_write_op(
+ win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset,
+ const boost::asio::const_buffer& buffer, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ 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);
+ }
+ }
+}
+
+size_t win_iocp_handle_service::do_read(
+ win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset,
+ const boost::asio::mutable_buffer& buffer, boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return 0;
+ }
+
+ // A request to read 0 bytes on a stream handle is a no-op.
+ if (boost::asio::buffer_size(buffer) == 0)
+ {
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ overlapped_wrapper overlapped(ec);
+ if (ec)
+ {
+ return 0;
+ }
+
+ // Read some data.
+ overlapped.Offset = offset & 0xFFFFFFFF;
+ overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
+ BOOL ok = ::ReadFile(impl.handle_,
+ boost::asio::buffer_cast<LPVOID>(buffer),
+ static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
+ if (!ok)
+ {
+ DWORD last_error = ::GetLastError();
+ if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
+ {
+ if (last_error == ERROR_HANDLE_EOF)
+ {
+ ec = boost::asio::error::eof;
+ }
+ else
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ return 0;
+ }
+ }
+
+ // Wait for the operation to complete.
+ DWORD bytes_transferred = 0;
+ ok = ::GetOverlappedResult(impl.handle_,
+ &overlapped, &bytes_transferred, TRUE);
+ if (!ok)
+ {
+ DWORD last_error = ::GetLastError();
+ if (last_error == ERROR_HANDLE_EOF)
+ {
+ ec = boost::asio::error::eof;
+ }
+ else
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ return 0;
+ }
+
+ ec = boost::system::error_code();
+ return bytes_transferred;
+}
+
+void win_iocp_handle_service::start_read_op(
+ win_iocp_handle_service::implementation_type& impl, boost::uint64_t offset,
+ const boost::asio::mutable_buffer& buffer, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ 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);
+ }
+ }
+}
+
+void win_iocp_handle_service::update_cancellation_thread_id(
+ win_iocp_handle_service::implementation_type& impl)
+{
+ 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);
+}
+
+void win_iocp_handle_service::close_for_destruction(implementation_type& impl)
+{
+ if (is_open(impl))
+ {
+ ::CloseHandle(impl.handle_);
+ impl.handle_ = INVALID_HANDLE_VALUE;
+ impl.safe_cancellation_thread_id_ = 0;
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_HANDLE_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/win_iocp_io_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_iocp_io_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,113 @@
+//
+// detail/impl/win_iocp_io_service.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_IMPL_WIN_IOCP_IO_SERVICE_HPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#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/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+void win_iocp_io_service::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);
+}
+
+template <typename Handler>
+void win_iocp_io_service::post(Handler handler)
+{
+ // Allocate and construct an operation to wrap the handler.
+ typedef completion_handler<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
+
+ post_immediate_completion(p.p);
+ p.v = p.p = 0;
+}
+
+template <typename Time_Traits>
+void win_iocp_io_service::add_timer_queue(
+ timer_queue<Time_Traits>& queue)
+{
+ do_add_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void win_iocp_io_service::remove_timer_queue(
+ timer_queue<Time_Traits>& queue)
+{
+ do_remove_timer_queue(queue);
+}
+
+template <typename Time_Traits>
+void win_iocp_io_service::schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token)
+{
+ // If the service has been shut down we silently discard the timer.
+ if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
+ return;
+
+ mutex::scoped_lock lock(dispatch_mutex_);
+
+ bool earliest = queue.enqueue_timer(time, op, token);
+ work_started();
+ if (earliest)
+ update_timeout();
+}
+
+template <typename Time_Traits>
+std::size_t win_iocp_io_service::cancel_timer(
+ timer_queue<Time_Traits>& queue, void* token)
+{
+ // If the service has been shut down we silently ignore the cancellation.
+ if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
+ return 0;
+
+ mutex::scoped_lock lock(dispatch_mutex_);
+ op_queue<win_iocp_operation> ops;
+ std::size_t n = queue.cancel_timer(token, ops);
+ post_deferred_completions(ops);
+ return n;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_HPP

Added: trunk/boost/asio/detail/impl/win_iocp_io_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_iocp_io_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,493 @@
+//
+// detail/impl/win_iocp_io_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_IOCP_IO_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/limits.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_iocp_io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+struct win_iocp_io_service::work_finished_on_block_exit
+{
+ ~work_finished_on_block_exit()
+ {
+ io_service_->work_finished();
+ }
+
+ win_iocp_io_service* io_service_;
+};
+
+struct win_iocp_io_service::timer_thread_function
+{
+ void operator()()
+ {
+ while (::InterlockedExchangeAdd(&io_service_->shutdown_, 0) == 0)
+ {
+ if (::WaitForSingleObject(io_service_->waitable_timer_.handle,
+ INFINITE) == WAIT_OBJECT_0)
+ {
+ ::InterlockedExchange(&io_service_->dispatch_required_, 1);
+ ::PostQueuedCompletionStatus(io_service_->iocp_.handle,
+ 0, wake_for_dispatch, 0);
+ }
+ }
+ }
+
+ win_iocp_io_service* io_service_;
+};
+
+win_iocp_io_service::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),
+ stopped_(0),
+ shutdown_(0),
+ dispatch_required_(0)
+{
+}
+
+void win_iocp_io_service::init(size_t concurrency_hint)
+{
+ iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,
+ static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0))));
+ if (!iocp_.handle)
+ {
+ DWORD last_error = ::GetLastError();
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "iocp");
+ }
+}
+
+void win_iocp_io_service::shutdown_service()
+{
+ ::InterlockedExchange(&shutdown_, 1);
+
+ if (timer_thread_)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = 1;
+ ::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE);
+ }
+
+ while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0)
+ {
+ op_queue<win_iocp_operation> ops;
+ timer_queues_.get_all_timers(ops);
+ ops.push(completed_ops_);
+ if (!ops.empty())
+ {
+ while (win_iocp_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, gqcs_timeout);
+ if (overlapped)
+ {
+ ::InterlockedDecrement(&outstanding_work_);
+ static_cast<win_iocp_operation*>(overlapped)->destroy();
+ }
+ }
+ }
+
+ if (timer_thread_)
+ timer_thread_->join();
+}
+
+boost::system::error_code win_iocp_io_service::register_handle(
+ HANDLE handle, boost::system::error_code& ec)
+{
+ if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0)
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+ return ec;
+}
+
+size_t win_iocp_io_service::run(boost::system::error_code& ec)
+{
+ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
+ {
+ stop();
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ call_stack<win_iocp_io_service>::context ctx(this);
+
+ size_t n = 0;
+ while (do_one(true, ec))
+ if (n != (std::numeric_limits<size_t>::max)())
+ ++n;
+ return n;
+}
+
+size_t win_iocp_io_service::run_one(boost::system::error_code& ec)
+{
+ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
+ {
+ stop();
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ call_stack<win_iocp_io_service>::context ctx(this);
+
+ return do_one(true, ec);
+}
+
+size_t win_iocp_io_service::poll(boost::system::error_code& ec)
+{
+ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
+ {
+ stop();
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ call_stack<win_iocp_io_service>::context ctx(this);
+
+ size_t n = 0;
+ while (do_one(false, ec))
+ if (n != (std::numeric_limits<size_t>::max)())
+ ++n;
+ return n;
+}
+
+size_t win_iocp_io_service::poll_one(boost::system::error_code& ec)
+{
+ if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
+ {
+ stop();
+ ec = boost::system::error_code();
+ return 0;
+ }
+
+ call_stack<win_iocp_io_service>::context ctx(this);
+
+ return do_one(false, ec);
+}
+
+void win_iocp_io_service::stop()
+{
+ if (::InterlockedExchange(&stopped_, 1) == 0)
+ {
+ if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
+ {
+ DWORD last_error = ::GetLastError();
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "pqcs");
+ }
+ }
+}
+
+void win_iocp_io_service::post_deferred_completion(win_iocp_operation* op)
+{
+ // 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.
+ mutex::scoped_lock lock(dispatch_mutex_);
+ completed_ops_.push(op);
+ ::InterlockedExchange(&dispatch_required_, 1);
+ }
+}
+
+void win_iocp_io_service::post_deferred_completions(
+ op_queue<win_iocp_operation>& ops)
+{
+ while (win_iocp_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.
+ mutex::scoped_lock lock(dispatch_mutex_);
+ completed_ops_.push(op);
+ completed_ops_.push(ops);
+ ::InterlockedExchange(&dispatch_required_, 1);
+ }
+ }
+}
+
+void win_iocp_io_service::on_pending(win_iocp_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.
+ mutex::scoped_lock lock(dispatch_mutex_);
+ completed_ops_.push(op);
+ ::InterlockedExchange(&dispatch_required_, 1);
+ }
+ }
+}
+
+void win_iocp_io_service::on_completion(win_iocp_operation* op,
+ DWORD last_error, DWORD bytes_transferred)
+{
+ // 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,
+ 0, overlapped_contains_result, op))
+ {
+ // Out of resources. Put on completed queue instead.
+ mutex::scoped_lock lock(dispatch_mutex_);
+ completed_ops_.push(op);
+ ::InterlockedExchange(&dispatch_required_, 1);
+ }
+}
+
+void win_iocp_io_service::on_completion(win_iocp_operation* op,
+ const boost::system::error_code& ec, DWORD bytes_transferred)
+{
+ // 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.
+ mutex::scoped_lock lock(dispatch_mutex_);
+ completed_ops_.push(op);
+ ::InterlockedExchange(&dispatch_required_, 1);
+ }
+}
+
+size_t win_iocp_io_service::do_one(bool block, boost::system::error_code& ec)
+{
+ for (;;)
+ {
+ // Try to acquire responsibility for dispatching timers and completed ops.
+ if (::InterlockedCompareExchange(&dispatch_required_, 0, 1) == 1)
+ {
+ mutex::scoped_lock lock(dispatch_mutex_);
+
+ // Dispatch pending timers and operations.
+ op_queue<win_iocp_operation> ops;
+ ops.push(completed_ops_);
+ timer_queues_.get_ready_timers(ops);
+ post_deferred_completions(ops);
+ update_timeout();
+ }
+
+ // Get the next operation from the queue.
+ DWORD bytes_transferred = 0;
+ dword_ptr_t completion_key = 0;
+ LPOVERLAPPED overlapped = 0;
+ ::SetLastError(0);
+ BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
+ &completion_key, &overlapped, block ? gqcs_timeout : 0);
+ DWORD last_error = ::GetLastError();
+
+ if (overlapped)
+ {
+ win_iocp_operation* op = static_cast<win_iocp_operation*>(overlapped);
+ boost::system::error_code result_ec(last_error,
+ boost::asio::error::get_system_category());
+
+ // 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;
+ }
+
+ // 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;
+ }
+ }
+ else if (!ok)
+ {
+ if (last_error != WAIT_TIMEOUT)
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return 0;
+ }
+
+ // If we're not polling we need to keep going until we get a real handler.
+ if (block)
+ continue;
+
+ ec = boost::system::error_code();
+ return 0;
+ }
+ else if (completion_key == wake_for_dispatch)
+ {
+ // We have been woken up to try to acquire responsibility for dispatching
+ // timers and completed operations.
+ }
+ else
+ {
+ // The stopped_ flag is always checked to ensure that any leftover
+ // interrupts from a previous run invocation are ignored.
+ if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
+ {
+ // Wake up next thread that is blocked on GetQueuedCompletionStatus.
+ if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
+ {
+ last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return 0;
+ }
+
+ ec = boost::system::error_code();
+ return 0;
+ }
+ }
+ }
+}
+
+void win_iocp_io_service::do_add_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(dispatch_mutex_);
+
+ timer_queues_.insert(&queue);
+
+ if (!waitable_timer_.handle)
+ {
+ waitable_timer_.handle = ::CreateWaitableTimer(0, FALSE, 0);
+ if (waitable_timer_.handle == 0)
+ {
+ DWORD last_error = ::GetLastError();
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "timer");
+ }
+ }
+
+ if (!timer_thread_)
+ {
+ timer_thread_function thread_function = { this };
+ timer_thread_.reset(new thread(thread_function, 65536));
+ }
+}
+
+void win_iocp_io_service::do_remove_timer_queue(timer_queue_base& queue)
+{
+ mutex::scoped_lock lock(dispatch_mutex_);
+
+ timer_queues_.erase(&queue);
+}
+
+void win_iocp_io_service::update_timeout()
+{
+ if (timer_thread_)
+ {
+ // There's no point updating the waitable timer if the new timeout period
+ // exceeds the maximum timeout. In that case, we might as well wait for the
+ // existing period of the timer to expire.
+ long timeout_usec = timer_queues_.wait_duration_usec(max_timeout_usec);
+ if (timeout_usec < max_timeout_usec)
+ {
+ LARGE_INTEGER timeout;
+ timeout.QuadPart = -timeout_usec;
+ timeout.QuadPart *= 10;
+ ::SetWaitableTimer(waitable_timer_.handle,
+ &timeout, max_timeout_msec, 0, 0, FALSE);
+ }
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_IO_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/win_iocp_serial_port_service.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_iocp_serial_port_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,182 @@
+//
+// detail/impl/win_iocp_serial_port_service.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+#include <cstring>
+#include <boost/asio/detail/win_iocp_serial_port_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_iocp_serial_port_service::win_iocp_serial_port_service(
+ boost::asio::io_service& io_service)
+ : handle_service_(io_service)
+{
+}
+
+void win_iocp_serial_port_service::shutdown_service()
+{
+}
+
+boost::system::error_code win_iocp_serial_port_service::open(
+ win_iocp_serial_port_service::implementation_type& impl,
+ const std::string& device, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ // For convenience, add a leading \\.\ sequence if not already present.
+ std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
+
+ // Open a handle to the serial port.
+ ::HANDLE handle = ::CreateFileA(name.c_str(),
+ GENERIC_READ | GENERIC_WRITE, 0, 0,
+ OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
+ if (handle == INVALID_HANDLE_VALUE)
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ // Determine the initial serial port parameters.
+ using namespace std; // For memset.
+ ::DCB dcb;
+ memset(&dcb, 0, sizeof(DCB));
+ dcb.DCBlength = sizeof(DCB);
+ if (!::GetCommState(handle, &dcb))
+ {
+ DWORD last_error = ::GetLastError();
+ ::CloseHandle(handle);
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ // Set some default serial port parameters. This implementation does not
+ // support changing these, so they might as well be in a known state.
+ dcb.fBinary = TRUE; // Win32 only supports binary mode.
+ dcb.fDsrSensitivity = FALSE;
+ dcb.fNull = FALSE; // Do not ignore NULL characters.
+ dcb.fAbortOnError = FALSE; // Ignore serial framing errors.
+ if (!::SetCommState(handle, &dcb))
+ {
+ DWORD last_error = ::GetLastError();
+ ::CloseHandle(handle);
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ // Set up timeouts so that the serial port will behave similarly to a
+ // network socket. Reads wait for at least one byte, then return with
+ // whatever they have. Writes return once everything is out the door.
+ ::COMMTIMEOUTS timeouts;
+ timeouts.ReadIntervalTimeout = 1;
+ timeouts.ReadTotalTimeoutMultiplier = 0;
+ timeouts.ReadTotalTimeoutConstant = 0;
+ timeouts.WriteTotalTimeoutMultiplier = 0;
+ timeouts.WriteTotalTimeoutConstant = 0;
+ if (!::SetCommTimeouts(handle, &timeouts))
+ {
+ DWORD last_error = ::GetLastError();
+ ::CloseHandle(handle);
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ // We're done. Take ownership of the serial port handle.
+ if (handle_service_.assign(impl, handle, ec))
+ ::CloseHandle(handle);
+ return ec;
+}
+
+boost::system::error_code win_iocp_serial_port_service::do_set_option(
+ win_iocp_serial_port_service::implementation_type& impl,
+ win_iocp_serial_port_service::store_function_type store,
+ const void* option, boost::system::error_code& ec)
+{
+ using namespace std; // For memcpy.
+
+ ::DCB dcb;
+ memset(&dcb, 0, sizeof(DCB));
+ dcb.DCBlength = sizeof(DCB);
+ if (!::GetCommState(handle_service_.native(impl), &dcb))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ if (store(option, dcb, ec))
+ return ec;
+
+ if (!::SetCommState(handle_service_.native(impl), &dcb))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code win_iocp_serial_port_service::do_get_option(
+ const win_iocp_serial_port_service::implementation_type& impl,
+ win_iocp_serial_port_service::load_function_type load,
+ void* option, boost::system::error_code& ec) const
+{
+ using namespace std; // For memset.
+
+ ::DCB dcb;
+ memset(&dcb, 0, sizeof(DCB));
+ dcb.DCBlength = sizeof(DCB);
+ if (!::GetCommState(handle_service_.native(impl), &dcb))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ return ec;
+ }
+
+ return load(option, dcb, ec);
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SERIAL_PORT_SERVICE_IPP

Added: trunk/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_iocp_socket_service_base.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,567 @@
+//
+// detail/impl/win_iocp_socket_service_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/win_iocp_socket_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_iocp_socket_service_base::win_iocp_socket_service_base(
+ boost::asio::io_service& io_service)
+ : io_service_(io_service),
+ iocp_service_(use_service<win_iocp_io_service>(io_service)),
+ reactor_(0),
+ mutex_(),
+ impl_list_(0)
+{
+}
+
+void win_iocp_socket_service_base::shutdown_service()
+{
+ // Close all implementations, causing all operations to complete.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ base_implementation_type* impl = impl_list_;
+ while (impl)
+ {
+ boost::system::error_code ignored_ec;
+ close_for_destruction(*impl);
+ impl = impl->next_;
+ }
+}
+
+void win_iocp_socket_service_base::construct(
+ win_iocp_socket_service_base::base_implementation_type& impl)
+{
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+ impl.cancel_token_.reset();
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+ impl.safe_cancellation_thread_id_ = 0;
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+
+ // Insert implementation into linked list of all implementations.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ impl.next_ = impl_list_;
+ impl.prev_ = 0;
+ if (impl_list_)
+ impl_list_->prev_ = &impl;
+ impl_list_ = &impl;
+}
+
+void win_iocp_socket_service_base::destroy(
+ win_iocp_socket_service_base::base_implementation_type& impl)
+{
+ close_for_destruction(impl);
+
+ // Remove implementation from linked list of all implementations.
+ boost::asio::detail::mutex::scoped_lock lock(mutex_);
+ if (impl_list_ == &impl)
+ impl_list_ = impl.next_;
+ if (impl.prev_)
+ impl.prev_->next_ = impl.next_;
+ if (impl.next_)
+ impl.next_->prev_= impl.prev_;
+ impl.next_ = 0;
+ impl.prev_ = 0;
+}
+
+boost::system::error_code win_iocp_socket_service_base::close(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ // 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* r = static_cast<reactor*>(
+ interlocked_compare_exchange_pointer(
+ reinterpret_cast<void**>(&reactor_), 0, 0));
+ if (r)
+ r->close_descriptor(impl.socket_, impl.reactor_data_);
+ }
+
+ if (socket_ops::close(impl.socket_, impl.state_, false, ec) == 0)
+ {
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+ impl.cancel_token_.reset();
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+ impl.safe_cancellation_thread_id_ = 0;
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+ }
+
+ return ec;
+}
+
+boost::system::error_code win_iocp_socket_service_base::cancel(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ boost::system::error_code& ec)
+{
+ if (!is_open(impl))
+ {
+ ec = boost::asio::error::bad_descriptor;
+ return ec;
+ }
+ else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
+ ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
+ {
+ // The version of Windows supports cancellation from any thread.
+ typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
+ cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
+ socket_type sock = impl.socket_;
+ HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
+ if (!cancel_io_ex(sock_as_handle, 0))
+ {
+ DWORD last_error = ::GetLastError();
+ if (last_error == ERROR_NOT_FOUND)
+ {
+ // ERROR_NOT_FOUND means that there were no operations to be
+ // cancelled. We swallow this error to match the behaviour on other
+ // platforms.
+ ec = boost::system::error_code();
+ }
+ else
+ {
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+ }
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+ else if (impl.safe_cancellation_thread_id_ == 0)
+ {
+ // No operations have been started, so there's nothing to cancel.
+ ec = boost::system::error_code();
+ }
+ else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId())
+ {
+ // Asynchronous operations have been started from the current thread only,
+ // so it is safe to try to cancel them using CancelIo.
+ socket_type sock = impl.socket_;
+ HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
+ if (!::CancelIo(sock_as_handle))
+ {
+ DWORD last_error = ::GetLastError();
+ ec = boost::system::error_code(last_error,
+ boost::asio::error::get_system_category());
+ }
+ else
+ {
+ ec = boost::system::error_code();
+ }
+ }
+ else
+ {
+ // Asynchronous operations have been started from more than one thread,
+ // so cancellation is not safe.
+ ec = boost::asio::error::operation_not_supported;
+ }
+#else // defined(BOOST_ASIO_ENABLE_CANCELIO)
+ else
+ {
+ // Cancellation is not supported as CancelIo may not be used.
+ ec = boost::asio::error::operation_not_supported;
+ }
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+
+ return ec;
+}
+
+boost::system::error_code win_iocp_socket_service_base::do_open(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ int family, int type, int protocol, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ socket_holder sock(socket_ops::socket(family, type, protocol, ec));
+ if (sock.get() == invalid_socket)
+ return ec;
+
+ HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock.get());
+ if (iocp_service_.register_handle(sock_as_handle, ec))
+ return ec;
+
+ impl.socket_ = sock.release();
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ impl.cancel_token_.reset(static_cast<void*>(0), socket_ops::noop_deleter());
+ ec = boost::system::error_code();
+ return ec;
+}
+
+boost::system::error_code win_iocp_socket_service_base::do_assign(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ int type, socket_type native_socket, boost::system::error_code& ec)
+{
+ if (is_open(impl))
+ {
+ ec = boost::asio::error::already_open;
+ return ec;
+ }
+
+ HANDLE sock_as_handle = reinterpret_cast<HANDLE>(native_socket);
+ if (iocp_service_.register_handle(sock_as_handle, ec))
+ return ec;
+
+ impl.socket_ = native_socket;
+ switch (type)
+ {
+ case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
+ case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
+ default: impl.state_ = 0; break;
+ }
+ impl.cancel_token_.reset(static_cast<void*>(0), socket_ops::noop_deleter());
+ ec = boost::system::error_code();
+ return ec;
+}
+
+void win_iocp_socket_service_base::start_send_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ socket_base::message_flags flags, bool noop, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ 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
+ {
+ DWORD bytes_transferred = 0;
+ int result = ::WSASend(impl.socket_, buffers,
+ static_cast<DWORD>(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);
+ }
+}
+
+void win_iocp_socket_service_base::start_send_to_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ const socket_addr_type* addr, int addrlen,
+ socket_base::message_flags flags, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ iocp_service_.work_started();
+
+ if (!is_open(impl))
+ iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
+ else
+ {
+ DWORD bytes_transferred = 0;
+ int result = ::WSASendTo(impl.socket_, buffers,
+ static_cast<DWORD>(buffer_count),
+ &bytes_transferred, flags, addr, addrlen, 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);
+ }
+}
+
+void win_iocp_socket_service_base::start_receive_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ socket_base::message_flags flags, bool noop, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ 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
+ {
+ DWORD bytes_transferred = 0;
+ DWORD recv_flags = flags;
+ int result = ::WSARecv(impl.socket_, buffers,
+ static_cast<DWORD>(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);
+ }
+}
+
+void win_iocp_socket_service_base::start_null_buffers_receive_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ socket_base::message_flags flags, reactor_op* op)
+{
+ if ((impl.state_ & socket_ops::stream_oriented) != 0)
+ {
+ // For stream sockets on Windows, we may issue a 0-byte overlapped
+ // WSARecv to wait until there is data available on the socket.
+ ::WSABUF buf = { 0, 0 };
+ start_receive_op(impl, &buf, 1, flags, false, op);
+ }
+ else
+ {
+ start_reactor_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ op);
+ }
+}
+
+void win_iocp_socket_service_base::start_receive_from_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr,
+ socket_base::message_flags flags, int* addrlen, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ iocp_service_.work_started();
+
+ 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,
+ static_cast<DWORD>(buffer_count),
+ &bytes_transferred, &recv_flags, addr, addrlen, 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);
+ }
+}
+
+void win_iocp_socket_service_base::start_accept_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ bool peer_is_open, socket_holder& new_socket, int family, int type,
+ int protocol, void* output_buffer, DWORD address_length, operation* op)
+{
+ update_cancellation_thread_id(impl);
+ 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
+ {
+ boost::system::error_code ec;
+ new_socket.reset(socket_ops::socket(family, type, protocol, ec));
+ if (new_socket.get() == invalid_socket)
+ iocp_service_.on_completion(op, ec);
+ else
+ {
+ 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);
+ }
+ }
+}
+
+void win_iocp_socket_service_base::restart_accept_op(
+ socket_type s, socket_holder& new_socket, int family, int type,
+ int protocol, void* output_buffer, DWORD address_length, operation* op)
+{
+ new_socket.reset();
+ iocp_service_.work_started();
+
+ boost::system::error_code ec;
+ new_socket.reset(socket_ops::socket(family, type, protocol, ec));
+ if (new_socket.get() == invalid_socket)
+ iocp_service_.on_completion(op, ec);
+ else
+ {
+ DWORD bytes_read = 0;
+ BOOL result = ::AcceptEx(s, 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);
+ }
+}
+
+void win_iocp_socket_service_base::start_reactor_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ int op_type, reactor_op* op)
+{
+ reactor& r = get_reactor();
+ update_cancellation_thread_id(impl);
+
+ 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);
+}
+
+void win_iocp_socket_service_base::start_connect_op(
+ win_iocp_socket_service_base::base_implementation_type& impl,
+ reactor_op* op, const socket_addr_type* addr, std::size_t addrlen)
+{
+ reactor& r = get_reactor();
+ update_cancellation_thread_id(impl);
+
+ if ((impl.state_ & socket_ops::non_blocking) != 0
+ || socket_ops::set_internal_non_blocking(
+ impl.socket_, impl.state_, op->ec_))
+ {
+ if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0)
+ {
+ 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, false);
+ return;
+ }
+ }
+ }
+
+ r.post_immediate_completion(op);
+}
+
+void win_iocp_socket_service_base::close_for_destruction(
+ win_iocp_socket_service_base::base_implementation_type& impl)
+{
+ if (is_open(impl))
+ {
+ // 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* r = static_cast<reactor*>(
+ interlocked_compare_exchange_pointer(
+ reinterpret_cast<void**>(&reactor_), 0, 0));
+ if (r)
+ r->close_descriptor(impl.socket_, impl.reactor_data_);
+ }
+
+ boost::system::error_code ignored_ec;
+ socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
+ impl.socket_ = invalid_socket;
+ impl.state_ = 0;
+ impl.cancel_token_.reset();
+#if defined(BOOST_ASIO_ENABLE_CANCELIO)
+ impl.safe_cancellation_thread_id_ = 0;
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+}
+
+void win_iocp_socket_service_base::update_cancellation_thread_id(
+ win_iocp_socket_service_base::base_implementation_type& impl)
+{
+#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);
+#else // defined(BOOST_ASIO_ENABLE_CANCELIO)
+ (void)impl;
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+}
+
+reactor& win_iocp_socket_service_base::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;
+}
+
+void* win_iocp_socket_service_base::interlocked_compare_exchange_pointer(
+ void** dest, void* exch, void* cmp)
+{
+#if defined(_M_IX86)
+ return reinterpret_cast<void*>(InterlockedCompareExchange(
+ reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch),
+ reinterpret_cast<LONG>(cmp)));
+#else
+ return InterlockedCompareExchangePointer(dest, exch, cmp);
+#endif
+}
+
+void* win_iocp_socket_service_base::interlocked_exchange_pointer(
+ void** dest, void* val)
+{
+#if defined(_M_IX86)
+ return reinterpret_cast<void*>(InterlockedExchange(
+ reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val)));
+#else
+ return InterlockedExchangePointer(dest, val);
+#endif
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_IOCP_SOCKET_SERVICE_BASE_IPP

Added: trunk/boost/asio/detail/impl/win_mutex.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_mutex.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,78 @@
+//
+// detail/impl/win_mutex.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_MUTEX_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS)
+
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_mutex.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_mutex::win_mutex()
+{
+ int error = do_init();
+ boost::system::error_code ec(error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "mutex");
+}
+
+int win_mutex::do_init()
+{
+#if defined(__MINGW32__)
+ // Not sure if MinGW supports structured exception handling, so for now
+ // we'll just call the Windows API and hope.
+# if defined(UNDER_CE)
+ ::InitializeCriticalSection(&crit_section_);
+# else
+ ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
+# endif
+ return 0;
+#else
+ __try
+ {
+# if defined(UNDER_CE)
+ ::InitializeCriticalSection(&crit_section_);
+# else
+ ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
+# endif
+ }
+ __except(GetExceptionCode() == STATUS_NO_MEMORY
+ ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
+ {
+ return ERROR_OUTOFMEMORY;
+ }
+
+ return 0;
+#endif
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_MUTEX_IPP

Added: trunk/boost/asio/detail/impl/win_thread.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_thread.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,140 @@
+//
+// detail/impl/win_thread.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_THREAD_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
+#include <process.h>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_thread.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+win_thread::~win_thread()
+{
+ ::CloseHandle(thread_);
+
+ // The exit_event_ handle is deliberately allowed to leak here since it
+ // is an error for the owner of an internal thread not to join() it.
+}
+
+void win_thread::join()
+{
+ HANDLE handles[2] = { exit_event_, thread_ };
+ ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+ ::CloseHandle(exit_event_);
+ if (terminate_threads())
+ {
+ ::TerminateThread(thread_, 0);
+ }
+ else
+ {
+ ::QueueUserAPC(apc_function, thread_, 0);
+ ::WaitForSingleObject(thread_, INFINITE);
+ }
+}
+
+void win_thread::start_thread(func_base* arg, unsigned int stack_size)
+{
+ ::HANDLE entry_event = 0;
+ arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0);
+ if (!entry_event)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread.entry_event");
+ }
+
+ arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0);
+ if (!exit_event_)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread.exit_event");
+ }
+
+ unsigned int thread_id = 0;
+ thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0,
+ stack_size, win_thread_function, arg, 0, &thread_id));
+ if (!thread_)
+ {
+ DWORD last_error = ::GetLastError();
+ delete arg;
+ if (entry_event)
+ ::CloseHandle(entry_event);
+ if (exit_event_)
+ ::CloseHandle(exit_event_);
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread");
+ }
+
+ if (entry_event)
+ {
+ ::WaitForSingleObject(entry_event, INFINITE);
+ ::CloseHandle(entry_event);
+ }
+}
+
+unsigned int __stdcall win_thread_function(void* arg)
+{
+ std::auto_ptr<win_thread::func_base> func(
+ static_cast<win_thread::func_base*>(arg));
+
+ ::SetEvent(func->entry_event_);
+
+ func->run();
+
+ // Signal that the thread has finished its work, but rather than returning go
+ // to sleep to put the thread into a well known state. If the thread is being
+ // joined during global object destruction then it may be killed using
+ // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx
+ // call will be interrupted using QueueUserAPC and the thread will shut down
+ // cleanly.
+ HANDLE exit_event = func->exit_event_;
+ func.reset();
+ ::SetEvent(exit_event);
+ ::SleepEx(INFINITE, TRUE);
+
+ return 0;
+}
+
+#if defined(WINVER) && (WINVER < 0x0500)
+void __stdcall apc_function(ULONG) {}
+#else
+void __stdcall apc_function(ULONG_PTR) {}
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_THREAD_IPP

Added: trunk/boost/asio/detail/impl/win_tss_ptr.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/win_tss_ptr.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,59 @@
+//
+// detail/impl/win_tss_ptr.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WIN_TSS_PTR_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS)
+
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_tss_ptr.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+DWORD win_tss_ptr_create()
+{
+#if defined(UNDER_CE)
+ enum { out_of_indexes = 0xFFFFFFFF };
+#else
+ enum { out_of_indexes = TLS_OUT_OF_INDEXES };
+#endif
+
+ DWORD tss_key = ::TlsAlloc();
+ if (tss_key == out_of_indexes)
+ {
+ DWORD last_error = ::GetLastError();
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "tss");
+ }
+ return tss_key;
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WIN_TSS_PTR_IPP

Added: trunk/boost/asio/detail/impl/winsock_init.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/impl/winsock_init.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,71 @@
+//
+// detail/impl/winsock_init.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IMPL_WINSOCK_INIT_IPP
+#define BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/winsock_init.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+void winsock_init_base::startup(data& d,
+ unsigned char major, unsigned char minor)
+{
+ if (::InterlockedIncrement(&d.init_count_) == 1)
+ {
+ WSADATA wsa_data;
+ long result = ::WSAStartup(MAKEWORD(major, minor), &wsa_data);
+ ::InterlockedExchange(&d.result_, result);
+ }
+}
+
+void winsock_init_base::cleanup(data& d)
+{
+ if (::InterlockedDecrement(&d.init_count_) == 0)
+ {
+ ::WSACleanup();
+ }
+}
+
+void winsock_init_base::throw_on_error(data& d)
+{
+ long result = ::InterlockedExchangeAdd(&d.result_, 0);
+ if (result != 0)
+ {
+ boost::system::error_code ec(result,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "winsock");
+ }
+}
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
+#endif // BOOST_ASIO_DETAIL_IMPL_WINSOCK_INIT_IPP

Modified: trunk/boost/asio/detail/io_control.hpp
==============================================================================
--- trunk/boost/asio/detail/io_control.hpp (original)
+++ trunk/boost/asio/detail/io_control.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// io_control.hpp
-// ~~~~~~~~~~~~~~
+// detail/io_control.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/kqueue_reactor.hpp (original)
+++ trunk/boost/asio/detail/kqueue_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// kqueue_reactor.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/kqueue_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
@@ -16,41 +16,35 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/kqueue_reactor_fwd.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_KQUEUE)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
 #include <sys/types.h>
 #include <sys/event.h>
 #include <sys/time.h>
-#include <boost/config.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/hash_map.hpp>
+#include <boost/asio/detail/kqueue_reactor_fwd.hpp>
 #include <boost/asio/detail/mutex.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/socket_types.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/error.hpp>
+#include <boost/asio/io_service.hpp>
 
 // Older versions of Mac OS X may not define EV_OOBAND.
 #if !defined(EV_OOBAND)
 # define EV_OOBAND EV_FLAG1
 #endif // !defined(EV_OOBAND)
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -78,371 +72,83 @@
   typedef descriptor_state* per_descriptor_data;
 
   // Constructor.
- kqueue_reactor(boost::asio::io_service& 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()),
- interrupter_(),
- shutdown_(false)
- {
- // The interrupter is put into a permanently readable state. Whenever we
- // want to interrupt the blocked kevent call we register a one-shot read
- // operation against the descriptor.
- interrupter_.interrupt();
- }
+ BOOST_ASIO_DECL kqueue_reactor(boost::asio::io_service& io_service);
 
   // Destructor.
- ~kqueue_reactor()
- {
- close(kqueue_fd_);
- }
+ BOOST_ASIO_DECL ~kqueue_reactor();
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- mutex::scoped_lock lock(mutex_);
- shutdown_ = true;
- lock.unlock();
-
- op_queue<operation> ops;
-
- descriptor_map::iterator iter = registered_descriptors_.begin();
- descriptor_map::iterator end = registered_descriptors_.end();
- while (iter != end)
- {
- for (int i = 0; i < max_ops; ++i)
- ops.push(iter->second.op_queue_[i]);
- iter->second.shutdown_ = true;
- ++iter;
- }
-
- timer_queues_.get_all_timers(ops);
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task.
- void init_task()
- {
- io_service_.init_task();
- }
+ BOOST_ASIO_DECL void init_task();
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type descriptor,
- per_descriptor_data& descriptor_data)
- {
- mutex::scoped_lock lock(registered_descriptors_mutex_);
-
- descriptor_map::iterator new_entry = registered_descriptors_.insert(
- std::make_pair(descriptor, descriptor_state())).first;
- descriptor_data = &new_entry->second;
-
- descriptor_data->shutdown_ = false;
+ BOOST_ASIO_DECL int register_descriptor(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
- return 0;
+ // Post a reactor operation for immediate completion.
+ void post_immediate_completion(reactor_op* op)
+ {
+ io_service_.post_immediate_completion(op);
   }
 
   // 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,
+ BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
       per_descriptor_data& descriptor_data,
- reactor_op* op, bool allow_speculative)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
- if (descriptor_data->shutdown_)
- return;
-
- bool first = descriptor_data->op_queue_[op_type].empty();
- if (first)
- {
- if (allow_speculative)
- {
- if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
- {
- if (op->perform())
- {
- descriptor_lock.unlock();
- io_service_.post_immediate_completion(op);
- return;
- }
- }
- }
- }
-
- descriptor_data->op_queue_[op_type].push(op);
- io_service_.work_started();
-
- if (first)
- {
- struct kevent event;
- switch (op_type)
- {
- case read_op:
- EV_SET(&event, descriptor, EVFILT_READ,
- EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
- break;
- case write_op:
- EV_SET(&event, descriptor, EVFILT_WRITE,
- EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
- break;
- case except_op:
- if (!descriptor_data->op_queue_[read_op].empty())
- return; // Already registered for read events.
- EV_SET(&event, descriptor, EVFILT_READ,
- EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data);
- break;
- }
-
- if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
- {
- op->ec_ = boost::system::error_code(errno,
- boost::asio::error::get_system_category());
- descriptor_data->op_queue_[op_type].pop();
- io_service_.post_deferred_completion(op);
- }
- }
- }
+ reactor_op* op, bool allow_speculative);
 
   // 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& descriptor_data)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
-
- op_queue<operation> ops;
- for (int i = 0; i < max_ops; ++i)
- {
- while (reactor_op* op = descriptor_data->op_queue_[i].front())
- {
- op->ec_ = boost::asio::error::operation_aborted;
- descriptor_data->op_queue_[i].pop();
- ops.push(op);
- }
- }
-
- descriptor_lock.unlock();
-
- io_service_.post_deferred_completions(ops);
- }
+ BOOST_ASIO_DECL void cancel_ops(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
   // 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& descriptor_data)
- {
- mutex::scoped_lock descriptor_lock(descriptor_data->mutex_);
- mutex::scoped_lock descriptors_lock(registered_descriptors_mutex_);
-
- // Remove the descriptor from the set of known descriptors. The descriptor
- // will be automatically removed from the kqueue set when it is closed.
- descriptor_data->shutdown_ = true;
-
- op_queue<operation> ops;
- for (int i = 0; i < max_ops; ++i)
- {
- while (reactor_op* op = descriptor_data->op_queue_[i].front())
- {
- op->ec_ = boost::asio::error::operation_aborted;
- descriptor_data->op_queue_[i].pop();
- ops.push(op);
- }
- }
-
- descriptor_lock.unlock();
-
- registered_descriptors_.erase(descriptor);
-
- descriptors_lock.unlock();
-
- io_service_.post_deferred_completions(ops);
- }
+ BOOST_ASIO_DECL void close_descriptor(socket_type descriptor,
+ per_descriptor_data& descriptor_data);
 
   // Add a new timer queue to the reactor.
   template <typename Time_Traits>
- void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- mutex::scoped_lock lock(mutex_);
- timer_queues_.insert(&timer_queue);
- }
+ void add_timer_queue(timer_queue<Time_Traits>& queue);
 
   // Remove a timer queue from the reactor.
   template <typename Time_Traits>
- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- mutex::scoped_lock lock(mutex_);
- timer_queues_.erase(&timer_queue);
- }
+ void remove_timer_queue(timer_queue<Time_Traits>& queue);
 
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
- void schedule_timer(timer_queue<Time_Traits>& timer_queue,
- const typename Time_Traits::time_type& time, timer_op* op, void* token)
- {
- mutex::scoped_lock lock(mutex_);
- if (!shutdown_)
- {
- bool earliest = timer_queue.enqueue_timer(time, op, token);
- io_service_.work_started();
- if (earliest)
- interrupt();
- }
- }
+ void schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token);
 
   // 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)
- {
- 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;
- }
+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
 
   // Run the kqueue loop.
- void run(bool block, op_queue<operation>& ops)
- {
- mutex::scoped_lock lock(mutex_);
-
- // Determine how long to block while waiting for events.
- timespec timeout_buf = { 0, 0 };
- timespec* timeout = block ? get_timeout(timeout_buf) : &timeout_buf;
-
- lock.unlock();
-
- // Block on the kqueue descriptor.
- struct kevent events[128];
- int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout);
-
- // Dispatch the waiting events.
- for (int i = 0; i < num_events; ++i)
- {
- int descriptor = events[i].ident;
- void* ptr = events[i].udata;
- if (ptr == &interrupter_)
- {
- // No need to reset the interrupter since we're leaving the descriptor
- // in a ready-to-read state and relying on one-shot notifications.
- }
- else
- {
- 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.
- static const int filter[max_ops] =
- { EVFILT_READ, EVFILT_WRITE, EVFILT_READ };
- for (int j = max_ops - 1; j >= 0; --j)
- {
- if (events[i].filter == filter[j])
- {
- if (j != except_op || events[i].flags & EV_OOBAND)
- {
- while (reactor_op* op = descriptor_data->op_queue_[j].front())
- {
- if (events[i].flags & EV_ERROR)
- {
- op->ec_ = boost::system::error_code(events[i].data,
- boost::asio::error::get_system_category());
- descriptor_data->op_queue_[j].pop();
- ops.push(op);
- }
- if (op->perform())
- {
- descriptor_data->op_queue_[j].pop();
- ops.push(op);
- }
- else
- break;
- }
- }
- }
- }
-
- // Renew registration for event notifications.
- struct kevent event;
- switch (events[i].filter)
- {
- case EVFILT_READ:
- if (!descriptor_data->op_queue_[read_op].empty())
- EV_SET(&event, descriptor, EVFILT_READ,
- EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
- else if (!descriptor_data->op_queue_[except_op].empty())
- EV_SET(&event, descriptor, EVFILT_READ,
- EV_ADD | EV_ONESHOT, EV_OOBAND, 0, descriptor_data);
- else
- continue;
- case EVFILT_WRITE:
- if (!descriptor_data->op_queue_[write_op].empty())
- EV_SET(&event, descriptor, EVFILT_WRITE,
- EV_ADD | EV_ONESHOT, 0, 0, descriptor_data);
- else
- continue;
- default:
- break;
- }
- if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
- {
- boost::system::error_code error(errno,
- boost::asio::error::get_system_category());
- for (int j = 0; j < max_ops; ++j)
- {
- while (reactor_op* op = descriptor_data->op_queue_[j].front())
- {
- op->ec_ = error;
- descriptor_data->op_queue_[j].pop();
- ops.push(op);
- }
- }
- }
- }
- }
-
- lock.lock();
- timer_queues_.get_ready_timers(ops);
- }
+ BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
   // Interrupt the kqueue loop.
- void interrupt()
- {
- struct kevent event;
- EV_SET(&event, interrupter_.read_descriptor(),
- EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &interrupter_);
- ::kevent(kqueue_fd_, &event, 1, 0, 0, 0);
- }
+ BOOST_ASIO_DECL void interrupt();
 
 private:
   // Create the kqueue file descriptor. Throws an exception if the descriptor
   // cannot be created.
- static int do_kqueue_create()
- {
- int fd = kqueue();
- if (fd == -1)
- {
- boost::throw_exception(
- boost::system::system_error(
- boost::system::error_code(errno,
- boost::asio::error::get_system_category()),
- "kqueue"));
- }
- return fd;
- }
+ BOOST_ASIO_DECL static int do_kqueue_create();
+
+ // Helper function to add a new timer queue.
+ BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+ // Helper function to remove a timer queue.
+ BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
 
   // Get the timeout value for the kevent call.
- timespec* get_timeout(timespec& ts)
- {
- // 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.
- long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
- ts.tv_sec = usec / 1000000;
- ts.tv_nsec = (usec % 1000000) * 1000;
- return &ts;
- }
+ BOOST_ASIO_DECL timespec* get_timeout(timespec& ts);
 
   // The io_service implementation used to post completions.
   io_service_impl& io_service_;
@@ -480,8 +186,13 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_KQUEUE)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/kqueue_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/kqueue_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
+
 #endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// kqueue_reactor_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/kqueue_reactor_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2005 Stefan Arentz (stefan at soze dot com)
@@ -16,15 +16,9 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_KQUEUE)
-
-#if (defined(__MACH__) && defined(__APPLE__)) \
- || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-
-// Define this to indicate that kqueue is supported on the target platform.
-#define BOOST_ASIO_HAS_KQUEUE 1
+#if defined(BOOST_ASIO_HAS_KQUEUE)
 
 namespace boost {
 namespace asio {
@@ -36,11 +30,6 @@
 } // namespace asio
 } // namespace boost
 
-#endif // (defined(__MACH__) && defined(__APPLE__))
- // || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
-
-#endif // !defined(BOOST_ASIO_DISABLE_KQUEUE)
-
-#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_HAS_KQUEUE)
 
 #endif // BOOST_ASIO_DETAIL_KQUEUE_REACTOR_FWD_HPP

Modified: trunk/boost/asio/detail/local_free_on_block_exit.hpp
==============================================================================
--- trunk/boost/asio/detail/local_free_on_block_exit.hpp (original)
+++ trunk/boost/asio/detail/local_free_on_block_exit.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// local_free_on_block_exit.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/local_free_on_block_exit.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,15 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -54,8 +52,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_LOCAL_FREE_ON_BLOCK_EXIT_HPP

Modified: trunk/boost/asio/detail/macos_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/macos_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/macos_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// macos_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/macos_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,13 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(__MACH__) && defined(__APPLE__)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <libkern/OSAtomic.h>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -52,8 +48,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(__MACH__) && defined(__APPLE__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(__MACH__) && defined(__APPLE__)
+
 #endif // BOOST_ASIO_DETAIL_MACOS_FENCED_BLOCK_HPP

Modified: trunk/boost/asio/detail/mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/mutex.hpp (original)
+++ trunk/boost/asio/detail/mutex.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// mutex.hpp
-// ~~~~~~~~~
+// detail/mutex.hpp
+// ~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_mutex.hpp>
@@ -47,6 +43,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_MUTEX_HPP

Modified: trunk/boost/asio/detail/noncopyable.hpp
==============================================================================
--- trunk/boost/asio/detail/noncopyable.hpp (original)
+++ trunk/boost/asio/detail/noncopyable.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// noncopyable.hpp
-// ~~~~~~~~~~~~~~~
+// detail/noncopyable.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,11 @@
 # 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/config.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Deleted: trunk/boost/asio/detail/null_buffers_op.hpp
==============================================================================
--- trunk/boost/asio/detail/null_buffers_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,79 +0,0 @@
-//
-// 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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_event.hpp
-// ~~~~~~~~~~~~~~
+// detail/null_event.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,14 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -72,8 +70,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_NULL_EVENT_HPP

Modified: trunk/boost/asio/detail/null_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/null_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/null_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// detail/null_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //

Modified: trunk/boost/asio/detail/null_mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/null_mutex.hpp (original)
+++ trunk/boost/asio/detail/null_mutex.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_mutex.hpp
-// ~~~~~~~~~~~~~~
+// detail/null_mutex.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,15 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/scoped_lock.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -61,8 +59,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_NULL_MUTEX_HPP

Modified: trunk/boost/asio/detail/null_signal_blocker.hpp
==============================================================================
--- trunk/boost/asio/detail/null_signal_blocker.hpp (original)
+++ trunk/boost/asio/detail/null_signal_blocker.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_signal_blocker.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// detail/null_signal_blocker.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,14 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -58,8 +56,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_NULL_SIGNAL_BLOCKER_HPP

Modified: trunk/boost/asio/detail/null_thread.hpp
==============================================================================
--- trunk/boost/asio/detail/null_thread.hpp (original)
+++ trunk/boost/asio/detail/null_thread.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_thread.hpp
-// ~~~~~~~~~~~~~~~
+// detail/null_thread.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,21 +15,15 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -41,11 +35,10 @@
 public:
   // Constructor.
   template <typename Function>
- null_thread(Function f)
+ null_thread(Function)
   {
- boost::system::system_error e(
+ boost::asio::detail::throw_error(
         boost::asio::error::operation_not_supported, "thread");
- boost::throw_exception(e);
   }
 
   // Destructor.
@@ -63,8 +56,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_NULL_THREAD_HPP

Modified: trunk/boost/asio/detail/null_tss_ptr.hpp
==============================================================================
--- trunk/boost/asio/detail/null_tss_ptr.hpp (original)
+++ trunk/boost/asio/detail/null_tss_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// null_tss_ptr.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/null_tss_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,14 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -65,8 +63,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_NULL_TSS_PTR_HPP

Modified: trunk/boost/asio/detail/old_win_sdk_compat.hpp
==============================================================================
--- trunk/boost/asio/detail/old_win_sdk_compat.hpp (original)
+++ trunk/boost/asio/detail/old_win_sdk_compat.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// old_win_sdk_compat.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/old_win_sdk_compat.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
@@ -36,6 +32,8 @@
 // a recent (i.e. Vista or later) SDK, as the SDK does not provide IPv6 support
 // in that case.
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -323,6 +321,8 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_OLD_WIN_SDK)
 
 // Even newer Platform SDKs that support IPv6 may not define IPV6_V6ONLY.
@@ -337,6 +337,4 @@
 
 #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_OLD_WIN_SDK_COMPAT_HPP

Modified: trunk/boost/asio/detail/op_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/op_queue.hpp (original)
+++ trunk/boost/asio/detail/op_queue.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// op_queue.hpp
-// ~~~~~~~~~~~~
+// detail/op_queue.hpp
+// ~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/operation.hpp
==============================================================================
--- trunk/boost/asio/detail/operation.hpp (original)
+++ trunk/boost/asio/detail/operation.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// operation.hpp
-// ~~~~~~~~~~~~~
+// detail/operation.hpp
+// ~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,11 @@
 # 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>
+#include <boost/asio/detail/config.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
 
@@ -33,13 +30,11 @@
 #if defined(BOOST_ASIO_HAS_IOCP)
 typedef win_iocp_operation operation;
 #else
-typedef task_io_service_operation<reactor> operation;
+typedef task_io_service_operation 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/pipe_select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/pipe_select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/pipe_select_interrupter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// pipe_select_interrupter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/pipe_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,22 +15,12 @@
 # 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/throw_exception.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#if !defined(BOOST_ASIO_HAS_EVENTFD)
 
 #include <boost/asio/detail/push_options.hpp>
-#include <fcntl.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_types.hpp>
 
 namespace boost {
 namespace asio {
@@ -40,57 +30,16 @@
 {
 public:
   // Constructor.
- pipe_select_interrupter()
- {
- int pipe_fds[2];
- if (pipe(pipe_fds) == 0)
- {
- read_descriptor_ = pipe_fds[0];
- ::fcntl(read_descriptor_, F_SETFL, O_NONBLOCK);
- write_descriptor_ = pipe_fds[1];
- ::fcntl(write_descriptor_, F_SETFL, O_NONBLOCK);
- }
- else
- {
- boost::system::error_code ec(errno,
- boost::asio::error::get_system_category());
- boost::system::system_error e(ec, "pipe_select_interrupter");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL pipe_select_interrupter();
 
   // Destructor.
- ~pipe_select_interrupter()
- {
- if (read_descriptor_ != -1)
- ::close(read_descriptor_);
- if (write_descriptor_ != -1)
- ::close(write_descriptor_);
- }
+ BOOST_ASIO_DECL ~pipe_select_interrupter();
 
   // Interrupt the select call.
- void interrupt()
- {
- char byte = 0;
- int result = ::write(write_descriptor_, &byte, 1);
- (void)result;
- }
+ BOOST_ASIO_DECL void interrupt();
 
   // Reset the select interrupt. Returns true if the call was interrupted.
- bool reset()
- {
- for (;;)
- {
- char data[1024];
- int bytes_read = ::read(read_descriptor_, data, sizeof(data));
- if (bytes_read < 0 && errno == EINTR)
- continue;
- bool was_interrupted = (bytes_read > 0);
- while (bytes_read == sizeof(data))
- bytes_read = ::read(read_descriptor_, data, sizeof(data));
- return was_interrupted;
- }
- }
+ BOOST_ASIO_DECL bool reset();
 
   // Get the read descriptor to be passed to select.
   int read_descriptor() const
@@ -115,8 +64,13 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/pipe_select_interrupter.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_HAS_EVENTFD)
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_PIPE_SELECT_INTERRUPTER_HPP

Modified: trunk/boost/asio/detail/pop_options.hpp
==============================================================================
--- trunk/boost/asio/detail/pop_options.hpp (original)
+++ trunk/boost/asio/detail/pop_options.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// pop_options.hpp
-// ~~~~~~~~~~~~~~~
+// detail/pop_options.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //

Modified: trunk/boost/asio/detail/posix_event.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_event.hpp (original)
+++ trunk/boost/asio/detail/posix_event.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_event.hpp
-// ~~~~~~~~~~~~~~~
+// detail/posix_event.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,24 +15,16 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if defined(BOOST_HAS_PTHREADS)
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <boost/assert.hpp>
-#include <boost/throw_exception.hpp>
 #include <pthread.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -42,19 +34,7 @@
 {
 public:
   // Constructor.
- posix_event()
- : signalled_(false)
- {
- int error = ::pthread_cond_init(&cond_, 0);
- if (error != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(error,
- boost::asio::error::get_system_category()),
- "event");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL posix_event();
 
   // Destructor.
   ~posix_event()
@@ -109,8 +89,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_HAS_PTHREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/posix_event.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_EVENT_HPP

Modified: trunk/boost/asio/detail/posix_fd_set_adapter.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_fd_set_adapter.hpp (original)
+++ trunk/boost/asio/detail/posix_fd_set_adapter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_fd_set_adapter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/posix_fd_set_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstring>
-#include <boost/asio/detail/pop_options.hpp>
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
+#include <cstring>
 #include <boost/asio/detail/socket_types.hpp>
 
-#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -76,8 +75,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_FD_SET_ADAPTER_HPP

Modified: trunk/boost/asio/detail/posix_mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_mutex.hpp (original)
+++ trunk/boost/asio/detail/posix_mutex.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_mutex.hpp
-// ~~~~~~~~~~~~~~~
+// detail/posix_mutex.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,24 +15,16 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if defined(BOOST_HAS_PTHREADS)
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
 #include <pthread.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/scoped_lock.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -46,18 +38,7 @@
   typedef boost::asio::detail::scoped_lock<posix_mutex> scoped_lock;
 
   // Constructor.
- posix_mutex()
- {
- int error = ::pthread_mutex_init(&mutex_, 0);
- if (error != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(error,
- boost::asio::error::get_system_category()),
- "mutex");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL posix_mutex();
 
   // Destructor.
   ~posix_mutex()
@@ -86,8 +67,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_HAS_PTHREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/posix_mutex.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_MUTEX_HPP

Modified: trunk/boost/asio/detail/posix_signal_blocker.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_signal_blocker.hpp (original)
+++ trunk/boost/asio/detail/posix_signal_blocker.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_signal_blocker.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/posix_signal_blocker.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,22 +15,17 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
-#if defined(BOOST_HAS_PTHREADS)
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <csignal>
 #include <pthread.h>
 #include <signal.h>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -85,8 +80,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_HAS_PTHREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_SIGNAL_BLOCKER_HPP

Modified: trunk/boost/asio/detail/posix_thread.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_thread.hpp (original)
+++ trunk/boost/asio/detail/posix_thread.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_thread.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/posix_thread.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,29 +15,23 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if defined(BOOST_HAS_PTHREADS)
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <memory>
-#include <boost/throw_exception.hpp>
 #include <pthread.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
 
-extern "C" void* boost_asio_detail_posix_thread_function(void* arg);
+extern "C"
+{
+ BOOST_ASIO_DECL void* boost_asio_detail_posix_thread_function(void* arg);
+}
 
 class posix_thread
   : private noncopyable
@@ -48,36 +42,14 @@
   posix_thread(Function f)
     : joined_(false)
   {
- std::auto_ptr<func_base> arg(new func<Function>(f));
- int error = ::pthread_create(&thread_, 0,
- boost_asio_detail_posix_thread_function, arg.get());
- if (error != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(error,
- boost::asio::error::get_system_category()),
- "thread");
- boost::throw_exception(e);
- }
- arg.release();
+ start_thread(new func<Function>(f));
   }
 
   // Destructor.
- ~posix_thread()
- {
- if (!joined_)
- ::pthread_detach(thread_);
- }
+ BOOST_ASIO_DECL ~posix_thread();
 
   // Wait for the thread to exit.
- void join()
- {
- if (!joined_)
- {
- ::pthread_join(thread_, 0);
- joined_ = true;
- }
- }
+ BOOST_ASIO_DECL void join();
 
 private:
   friend void* boost_asio_detail_posix_thread_function(void* arg);
@@ -89,6 +61,12 @@
     virtual void run() = 0;
   };
 
+ struct auto_func_base_ptr
+ {
+ func_base* ptr;
+ ~auto_func_base_ptr() { delete ptr; }
+ };
+
   template <typename Function>
   class func
     : public func_base
@@ -108,24 +86,22 @@
     Function f_;
   };
 
+ BOOST_ASIO_DECL void start_thread(func_base* arg);
+
   ::pthread_t thread_;
   bool joined_;
 };
 
-inline void* boost_asio_detail_posix_thread_function(void* arg)
-{
- std::auto_ptr<posix_thread::func_base> f(
- static_cast<posix_thread::func_base*>(arg));
- f->run();
- return 0;
-}
-
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_HAS_PTHREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/posix_thread.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_THREAD_HPP

Modified: trunk/boost/asio/detail/posix_tss_ptr.hpp
==============================================================================
--- trunk/boost/asio/detail/posix_tss_ptr.hpp (original)
+++ trunk/boost/asio/detail/posix_tss_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// posix_tss_ptr.hpp
-// ~~~~~~~~~~~~~~~~~
+// detail/posix_tss_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,27 +15,22 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#if defined(BOOST_HAS_PTHREADS)
+#if defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
 #include <pthread.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
 
+// Helper function to create thread-specific storage.
+BOOST_ASIO_DECL void posix_tss_ptr_create(pthread_key_t& key);
+
 template <typename T>
 class posix_tss_ptr
   : private noncopyable
@@ -44,15 +39,7 @@
   // Constructor.
   posix_tss_ptr()
   {
- int error = ::pthread_key_create(&tss_key_, 0);
- if (error != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(error,
- boost::asio::error::get_system_category()),
- "tss");
- boost::throw_exception(e);
- }
+ posix_tss_ptr_create(tss_key_);
   }
 
   // Destructor.
@@ -77,14 +64,19 @@
   // Thread-specific storage to allow unlocked access to determine whether a
   // thread is a member of the pool.
   pthread_key_t tss_key_;
+
 };
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_HAS_PTHREADS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/posix_tss_ptr.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_HAS_PTHREADS) && !defined(BOOST_ASIO_DISABLE_THREADS)
+
 #endif // BOOST_ASIO_DETAIL_POSIX_TSS_PTR_HPP

Modified: trunk/boost/asio/detail/push_options.hpp
==============================================================================
--- trunk/boost/asio/detail/push_options.hpp (original)
+++ trunk/boost/asio/detail/push_options.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// push_options.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/push_options.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactive_descriptor_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/reactive_descriptor_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,21 +15,24 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
+#include <boost/utility/addressof.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/descriptor_ops.hpp>
+#include <boost/asio/detail/descriptor_read_op.hpp>
+#include <boost/asio/detail/descriptor_write_op.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/reactive_null_buffers_op.hpp>
 #include <boost/asio/detail/reactor.hpp>
-#include <boost/asio/detail/reactor_op.hpp>
 
-#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -49,7 +52,7 @@
     // Default constructor.
     implementation_type()
       : descriptor_(-1),
- flags_(0)
+ state_(0)
     {
     }
 
@@ -60,94 +63,29 @@
     // The native descriptor representation.
     int descriptor_;
 
- enum
- {
- // 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 descriptor is non-blocking.
- non_blocking = user_set_non_blocking | internal_non_blocking
- };
-
- // Flags indicating the current state of the descriptor.
- unsigned char flags_;
+ // The current state of the descriptor.
+ descriptor_ops::state_type state_;
 
     // Per-descriptor data used by the reactor.
     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_descriptor_service(boost::asio::io_service& 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();
- }
+ BOOST_ASIO_DECL reactive_descriptor_service(
+ boost::asio::io_service& io_service);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Construct a new descriptor implementation.
- void construct(implementation_type& impl)
- {
- impl.descriptor_ = -1;
- impl.flags_ = 0;
- }
+ BOOST_ASIO_DECL void construct(implementation_type& impl);
 
   // Destroy a descriptor implementation.
- void destroy(implementation_type& impl)
- {
- if (impl.descriptor_ != -1)
- {
- reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
-
- if (impl.flags_ & implementation_type::internal_non_blocking)
- {
- ioctl_arg_type non_blocking = 0;
- boost::system::error_code ignored_ec;
- descriptor_ops::ioctl(impl.descriptor_,
- FIONBIO, &non_blocking, ignored_ec);
- impl.flags_ &= ~implementation_type::internal_non_blocking;
- }
-
- boost::system::error_code ignored_ec;
- descriptor_ops::close(impl.descriptor_, ignored_ec);
-
- impl.descriptor_ = -1;
- }
- }
+ BOOST_ASIO_DECL void destroy(implementation_type& impl);
 
   // Assign a native descriptor to a descriptor implementation.
- boost::system::error_code assign(implementation_type& impl,
- const native_type& native_descriptor, boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- if (int err = reactor_.register_descriptor(
- native_descriptor, impl.reactor_data_))
- {
- ec = boost::system::error_code(err,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- impl.descriptor_ = native_descriptor;
- impl.flags_ = 0;
- ec = boost::system::error_code();
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code assign(implementation_type& impl,
+ const native_type& native_descriptor, boost::system::error_code& ec);
 
   // Determine whether the descriptor is open.
   bool is_open(const implementation_type& impl) const
@@ -156,31 +94,8 @@
   }
 
   // Destroy a descriptor implementation.
- boost::system::error_code close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
-
- if (impl.flags_ & implementation_type::internal_non_blocking)
- {
- ioctl_arg_type non_blocking = 0;
- boost::system::error_code ignored_ec;
- descriptor_ops::ioctl(impl.descriptor_,
- FIONBIO, &non_blocking, ignored_ec);
- impl.flags_ &= ~implementation_type::internal_non_blocking;
- }
-
- if (descriptor_ops::close(impl.descriptor_, ec) == -1)
- return ec;
-
- impl.descriptor_ = -1;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code close(implementation_type& impl,
+ boost::system::error_code& ec);
 
   // Get the native descriptor representation.
   native_type native(const implementation_type& impl) const
@@ -189,56 +104,16 @@
   }
 
   // Cancel all operations associated with the descriptor.
- boost::system::error_code cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_);
- ec = boost::system::error_code();
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl,
+ boost::system::error_code& ec);
 
   // Perform an IO control command on the descriptor.
   template <typename IO_Control_Command>
   boost::system::error_code io_control(implementation_type& impl,
       IO_Control_Command& command, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- descriptor_ops::ioctl(impl.descriptor_, command.name(),
- static_cast<ioctl_arg_type*>(command.data()), ec);
-
- // When updating the non-blocking mode we always perform the ioctl syscall,
- // even if the flags would otherwise indicate that the descriptor is
- // already in the correct state. This ensures that the underlying
- // descriptor is put into the state that has been requested by the user. If
- // the ioctl syscall was successful then we need to update the flags to
- // match.
- if (!ec && command.name() == static_cast<int>(FIONBIO))
- {
- if (*static_cast<ioctl_arg_type*>(command.data()))
- {
- impl.flags_ |= implementation_type::user_set_non_blocking;
- }
- else
- {
- // Clearing the non-blocking mode always overrides any internally-set
- // non-blocking flag. Any subsequent asynchronous operations will need
- // to re-enable non-blocking I/O.
- impl.flags_ &= ~(implementation_type::user_set_non_blocking
- | implementation_type::internal_non_blocking);
- }
- }
-
+ descriptor_ops::ioctl(impl.descriptor_, impl.state_,
+ command.name(), static_cast<ioctl_arg_type*>(command.data()), ec);
     return ec;
   }
 
@@ -247,148 +122,23 @@
   size_t write_some(implementation_type& impl,
       const ConstBufferSequence& buffers, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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 (bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Send the data.
- for (;;)
- {
- // Try to complete the operation without blocking.
- int bytes_sent = descriptor_ops::gather_write(
- impl.descriptor_, bufs.buffers(), bufs.count(), ec);
-
- // Check if operation succeeded.
- if (bytes_sent >= 0)
- return bytes_sent;
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for descriptor to become ready.
- if (descriptor_ops::poll_write(impl.descriptor_, ec) < 0)
- return 0;
- }
+ return descriptor_ops::sync_write(impl.descriptor_, impl.state_,
+ bufs.buffers(), bufs.count(), bufs.all_empty(), ec);
   }
 
   // Wait until data can be written without blocking.
   size_t write_some(implementation_type& impl,
       const null_buffers&, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for descriptor to become ready.
     descriptor_ops::poll_write(impl.descriptor_, ec);
 
     return 0;
   }
 
- template <typename ConstBufferSequence>
- class write_op_base : public reactor_op
- {
- public:
- write_op_base(int descriptor,
- const ConstBufferSequence& buffers, func_type complete_func)
- : reactor_op(&write_op_base::do_perform, complete_func),
- descriptor_(descriptor),
- buffers_(buffers)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- write_op_base* o(static_cast<write_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Write the data.
- 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)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- private:
- int descriptor_;
- ConstBufferSequence buffers_;
- };
-
- template <typename ConstBufferSequence, typename Handler>
- class write_op : public write_op_base<ConstBufferSequence>
- {
- public:
- write_op(int descriptor,
- const ConstBufferSequence& buffers, Handler handler)
- : write_op_base<ConstBufferSequence>(
- descriptor, buffers, &write_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.
- 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:
- 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>
@@ -396,15 +146,16 @@
       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);
+ typedef descriptor_write_op<ConstBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.descriptor_, buffers, handler);
 
- start_op(impl, reactor::write_op, ptr.get(), true,
+ start_op(impl, reactor::write_op, p.p, true,
         buffer_sequence_adapter<boost::asio::const_buffer,
           ConstBufferSequence>::all_empty(buffers));
- ptr.release();
+ p.v = p.p = 0;
   }
 
   // Start an asynchronous wait until data can be written without blocking.
@@ -413,13 +164,14 @@
       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);
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
 
- start_op(impl, reactor::write_op, ptr.get(), false, false);
- ptr.release();
+ start_op(impl, reactor::write_op, p.p, false, false);
+ p.v = p.p = 0;
   }
 
   // Read some data from the stream. Returns the number of bytes read.
@@ -427,157 +179,23 @@
   size_t read_some(implementation_type& impl,
       const MutableBufferSequence& buffers, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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 (bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Read some data.
- for (;;)
- {
- // Try to complete the operation without blocking.
- int bytes_read = descriptor_ops::scatter_read(
- impl.descriptor_, bufs.buffers(), bufs.count(), ec);
-
- // Check if operation succeeded.
- if (bytes_read > 0)
- return bytes_read;
-
- // Check for EOF.
- if (bytes_read == 0)
- {
- ec = boost::asio::error::eof;
- return 0;
- }
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for descriptor to become ready.
- if (descriptor_ops::poll_read(impl.descriptor_, ec) < 0)
- return 0;
- }
+ return descriptor_ops::sync_read(impl.descriptor_, impl.state_,
+ bufs.buffers(), bufs.count(), bufs.all_empty(), ec);
   }
 
   // Wait until data can be read without blocking.
   size_t read_some(implementation_type& impl,
       const null_buffers&, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for descriptor to become ready.
     descriptor_ops::poll_read(impl.descriptor_, ec);
 
     return 0;
   }
 
- template <typename MutableBufferSequence>
- class read_op_base : public reactor_op
- {
- public:
- read_op_base(int descriptor,
- const MutableBufferSequence& buffers, func_type complete_func)
- : reactor_op(&read_op_base::do_perform, complete_func),
- descriptor_(descriptor),
- buffers_(buffers)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- read_op_base* o(static_cast<read_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Read some data.
- 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;
-
- // Retry operation if interrupted by signal.
- if (ec == boost::asio::error::interrupted)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- 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)
- {
- }
-
- 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:
- Handler handler_;
- };
-
   // Start an asynchronous read. The buffer for the data being read must be
   // valid for the lifetime of the asynchronous operation.
   template <typename MutableBufferSequence, typename Handler>
@@ -585,16 +203,16 @@
       const MutableBufferSequence& buffers, Handler handler)
   {
     // 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);
+ typedef descriptor_read_op<MutableBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.descriptor_, buffers, handler);
 
- start_op(impl, reactor::read_op, ptr.get(), true,
+ start_op(impl, reactor::read_op, p.p, true,
         buffer_sequence_adapter<boost::asio::mutable_buffer,
           MutableBufferSequence>::all_empty(buffers));
- ptr.release();
+ p.v = p.p = 0;
   }
 
   // Wait until data can be read without blocking.
@@ -603,57 +221,20 @@
       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);
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
 
- start_op(impl, reactor::read_op, ptr.get(), false, false);
- ptr.release();
+ start_op(impl, reactor::read_op, p.p, false, false);
+ p.v = p.p = 0;
   }
 
 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))
- {
- if (is_non_blocking(impl) || set_non_blocking(impl, op->ec_))
- {
- reactor_.start_op(op_type, impl.descriptor_,
- impl.reactor_data_, op, non_blocking);
- return;
- }
- }
- else
- op->ec_ = boost::asio::error::bad_descriptor;
- }
-
- io_service_impl_.post_immediate_completion(op);
- }
-
- // Determine whether the descriptor 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 (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_;
+ BOOST_ASIO_DECL void start_op(implementation_type& impl, int op_type,
+ reactor_op* op, bool non_blocking, bool noop);
 
   // The selector that performs event demultiplexing for the service.
   reactor& reactor_;
@@ -663,8 +244,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/reactive_descriptor_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_REACTIVE_DESCRIPTOR_SERVICE_HPP

Added: trunk/boost/asio/detail/reactive_null_buffers_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_null_buffers_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,85 @@
+//
+// detail/reactive_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_REACTIVE_NULL_BUFFERS_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class reactive_null_buffers_op : public reactor_op
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_null_buffers_op);
+
+ reactive_null_buffers_op(Handler handler)
+ : reactor_op(&reactive_null_buffers_op::do_perform,
+ &reactive_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.
+ reactive_null_buffers_op* o(static_cast<reactive_null_buffers_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_NULL_BUFFERS_OP_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactive_serial_port_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/reactive_serial_port_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
@@ -16,23 +16,20 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <cstring>
-#include <string>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/serial_port_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
- && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT)
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
+#include <string>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
+#include <boost/asio/serial_port_base.hpp>
 #include <boost/asio/detail/descriptor_ops.hpp>
 #include <boost/asio/detail/reactive_descriptor_service.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -47,119 +44,55 @@
   // 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)
- : descriptor_service_(io_service)
- {
- }
+ BOOST_ASIO_DECL reactive_serial_port_service(
+ boost::asio::io_service& io_service);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- descriptor_service_.shutdown_service();
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
- // Construct a new handle implementation.
+ // Construct a new serial port implementation.
   void construct(implementation_type& impl)
   {
     descriptor_service_.construct(impl);
   }
 
- // Destroy a handle implementation.
+ // Destroy a serial port implementation.
   void destroy(implementation_type& impl)
   {
     descriptor_service_.destroy(impl);
   }
 
   // Open the serial port using the specified device name.
- boost::system::error_code open(implementation_type& impl,
- const std::string& device, boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- int fd = descriptor_ops::open(device.c_str(),
- O_RDWR | O_NONBLOCK | O_NOCTTY, ec);
- if (fd < 0)
- return ec;
-
- int s = descriptor_ops::fcntl(fd, F_GETFL, ec);
- if (s >= 0)
- s = descriptor_ops::fcntl(fd, F_SETFL, s | O_NONBLOCK, ec);
- if (s < 0)
- {
- boost::system::error_code ignored_ec;
- descriptor_ops::close(fd, ignored_ec);
- return ec;
- }
-
- // Set up default serial port options.
- termios ios;
- descriptor_ops::clear_error(ec);
- s = descriptor_ops::error_wrapper(::tcgetattr(fd, &ios), ec);
- if (s >= 0)
- {
-#if defined(_BSD_SOURCE)
- ::cfmakeraw(&ios);
-#else
- ios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK
- | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
- ios.c_oflag &= ~OPOST;
- ios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- ios.c_cflag &= ~(CSIZE | PARENB);
- ios.c_cflag |= CS8;
-#endif
- ios.c_iflag |= IGNPAR;
- ios.c_cflag |= CREAD | CLOCAL;
- descriptor_ops::clear_error(ec);
- s = descriptor_ops::error_wrapper(::tcsetattr(fd, TCSANOW, &ios), ec);
- }
- if (s < 0)
- {
- boost::system::error_code ignored_ec;
- descriptor_ops::close(fd, ignored_ec);
- return ec;
- }
-
- // We're done. Take ownership of the serial port descriptor.
- if (descriptor_service_.assign(impl, fd, ec))
- {
- boost::system::error_code ignored_ec;
- descriptor_ops::close(fd, ignored_ec);
- }
-
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl,
+ const std::string& device, boost::system::error_code& ec);
 
- // Assign a native handle to a handle implementation.
+ // Assign a native descriptor to a serial port implementation.
   boost::system::error_code assign(implementation_type& impl,
       const native_type& native_descriptor, boost::system::error_code& ec)
   {
     return descriptor_service_.assign(impl, native_descriptor, ec);
   }
 
- // Determine whether the handle is open.
+ // Determine whether the serial port is open.
   bool is_open(const implementation_type& impl) const
   {
     return descriptor_service_.is_open(impl);
   }
 
- // Destroy a handle implementation.
+ // Destroy a serial port implementation.
   boost::system::error_code close(implementation_type& impl,
       boost::system::error_code& ec)
   {
     return descriptor_service_.close(impl, ec);
   }
 
- // Get the native handle representation.
+ // Get the native serial port representation.
   native_type native(implementation_type& impl)
   {
     return descriptor_service_.native(impl);
   }
 
- // Cancel all operations associated with the handle.
+ // Cancel all operations associated with the serial port.
   boost::system::error_code cancel(implementation_type& impl,
       boost::system::error_code& ec)
   {
@@ -171,20 +104,9 @@
   boost::system::error_code set_option(implementation_type& impl,
       const SettableSerialPortOption& option, boost::system::error_code& ec)
   {
- termios ios;
- descriptor_ops::clear_error(ec);
- descriptor_ops::error_wrapper(::tcgetattr(
- descriptor_service_.native(impl), &ios), ec);
- if (ec)
- return ec;
-
- if (option.store(ios, ec))
- return ec;
-
- descriptor_ops::clear_error(ec);
- descriptor_ops::error_wrapper(::tcsetattr(
- descriptor_service_.native(impl), TCSANOW, &ios), ec);
- return ec;
+ return do_set_option(impl,
+ &reactive_serial_port_service::store_option<SettableSerialPortOption>,
+ &option, ec);
   }
 
   // Get an option from the serial port.
@@ -192,21 +114,16 @@
   boost::system::error_code get_option(const implementation_type& impl,
       GettableSerialPortOption& option, boost::system::error_code& ec) const
   {
- termios ios;
- descriptor_ops::clear_error(ec);
- descriptor_ops::error_wrapper(::tcgetattr(
- descriptor_service_.native(impl), &ios), ec);
- if (ec)
- return ec;
-
- return option.load(ios, ec);
+ return do_get_option(impl,
+ &reactive_serial_port_service::load_option<GettableSerialPortOption>,
+ &option, ec);
   }
 
   // Send a break sequence to the serial port.
   boost::system::error_code send_break(implementation_type& impl,
       boost::system::error_code& ec)
   {
- descriptor_ops::clear_error(ec);
+ errno = 0;
     descriptor_ops::error_wrapper(::tcsendbreak(
           descriptor_service_.native(impl), 0), ec);
     return ec;
@@ -247,6 +164,41 @@
   }
 
 private:
+ // Function pointer type for storing a serial port option.
+ typedef boost::system::error_code (*store_function_type)(
+ const void*, termios&, boost::system::error_code&);
+
+ // Helper function template to store a serial port option.
+ template <typename SettableSerialPortOption>
+ static boost::system::error_code store_option(const void* option,
+ termios& storage, boost::system::error_code& ec)
+ {
+ return static_cast<const SettableSerialPortOption*>(option)->store(
+ storage, ec);
+ }
+
+ // Helper function to set a serial port option.
+ BOOST_ASIO_DECL boost::system::error_code do_set_option(
+ implementation_type& impl, store_function_type store,
+ const void* option, boost::system::error_code& ec);
+
+ // Function pointer type for loading a serial port option.
+ typedef boost::system::error_code (*load_function_type)(
+ void*, const termios&, boost::system::error_code&);
+
+ // Helper function template to load a serial port option.
+ template <typename GettableSerialPortOption>
+ static boost::system::error_code load_option(void* option,
+ const termios& storage, boost::system::error_code& ec)
+ {
+ return static_cast<GettableSerialPortOption*>(option)->load(storage, ec);
+ }
+
+ // Helper function to get a serial port option.
+ BOOST_ASIO_DECL boost::system::error_code do_get_option(
+ const implementation_type& impl, load_function_type load,
+ void* option, boost::system::error_code& ec) const;
+
   // The implementation used for initiating asynchronous operations.
   reactive_descriptor_service descriptor_service_;
 };
@@ -255,9 +207,13 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
- // && !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/reactive_serial_port_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
 #endif // BOOST_ASIO_DETAIL_REACTIVE_SERIAL_PORT_SERVICE_HPP

Added: trunk/boost/asio/detail/reactive_socket_accept_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_accept_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,133 @@
+//
+// detail/reactive_socket_accept_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_REACTIVE_SOCKET_ACCEPT_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_holder.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Socket, typename Protocol>
+class reactive_socket_accept_op_base : public reactor_op
+{
+public:
+ reactive_socket_accept_op_base(socket_type socket,
+ socket_ops::state_type state, Socket& peer, const Protocol& protocol,
+ typename Protocol::endpoint* peer_endpoint, func_type complete_func)
+ : reactor_op(&reactive_socket_accept_op_base::do_perform, complete_func),
+ socket_(socket),
+ state_(state),
+ peer_(peer),
+ protocol_(protocol),
+ peer_endpoint_(peer_endpoint)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_accept_op_base* o(
+ static_cast<reactive_socket_accept_op_base*>(base));
+
+ std::size_t addrlen = o->peer_endpoint_ ? o->peer_endpoint_->capacity() : 0;
+ socket_type new_socket = invalid_socket;
+ bool result = socket_ops::non_blocking_accept(o->socket_,
+ o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0,
+ o->peer_endpoint_ ? &addrlen : 0, o->ec_, new_socket);
+
+ // On success, assign new connection to peer socket object.
+ if (new_socket >= 0)
+ {
+ socket_holder new_socket_holder(new_socket);
+ if (o->peer_endpoint_)
+ o->peer_endpoint_->resize(addrlen);
+ if (!o->peer_.assign(o->protocol_, new_socket, o->ec_))
+ new_socket_holder.release();
+ }
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ socket_ops::state_type state_;
+ Socket& peer_;
+ Protocol protocol_;
+ typename Protocol::endpoint* peer_endpoint_;
+};
+
+template <typename Socket, typename Protocol, typename Handler>
+class reactive_socket_accept_op :
+ public reactive_socket_accept_op_base<Socket, Protocol>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op);
+
+ reactive_socket_accept_op(socket_type socket,
+ socket_ops::state_type state, Socket& peer, const Protocol& protocol,
+ typename Protocol::endpoint* peer_endpoint, Handler handler)
+ : reactive_socket_accept_op_base<Socket, Protocol>(socket, state, peer,
+ protocol, peer_endpoint, &reactive_socket_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.
+ reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP

Added: trunk/boost/asio/detail/reactive_socket_connect_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_connect_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,103 @@
+//
+// detail/reactive_socket_connect_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_REACTIVE_SOCKET_CONNECT_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_CONNECT_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactive_socket_connect_op_base : public reactor_op
+{
+public:
+ reactive_socket_connect_op_base(socket_type socket, func_type complete_func)
+ : reactor_op(&reactive_socket_connect_op_base::do_perform, complete_func),
+ socket_(socket)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_connect_op_base* o(
+ static_cast<reactive_socket_connect_op_base*>(base));
+
+ return socket_ops::non_blocking_connect(o->socket_, o->ec_);
+ }
+
+private:
+ socket_type socket_;
+};
+
+template <typename Handler>
+class reactive_socket_connect_op : public reactive_socket_connect_op_base
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_connect_op);
+
+ reactive_socket_connect_op(socket_type socket, Handler handler)
+ : reactive_socket_connect_op_base(socket,
+ &reactive_socket_connect_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.
+ reactive_socket_connect_op* o
+ (static_cast<reactive_socket_connect_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ 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_REACTIVE_SOCKET_CONNECT_OP_HPP

Added: trunk/boost/asio/detail/reactive_socket_recv_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_recv_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,120 @@
+//
+// detail/reactive_socket_recv_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_REACTIVE_SOCKET_RECV_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence>
+class reactive_socket_recv_op_base : public reactor_op
+{
+public:
+ reactive_socket_recv_op_base(socket_type socket,
+ socket_ops::state_type state, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op(&reactive_socket_recv_op_base::do_perform, complete_func),
+ socket_(socket),
+ state_(state),
+ buffers_(buffers),
+ flags_(flags)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_recv_op_base* o(
+ static_cast<reactive_socket_recv_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ return socket_ops::non_blocking_recv(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ (o->state_ & socket_ops::stream_oriented),
+ o->ec_, o->bytes_transferred_);
+ }
+
+private:
+ socket_type socket_;
+ socket_ops::state_type state_;
+ MutableBufferSequence buffers_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Handler>
+class reactive_socket_recv_op :
+ public reactive_socket_recv_op_base<MutableBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op);
+
+ reactive_socket_recv_op(socket_type socket,
+ socket_ops::state_type state, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ : reactive_socket_recv_op_base<MutableBufferSequence>(socket, state,
+ buffers, flags, &reactive_socket_recv_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.
+ reactive_socket_recv_op* o(static_cast<reactive_socket_recv_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_HPP

Added: trunk/boost/asio/detail/reactive_socket_recvfrom_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_recvfrom_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,130 @@
+//
+// detail/reactive_socket_recvfrom_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_REACTIVE_SOCKET_RECVFROM_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Endpoint>
+class reactive_socket_recvfrom_op_base : public reactor_op
+{
+public:
+ reactive_socket_recvfrom_op_base(socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op(&reactive_socket_recvfrom_op_base::do_perform, complete_func),
+ socket_(socket),
+ protocol_type_(protocol_type),
+ buffers_(buffers),
+ sender_endpoint_(endpoint),
+ flags_(flags)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_recvfrom_op_base* o(
+ static_cast<reactive_socket_recvfrom_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(o->buffers_);
+
+ std::size_t addr_len = o->sender_endpoint_.capacity();
+ bool result = socket_ops::non_blocking_recvfrom(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ o->sender_endpoint_.data(), &addr_len,
+ o->ec_, o->bytes_transferred_);
+
+ if (result && !o->ec_)
+ o->sender_endpoint_.resize(addr_len);
+
+ return result;
+ }
+
+private:
+ socket_type socket_;
+ int protocol_type_;
+ MutableBufferSequence buffers_;
+ Endpoint& sender_endpoint_;
+ socket_base::message_flags flags_;
+};
+
+template <typename MutableBufferSequence, typename Endpoint, typename Handler>
+class reactive_socket_recvfrom_op :
+ public reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op);
+
+ reactive_socket_recvfrom_op(socket_type socket, int protocol_type,
+ const MutableBufferSequence& buffers, Endpoint& endpoint,
+ socket_base::message_flags flags, Handler handler)
+ : reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>(
+ socket, protocol_type, buffers, endpoint, flags,
+ &reactive_socket_recvfrom_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.
+ reactive_socket_recvfrom_op* o(
+ static_cast<reactive_socket_recvfrom_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_HPP

Added: trunk/boost/asio/detail/reactive_socket_send_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_send_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,117 @@
+//
+// detail/reactive_socket_send_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_REACTIVE_SOCKET_SEND_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence>
+class reactive_socket_send_op_base : public reactor_op
+{
+public:
+ reactive_socket_send_op_base(socket_type socket,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op(&reactive_socket_send_op_base::do_perform, complete_func),
+ socket_(socket),
+ buffers_(buffers),
+ flags_(flags)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_send_op_base* o(
+ static_cast<reactive_socket_send_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(o->buffers_);
+
+ return socket_ops::non_blocking_send(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ o->ec_, o->bytes_transferred_);
+ }
+
+private:
+ socket_type socket_;
+ ConstBufferSequence buffers_;
+ socket_base::message_flags flags_;
+};
+
+template <typename ConstBufferSequence, typename Handler>
+class reactive_socket_send_op :
+ public reactive_socket_send_op_base<ConstBufferSequence>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_send_op);
+
+ reactive_socket_send_op(socket_type socket,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ : reactive_socket_send_op_base<ConstBufferSequence>(socket,
+ buffers, flags, &reactive_socket_send_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.
+ reactive_socket_send_op* o(static_cast<reactive_socket_send_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SEND_OP_HPP

Added: trunk/boost/asio/detail/reactive_socket_sendto_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_sendto_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,120 @@
+//
+// detail/reactive_socket_sendto_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_REACTIVE_SOCKET_SENDTO_OP_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence, typename Endpoint>
+class reactive_socket_sendto_op_base : public reactor_op
+{
+public:
+ reactive_socket_sendto_op_base(socket_type socket,
+ const ConstBufferSequence& buffers, const Endpoint& endpoint,
+ socket_base::message_flags flags, func_type complete_func)
+ : reactor_op(&reactive_socket_sendto_op_base::do_perform, complete_func),
+ socket_(socket),
+ buffers_(buffers),
+ destination_(endpoint),
+ flags_(flags)
+ {
+ }
+
+ static bool do_perform(reactor_op* base)
+ {
+ reactive_socket_sendto_op_base* o(
+ static_cast<reactive_socket_sendto_op_base*>(base));
+
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(o->buffers_);
+
+ return socket_ops::non_blocking_sendto(o->socket_,
+ bufs.buffers(), bufs.count(), o->flags_,
+ o->destination_.data(), o->destination_.size(),
+ o->ec_, o->bytes_transferred_);
+ }
+
+private:
+ socket_type socket_;
+ ConstBufferSequence buffers_;
+ Endpoint destination_;
+ socket_base::message_flags flags_;
+};
+
+template <typename ConstBufferSequence, typename Endpoint, typename Handler>
+class reactive_socket_sendto_op :
+ public reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_sendto_op);
+
+ reactive_socket_sendto_op(socket_type socket,
+ const ConstBufferSequence& buffers, const Endpoint& endpoint,
+ socket_base::message_flags flags, Handler handler)
+ : reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>(socket,
+ buffers, endpoint, flags, &reactive_socket_sendto_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.
+ reactive_socket_sendto_op* o(static_cast<reactive_socket_sendto_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SENDTO_OP_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactive_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/reactive_socket_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,29 +15,38 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
 
+#include <boost/utility/addressof.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/noncopyable.hpp>
-#include <boost/asio/detail/null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_accept_op.hpp>
+#include <boost/asio/detail/reactive_socket_connect_op.hpp>
+#include <boost/asio/detail/reactive_socket_recvfrom_op.hpp>
+#include <boost/asio/detail/reactive_socket_sendto_op.hpp>
+#include <boost/asio/detail/reactive_socket_service_base.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>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
 
 template <typename Protocol>
-class reactive_socket_service
+class reactive_socket_service :
+ public reactive_socket_service_base
 {
 public:
   // The protocol type.
@@ -50,132 +59,32 @@
   typedef socket_type native_type;
 
   // The implementation type of the socket.
- class implementation_type
- : private boost::asio::detail::noncopyable
+ struct implementation_type :
+ reactive_socket_service_base::base_implementation_type
   {
- public:
     // Default constructor.
     implementation_type()
- : socket_(invalid_socket),
- flags_(0),
- protocol_(endpoint_type().protocol())
+ : protocol_(endpoint_type().protocol())
     {
     }
 
- private:
- // Only this service will have access to the internal values.
- friend class reactive_socket_service<Protocol>;
-
- // The native socket representation.
- socket_type socket_;
-
- enum
- {
- // The user wants a non-blocking socket.
- user_set_non_blocking = 1,
-
- // The implementation wants a non-blocking socket (in order to be able to
- // perform asynchronous read and write operations).
- internal_non_blocking = 2,
-
- // Helper "flag" used to determine whether the socket is non-blocking.
- non_blocking = user_set_non_blocking | internal_non_blocking,
-
- // 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.
- user_set_linger = 8
- };
-
- // Flags indicating the current state of the socket.
- unsigned char flags_;
-
     // The protocol associated with the socket.
     protocol_type protocol_;
-
- // Per-descriptor data used by the reactor.
- reactor::per_descriptor_data reactor_data_;
   };
 
   // Constructor.
   reactive_socket_service(boost::asio::io_service& io_service)
- : io_service_impl_(use_service<io_service_impl>(io_service)),
- reactor_(use_service<reactor>(io_service))
+ : reactive_socket_service_base(io_service)
   {
- reactor_.init_task();
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
-
- // Construct a new socket implementation.
- void construct(implementation_type& impl)
- {
- impl.socket_ = invalid_socket;
- impl.flags_ = 0;
- }
-
- // Destroy a socket implementation.
- void destroy(implementation_type& impl)
- {
- if (impl.socket_ != invalid_socket)
- {
- reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
-
- if (impl.flags_ & implementation_type::non_blocking)
- {
- ioctl_arg_type non_blocking = 0;
- boost::system::error_code ignored_ec;
- socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec);
- impl.flags_ &= ~implementation_type::non_blocking;
- }
-
- if (impl.flags_ & implementation_type::user_set_linger)
- {
- ::linger opt;
- opt.l_onoff = 0;
- opt.l_linger = 0;
- boost::system::error_code ignored_ec;
- socket_ops::setsockopt(impl.socket_,
- SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
- }
-
- boost::system::error_code ignored_ec;
- socket_ops::close(impl.socket_, ignored_ec);
-
- impl.socket_ = invalid_socket;
- }
   }
 
   // Open a new socket implementation.
   boost::system::error_code open(implementation_type& impl,
       const protocol_type& protocol, boost::system::error_code& ec)
   {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- socket_holder sock(socket_ops::socket(protocol.family(),
- protocol.type(), protocol.protocol(), ec));
- if (sock.get() == invalid_socket)
- return ec;
-
- if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_))
- {
- ec = boost::system::error_code(err,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- impl.socket_ = sock.release();
- impl.flags_ = 0;
- impl.protocol_ = protocol;
- ec = boost::system::error_code();
+ if (!do_open(impl, protocol.family(),
+ protocol.type(), protocol.protocol(), ec))
+ impl.protocol_ = protocol;
     return ec;
   }
 
@@ -184,56 +93,8 @@
       const protocol_type& protocol, const native_type& native_socket,
       boost::system::error_code& ec)
   {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- if (int err = reactor_.register_descriptor(
- native_socket, impl.reactor_data_))
- {
- ec = boost::system::error_code(err,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- impl.socket_ = native_socket;
- impl.flags_ = 0;
- impl.protocol_ = protocol;
- ec = boost::system::error_code();
- return ec;
- }
-
- // Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return impl.socket_ != invalid_socket;
- }
-
- // Destroy a socket implementation.
- boost::system::error_code close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
-
- if (impl.flags_ & implementation_type::non_blocking)
- {
- ioctl_arg_type non_blocking = 0;
- boost::system::error_code ignored_ec;
- socket_ops::ioctl(impl.socket_, FIONBIO, &non_blocking, ignored_ec);
- impl.flags_ &= ~implementation_type::non_blocking;
- }
-
- if (socket_ops::close(impl.socket_, ec) == socket_error_retval)
- return ec;
-
- impl.socket_ = invalid_socket;
- }
-
- ec = boost::system::error_code();
+ if (!do_assign(impl, protocol.type(), native_socket, ec))
+ impl.protocol_ = protocol;
     return ec;
   }
 
@@ -243,153 +104,23 @@
     return impl.socket_;
   }
 
- // Cancel all operations associated with the socket.
- boost::system::error_code cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- reactor_.cancel_ops(impl.socket_, impl.reactor_data_);
- ec = boost::system::error_code();
- return ec;
- }
-
- // Determine whether the socket is at the out-of-band data mark.
- bool at_mark(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return false;
- }
-
-#if defined(SIOCATMARK)
- boost::asio::detail::ioctl_arg_type value = 0;
- socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec);
-# if defined(ENOTTY)
- if (ec.value() == ENOTTY)
- ec = boost::asio::error::not_socket;
-# endif // defined(ENOTTY)
-#else // defined(SIOCATMARK)
- int value = sockatmark(impl.socket_);
- if (value == -1)
- ec = boost::system::error_code(errno,
- boost::asio::error::get_system_category());
- else
- ec = boost::system::error_code();
-#endif // defined(SIOCATMARK)
- return ec ? false : value != 0;
- }
-
- // Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- boost::asio::detail::ioctl_arg_type value = 0;
- socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec);
-#if defined(ENOTTY)
- if (ec.value() == ENOTTY)
- ec = boost::asio::error::not_socket;
-#endif // defined(ENOTTY)
- return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value);
- }
-
   // Bind the socket to the specified local endpoint.
   boost::system::error_code bind(implementation_type& impl,
       const endpoint_type& endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
     socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
     return ec;
   }
 
- // Place the socket into the state where it will listen for new connections.
- boost::system::error_code listen(implementation_type& impl, int backlog,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::listen(impl.socket_, backlog, ec);
- return ec;
- }
-
   // Set a socket option.
   template <typename Option>
   boost::system::error_code set_option(implementation_type& impl,
       const Option& option, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- if (option.level(impl.protocol_) == custom_socket_option_level
- && option.name(impl.protocol_) == enable_connection_aborted_option)
- {
- if (option.size(impl.protocol_) != sizeof(int))
- {
- ec = boost::asio::error::invalid_argument;
- }
- else
- {
- if (*reinterpret_cast<const int*>(option.data(impl.protocol_)))
- impl.flags_ |= implementation_type::enable_connection_aborted;
- else
- impl.flags_ &= ~implementation_type::enable_connection_aborted;
- ec = boost::system::error_code();
- }
- return ec;
- }
- else
- {
- if (option.level(impl.protocol_) == SOL_SOCKET
- && option.name(impl.protocol_) == SO_LINGER)
- {
- impl.flags_ |= implementation_type::user_set_linger;
- }
-
- socket_ops::setsockopt(impl.socket_,
- option.level(impl.protocol_), option.name(impl.protocol_),
- option.data(impl.protocol_), option.size(impl.protocol_), ec);
-
-#if defined(__MACH__) && defined(__APPLE__) \
-|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
- // To implement portable behaviour for SO_REUSEADDR with UDP sockets we
- // need to also set SO_REUSEPORT on BSD-based platforms.
- if (!ec && impl.protocol_.type() == SOCK_DGRAM
- && option.level(impl.protocol_) == SOL_SOCKET
- && option.name(impl.protocol_) == SO_REUSEADDR)
- {
- boost::system::error_code ignored_ec;
- socket_ops::setsockopt(impl.socket_, SOL_SOCKET, SO_REUSEPORT,
- option.data(impl.protocol_), option.size(impl.protocol_),
- ignored_ec);
- }
-#endif
-
- return ec;
- }
+ socket_ops::setsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), option.size(impl.protocol_), ec);
+ return ec;
   }
 
   // Set a socket option.
@@ -397,78 +128,12 @@
   boost::system::error_code get_option(const implementation_type& impl,
       Option& option, boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- if (option.level(impl.protocol_) == custom_socket_option_level
- && option.name(impl.protocol_) == enable_connection_aborted_option)
- {
- if (option.size(impl.protocol_) != sizeof(int))
- {
- ec = boost::asio::error::invalid_argument;
- }
- else
- {
- int* target = reinterpret_cast<int*>(option.data(impl.protocol_));
- if (impl.flags_ & implementation_type::enable_connection_aborted)
- *target = 1;
- else
- *target = 0;
- option.resize(impl.protocol_, sizeof(int));
- ec = boost::system::error_code();
- }
- return ec;
- }
- else
- {
- size_t size = option.size(impl.protocol_);
- socket_ops::getsockopt(impl.socket_,
- option.level(impl.protocol_), option.name(impl.protocol_),
- option.data(impl.protocol_), &size, ec);
- if (!ec)
- option.resize(impl.protocol_, size);
- return ec;
- }
- }
-
- // Perform an IO control command on the socket.
- template <typename IO_Control_Command>
- boost::system::error_code io_control(implementation_type& impl,
- IO_Control_Command& command, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::ioctl(impl.socket_, command.name(),
- static_cast<ioctl_arg_type*>(command.data()), ec);
-
- // When updating the non-blocking mode we always perform the ioctl
- // syscall, even if the flags would otherwise indicate that the socket is
- // already in the correct state. This ensures that the underlying socket
- // is put into the state that has been requested by the user. If the ioctl
- // syscall was successful then we need to update the flags to match.
- if (!ec && command.name() == static_cast<int>(FIONBIO))
- {
- if (*static_cast<ioctl_arg_type*>(command.data()))
- {
- impl.flags_ |= implementation_type::user_set_non_blocking;
- }
- else
- {
- // Clearing the non-blocking mode always overrides any internally-set
- // non-blocking flag. Any subsequent asynchronous operations will need
- // to re-enable non-blocking I/O.
- impl.flags_ &= ~(implementation_type::user_set_non_blocking
- | implementation_type::internal_non_blocking);
- }
- }
-
+ std::size_t size = option.size(impl.protocol_);
+ socket_ops::getsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), &size, ec);
+ if (!ec)
+ option.resize(impl.protocol_, size);
     return ec;
   }
 
@@ -476,12 +141,6 @@
   endpoint_type local_endpoint(const implementation_type& impl,
       boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return endpoint_type();
- }
-
     endpoint_type endpoint;
     std::size_t addr_len = endpoint.capacity();
     if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
@@ -494,218 +153,15 @@
   endpoint_type remote_endpoint(const implementation_type& impl,
       boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return endpoint_type();
- }
-
     endpoint_type endpoint;
     std::size_t addr_len = endpoint.capacity();
- if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
+ if (socket_ops::getpeername(impl.socket_,
+ endpoint.data(), &addr_len, false, ec))
       return endpoint_type();
     endpoint.resize(addr_len);
     return endpoint;
   }
 
- /// Disable sends or receives on the socket.
- boost::system::error_code shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::shutdown(impl.socket_, what, ec);
- return ec;
- }
-
- // Send the given data to the peer.
- template <typename ConstBufferSequence>
- size_t send(implementation_type& impl, const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- 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 && bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Send the data.
- for (;;)
- {
- // Try to complete the operation without blocking.
- int bytes_sent = socket_ops::send(impl.socket_,
- bufs.buffers(), bufs.count(), flags, ec);
-
- // Check if operation succeeded.
- if (bytes_sent >= 0)
- return bytes_sent;
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for socket to become ready.
- if (socket_ops::poll_write(impl.socket_, ec) < 0)
- return 0;
- }
- }
-
- // Wait until data can be sent without blocking.
- size_t send(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- // Wait for socket to become ready.
- socket_ops::poll_write(impl.socket_, ec);
-
- return 0;
- }
-
- template <typename ConstBufferSequence>
- class send_op_base : public reactor_op
- {
- public:
- 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),
- buffers_(buffers),
- flags_(flags)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- send_op_base* o(static_cast<send_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Send the data.
- 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)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- private:
- socket_type socket_;
- ConstBufferSequence buffers_;
- socket_base::message_flags flags_;
- };
-
- template <typename ConstBufferSequence, typename Handler>
- class send_op : public send_op_base<ConstBufferSequence>
- {
- public:
- 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)
- {
- }
-
- 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:
- 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)
- {
- // 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
   // sent.
   template <typename ConstBufferSequence>
@@ -713,148 +169,25 @@
       const endpoint_type& destination, socket_base::message_flags flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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.buffers(),
- bufs.count(), flags, destination.data(), destination.size(), ec);
-
- // Check if operation succeeded.
- if (bytes_sent >= 0)
- return bytes_sent;
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for socket to become ready.
- if (socket_ops::poll_write(impl.socket_, ec) < 0)
- return 0;
- }
+ return socket_ops::sync_sendto(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags,
+ destination.data(), destination.size(), ec);
   }
 
   // Wait until data can be sent without blocking.
   size_t send_to(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, const endpoint_type&,
+ const endpoint_type&, socket_base::message_flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for socket to become ready.
     socket_ops::poll_write(impl.socket_, ec);
 
     return 0;
   }
 
- template <typename ConstBufferSequence>
- class send_to_op_base : public reactor_op
- {
- public:
- 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),
- buffers_(buffers),
- destination_(endpoint),
- flags_(flags)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- send_to_op_base* o(static_cast<send_to_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Send the data.
- 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)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- private:
- socket_type socket_;
- 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>
@@ -864,235 +197,31 @@
       Handler handler)
   {
     // 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);
+ typedef reactive_socket_sendto_op<ConstBufferSequence,
+ endpoint_type, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler);
 
- start_op(impl, reactor::write_op, ptr.get(), true, false);
- ptr.release();
+ start_op(impl, reactor::write_op, p.p, true, false);
+ p.v = p.p = 0;
   }
 
   // Start an asynchronous wait until data can be sent without blocking.
   template <typename Handler>
   void async_send_to(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, const endpoint_type&, Handler handler)
+ const endpoint_type&, socket_base::message_flags, 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);
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(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.
- template <typename MutableBufferSequence>
- size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- 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 && bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Receive some data.
- for (;;)
- {
- // Try to complete the operation without blocking.
- int bytes_recvd = socket_ops::recv(impl.socket_,
- bufs.buffers(), bufs.count(), flags, ec);
-
- // Check if operation succeeded.
- if (bytes_recvd > 0)
- return bytes_recvd;
-
- // Check for EOF.
- if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM)
- {
- ec = boost::asio::error::eof;
- return 0;
- }
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for socket to become ready.
- if (socket_ops::poll_read(impl.socket_, ec) < 0)
- return 0;
- }
- }
-
- // Wait until data can be received without blocking.
- size_t receive(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- // Wait for socket to become ready.
- socket_ops::poll_read(impl.socket_, ec);
-
- return 0;
- }
-
- template <typename MutableBufferSequence>
- class receive_op_base : public reactor_op
- {
- public:
- receive_op_base(socket_type socket, int protocol_type,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, func_type complete_func)
- : reactor_op(&receive_op_base::do_perform, complete_func),
- socket_(socket),
- protocol_type_(protocol_type),
- buffers_(buffers),
- flags_(flags)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- receive_op_base* o(static_cast<receive_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Receive some data.
- 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.
- if (ec == boost::asio::error::interrupted)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- private:
- socket_type socket_;
- int protocol_type_;
- MutableBufferSequence buffers_;
- socket_base::message_flags flags_;
- };
-
- template <typename MutableBufferSequence, typename Handler>
- class receive_op : public receive_op_base<MutableBufferSequence>
- {
- 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)
- {
- }
-
- 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);
- }
- }
-
- private:
- Handler 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(), (flags & socket_base::message_out_of_band) == 0,
- (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.
- template <typename Handler>
- void async_receive(implementation_type& impl, const null_buffers&,
- socket_base::message_flags flags, 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);
-
- start_op(impl,
- (flags & socket_base::message_out_of_band)
- ? reactor::except_op : reactor::read_op,
- ptr.get(), false, false);
- ptr.release();
+ start_op(impl, reactor::write_op, p.p, false, false);
+ p.v = p.p = 0;
   }
 
   // Receive a datagram with the endpoint of the sender. Returns the number of
@@ -1103,47 +232,18 @@
       endpoint_type& sender_endpoint, socket_base::message_flags flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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.buffers(),
- bufs.count(), flags, sender_endpoint.data(), &addr_len, ec);
-
- // Check if operation succeeded.
- if (bytes_recvd > 0)
- {
- sender_endpoint.resize(addr_len);
- return bytes_recvd;
- }
-
- // Check for EOF.
- if (bytes_recvd == 0 && impl.protocol_.type() == SOCK_STREAM)
- {
- ec = boost::asio::error::eof;
- return 0;
- }
-
- // Operation failed.
- if ((impl.flags_ & implementation_type::user_set_non_blocking)
- || (ec != boost::asio::error::would_block
- && ec != boost::asio::error::try_again))
- return 0;
-
- // Wait for socket to become ready.
- if (socket_ops::poll_read(impl.socket_, ec) < 0)
- return 0;
- }
+ std::size_t addr_len = sender_endpoint.capacity();
+ std::size_t bytes_recvd = socket_ops::sync_recvfrom(
+ impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
+ flags, sender_endpoint.data(), &addr_len, ec);
+
+ if (!ec)
+ sender_endpoint.resize(addr_len);
+
+ return bytes_recvd;
   }
 
   // Wait until data can be received without blocking.
@@ -1151,12 +251,6 @@
       endpoint_type& sender_endpoint, socket_base::message_flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for socket to become ready.
     socket_ops::poll_read(impl.socket_, ec);
 
@@ -1166,105 +260,6 @@
     return 0;
   }
 
- template <typename MutableBufferSequence>
- class receive_from_op_base : public reactor_op
- {
- public:
- receive_from_op_base(socket_type socket, int protocol_type,
- const MutableBufferSequence& buffers, endpoint_type& endpoint,
- 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),
- buffers_(buffers),
- sender_endpoint_(endpoint),
- flags_(flags)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- receive_from_op_base* o(static_cast<receive_from_op_base*>(base));
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> bufs(o->buffers_);
-
- for (;;)
- {
- // Receive some data.
- 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.
- if (ec == boost::asio::error::interrupted)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
-
- o->sender_endpoint_.resize(addr_len);
- o->ec_ = ec;
- o->bytes_transferred_ = (bytes < 0 ? 0 : bytes);
- return true;
- }
- }
-
- private:
- socket_type socket_;
- int protocol_type_;
- 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.
@@ -1274,18 +269,20 @@
       socket_base::message_flags flags, Handler 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);
+ typedef reactive_socket_recvfrom_op<MutableBufferSequence,
+ endpoint_type, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
     int protocol_type = impl.protocol_.type();
- handler_ptr<alloc_traits> ptr(raw_ptr, impl.socket_,
- protocol_type, buffers, sender_endpoint, flags, handler);
+ p.p = new (p.v) op(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();
+ p.p, true, false);
+ p.v = p.p = 0;
   }
 
   // Wait until data can be received without blocking.
@@ -1295,10 +292,11 @@
       socket_base::message_flags flags, 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);
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
 
     // Reset endpoint since it can be given no sensible value at this time.
     sender_endpoint = endpoint_type();
@@ -1306,8 +304,8 @@
     start_op(impl,
         (flags & socket_base::message_out_of_band)
           ? reactor::except_op : reactor::read_op,
- ptr.get(), false, false);
- ptr.release();
+ p.p, false, false);
+ p.v = p.p = 0;
   }
 
   // Accept a new connection.
@@ -1315,12 +313,6 @@
   boost::system::error_code accept(implementation_type& impl,
       Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
     // We cannot accept a socket that is already open.
     if (peer.is_open())
     {
@@ -1328,181 +320,22 @@
       return ec;
     }
 
- // Accept a socket.
- for (;;)
- {
- // Try to complete the operation without blocking.
- socket_holder new_socket;
- std::size_t addr_len = 0;
- if (peer_endpoint)
- {
- addr_len = peer_endpoint->capacity();
- new_socket.reset(socket_ops::accept(impl.socket_,
- peer_endpoint->data(), &addr_len, ec));
- }
- else
- {
- new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec));
- }
-
- // Check if operation succeeded.
- if (new_socket.get() >= 0)
- {
- if (peer_endpoint)
- peer_endpoint->resize(addr_len);
- peer.assign(impl.protocol_, new_socket.get(), ec);
- if (!ec)
- new_socket.release();
- return ec;
- }
-
- // Operation failed.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- {
- if (impl.flags_ & implementation_type::user_set_non_blocking)
- return ec;
- // Fall through to retry operation.
- }
- else if (ec == boost::asio::error::connection_aborted)
- {
- if (impl.flags_ & implementation_type::enable_connection_aborted)
- return ec;
- // Fall through to retry operation.
- }
-#if defined(EPROTO)
- else if (ec.value() == EPROTO)
- {
- if (impl.flags_ & implementation_type::enable_connection_aborted)
- return ec;
- // Fall through to retry operation.
- }
-#endif // defined(EPROTO)
- else
- return ec;
-
- // Wait for socket to become ready.
- if (socket_ops::poll_read(impl.socket_, ec) < 0)
- return ec;
- }
- }
-
- template <typename Socket>
- class accept_op_base : public reactor_op
- {
- public:
- 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),
- peer_(peer),
- protocol_(protocol),
- peer_endpoint_(peer_endpoint),
- enable_connection_aborted_(enable_connection_aborted)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- 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;
- std::size_t* addr_len_p = 0;
- socket_addr_type* addr = 0;
- if (o->peer_endpoint_)
- {
- 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)
- continue;
-
- // Check if we need to run the operation again.
- if (ec == boost::asio::error::would_block
- || ec == boost::asio::error::try_again)
- return false;
- if (ec == boost::asio::error::connection_aborted
- && !o->enable_connection_aborted_)
- return false;
-#if defined(EPROTO)
- 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 (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;
- }
- }
-
- private:
- socket_type socket_;
- Socket& peer_;
- protocol_type protocol_;
- endpoint_type* peer_endpoint_;
- bool enable_connection_aborted_;
- };
+ std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
+ socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
+ impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
+ peer_endpoint ? &addr_len : 0, ec));
 
- 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)
+ // On success, assign new connection to peer socket object.
+ if (new_socket.get() >= 0)
     {
+ if (peer_endpoint)
+ peer_endpoint->resize(addr_len);
+ if (!peer.assign(impl.protocol_, new_socket.get(), ec))
+ new_socket.release();
     }
 
- 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_;
- };
+ return ec;
+ }
 
   // Start an asynchronous accept. The peer and peer_endpoint objects
   // must be valid until the accept's handler is invoked.
@@ -1511,230 +344,41 @@
       endpoint_type* peer_endpoint, Handler handler)
   {
     // 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);
+ typedef reactive_socket_accept_op<Socket, Protocol, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, impl.state_, peer,
+ impl.protocol_, peer_endpoint, handler);
 
- start_accept_op(impl, ptr.get(), peer.is_open());
- ptr.release();
+ start_accept_op(impl, p.p, peer.is_open());
+ p.v = p.p = 0;
   }
 
   // Connect the socket to the specified endpoint.
   boost::system::error_code connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- // Perform the connect operation.
- socket_ops::connect(impl.socket_,
+ socket_ops::sync_connect(impl.socket_,
         peer_endpoint.data(), peer_endpoint.size(), ec);
- if (ec != boost::asio::error::in_progress
- && ec != boost::asio::error::would_block)
- {
- // The connect operation finished immediately.
- return ec;
- }
-
- // Wait for socket to become ready.
- if (socket_ops::poll_connect(impl.socket_, ec) < 0)
- return ec;
-
- // Get the error code from the connect operation.
- int connect_error = 0;
- size_t connect_error_len = sizeof(connect_error);
- if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_ERROR,
- &connect_error, &connect_error_len, ec) == socket_error_retval)
- return ec;
-
- // Return the result of the connect operation.
- ec = boost::system::error_code(connect_error,
- boost::asio::error::get_system_category());
     return ec;
   }
 
- class connect_op_base : public reactor_op
- {
- public:
- connect_op_base(socket_type socket, func_type complete_func)
- : reactor_op(&connect_op_base::do_perform, complete_func),
- socket_(socket)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- 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(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)
- {
- o->ec_ = boost::system::error_code(connect_error,
- boost::asio::error::get_system_category());
- }
-
- return true;
- }
-
- 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)
- {
- }
-
- 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:
- Handler handler_;
- };
-
   // Start an asynchronous connect.
   template <typename Handler>
   void async_connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, Handler handler)
   {
     // 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);
+ typedef reactive_socket_connect_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, handler);
 
- start_connect_op(impl, ptr.get(), peer_endpoint);
- ptr.release();
+ start_connect_op(impl, p.p, peer_endpoint.data(), peer_endpoint.size());
+ p.v = p.p = 0;
   }
-
-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 (is_open(impl))
- {
- if (!non_blocking || is_non_blocking(impl)
- || set_non_blocking(impl, op->ec_))
- {
- reactor_.start_op(op_type, impl.socket_,
- impl.reactor_data_, op, non_blocking);
- return;
- }
- }
- else
- op->ec_ = boost::asio::error::bad_descriptor;
- }
-
- 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
- {
- op->ec_ = boost::asio::error::already_open;
- io_service_impl_.post_immediate_completion(op);
- }
- }
-
- // 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, false);
- 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_;
 };
 
 } // namespace detail
@@ -1743,4 +387,6 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_HPP

Added: trunk/boost/asio/detail/reactive_socket_service_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/reactive_socket_service_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,300 @@
+//
+// detail/reactive_socket_service_base.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_REACTIVE_SOCKET_SERVICE_BASE_HPP
+#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/buffer_sequence_adapter.hpp>
+#include <boost/asio/detail/reactive_null_buffers_op.hpp>
+#include <boost/asio/detail/reactive_socket_recv_op.hpp>
+#include <boost/asio/detail/reactive_socket_send_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>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class reactive_socket_service_base
+{
+public:
+ // The native type of a socket.
+ typedef socket_type native_type;
+
+ // The implementation type of the socket.
+ struct base_implementation_type
+ {
+ // The native socket representation.
+ socket_type socket_;
+
+ // The current state of the socket.
+ socket_ops::state_type state_;
+
+ // Per-descriptor data used by the reactor.
+ reactor::per_descriptor_data reactor_data_;
+ };
+
+ // Constructor.
+ BOOST_ASIO_DECL reactive_socket_service_base(
+ boost::asio::io_service& io_service);
+
+ // Destroy all user-defined handler objects owned by the service.
+ BOOST_ASIO_DECL void shutdown_service();
+
+ // Construct a new socket implementation.
+ BOOST_ASIO_DECL void construct(base_implementation_type& impl);
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
+
+ // Determine whether the socket is open.
+ bool is_open(const base_implementation_type& impl) const
+ {
+ return impl.socket_ != invalid_socket;
+ }
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code close(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Get the native socket representation.
+ native_type native(base_implementation_type& impl)
+ {
+ return impl.socket_;
+ }
+
+ // Cancel all operations associated with the socket.
+ BOOST_ASIO_DECL boost::system::error_code cancel(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Determine whether the socket is at the out-of-band data mark.
+ bool at_mark(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::sockatmark(impl.socket_, ec);
+ }
+
+ // Determine the number of bytes available for reading.
+ std::size_t available(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::available(impl.socket_, ec);
+ }
+
+ // Place the socket into the state where it will listen for new connections.
+ boost::system::error_code listen(base_implementation_type& impl,
+ int backlog, boost::system::error_code& ec)
+ {
+ socket_ops::listen(impl.socket_, backlog, ec);
+ return ec;
+ }
+
+ // Perform an IO control command on the socket.
+ template <typename IO_Control_Command>
+ boost::system::error_code io_control(base_implementation_type& impl,
+ IO_Control_Command& command, boost::system::error_code& ec)
+ {
+ socket_ops::ioctl(impl.socket_, impl.state_, command.name(),
+ static_cast<ioctl_arg_type*>(command.data()), ec);
+ return ec;
+ }
+
+ /// Disable sends or receives on the socket.
+ boost::system::error_code shutdown(base_implementation_type& impl,
+ socket_base::shutdown_type what, boost::system::error_code& ec)
+ {
+ socket_ops::shutdown(impl.socket_, what, ec);
+ return ec;
+ }
+
+ // Send the given data to the peer.
+ template <typename ConstBufferSequence>
+ size_t send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_send(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, ec);
+
+ return 0;
+ }
+
+ // 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(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_send_op<ConstBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, buffers, flags, handler);
+
+ start_op(impl, reactor::write_op, p.p, true,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler>
+ void async_send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
+
+ start_op(impl, reactor::write_op, p.p, false, false);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data from the peer. Returns the number of bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recv(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, ec);
+
+ return 0;
+ }
+
+ // 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(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_socket_recv_op<MutableBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, (flags & socket_base::message_out_of_band) == 0,
+ ((impl.state_ & socket_ops::stream_oriented)
+ && buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::all_empty(buffers)));
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler>
+ void async_receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef reactive_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
+
+ start_op(impl,
+ (flags & socket_base::message_out_of_band)
+ ? reactor::except_op : reactor::read_op,
+ p.p, false, false);
+ p.v = p.p = 0;
+ }
+
+protected:
+ // Open a new socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_open(
+ base_implementation_type& impl, int af,
+ int type, int protocol, boost::system::error_code& ec);
+
+ // Assign a native socket to a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_assign(
+ base_implementation_type& impl, int type,
+ const native_type& native_socket, boost::system::error_code& ec);
+
+ // Start the asynchronous read or write operation.
+ BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type,
+ reactor_op* op, bool non_blocking, bool noop);
+
+ // Start the asynchronous accept operation.
+ BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl,
+ reactor_op* op, bool peer_is_open);
+
+ // Start the asynchronous connect operation.
+ BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl,
+ reactor_op* op, const socket_addr_type* addr, size_t addrlen);
+
+ // The selector that performs event demultiplexing for the service.
+ reactor& reactor_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/reactive_socket_service_base.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_HPP

Modified: trunk/boost/asio/detail/reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/reactor.hpp (original)
+++ trunk/boost/asio/detail/reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactor.hpp
-// ~~~~~~~~~~~
+// detail/reactor.hpp
+// ~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,8 +15,6 @@
 # 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)
@@ -29,6 +27,4 @@
 # include <boost/asio/detail/select_reactor.hpp>
 #endif
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_REACTOR_HPP

Modified: trunk/boost/asio/detail/reactor_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/reactor_fwd.hpp (original)
+++ trunk/boost/asio/detail/reactor_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactor_fwd.hpp
-// ~~~~~~~~~~~~~~~
+// detail/reactor_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,26 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.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>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/select_reactor_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+# include <boost/asio/detail/epoll_reactor_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+# include <boost/asio/detail/kqueue_reactor_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+# include <boost/asio/detail/dev_poll_reactor_fwd.hpp>
+#else
+# include <boost/asio/detail/select_reactor_fwd.hpp>
+#endif
 
 namespace boost {
 namespace asio {
 namespace detail {
 
 #if defined(BOOST_ASIO_HAS_IOCP)
-typedef select_reactor<true> reactor;
+typedef select_reactor reactor;
 #elif defined(BOOST_ASIO_HAS_EPOLL)
 typedef epoll_reactor reactor;
 #elif defined(BOOST_ASIO_HAS_KQUEUE)
@@ -36,13 +42,11 @@
 #elif defined(BOOST_ASIO_HAS_DEV_POLL)
 typedef dev_poll_reactor reactor;
 #else
-typedef select_reactor<false> reactor;
+typedef select_reactor reactor;
 #endif
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_REACTOR_FWD_HPP

Modified: trunk/boost/asio/detail/reactor_op.hpp
==============================================================================
--- trunk/boost/asio/detail/reactor_op.hpp (original)
+++ trunk/boost/asio/detail/reactor_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactor_op.hpp
-// ~~~~~~~~~~~~
+// detail/reactor_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/operation.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// reactor_op_queue.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/reactor_op_queue.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/error.hpp>
+#include <boost/asio/detail/config.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>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Added: trunk/boost/asio/detail/regex_fwd.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/regex_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,31 @@
+//
+// detail/regex_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_REGEX_FWD_HPP
+#define BOOST_ASIO_DETAIL_REGEX_FWD_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/regex_fwd.hpp>
+#include <boost/regex/v4/match_flags.hpp>
+
+namespace boost {
+
+template <class BidiIterator>
+class sub_match;
+
+template <class BidiIterator, class Allocator>
+class match_results;
+
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_REGEX_FWD_HPP

Added: trunk/boost/asio/detail/resolve_endpoint_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/resolve_endpoint_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,118 @@
+//
+// detail/resolve_endpoint_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_RESOLVER_ENDPOINT_OP_HPP
+#define BOOST_ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/basic_resolver_iterator.hpp>
+#include <boost/asio/detail/bind_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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Protocol, typename Handler>
+class resolve_endpoint_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(resolve_endpoint_op);
+
+ typedef typename Protocol::endpoint endpoint_type;
+ typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type;
+
+ resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token,
+ const endpoint_type& endpoint, io_service_impl& ios, Handler handler)
+ : operation(&resolve_endpoint_op::do_complete),
+ cancel_token_(cancel_token),
+ endpoint_(endpoint),
+ io_service_impl_(ios),
+ 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 operation object.
+ resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ if (owner && owner != &o->io_service_impl_)
+ {
+ // The operation is being run on the worker io_service. Time to perform
+ // the resolver operation.
+
+ // Perform the blocking endpoint resolution operation.
+ char host_name[NI_MAXHOST];
+ char service_name[NI_MAXSERV];
+ socket_ops::background_getnameinfo(o->cancel_token_, o->endpoint_.data(),
+ o->endpoint_.size(), host_name, NI_MAXHOST, service_name, NI_MAXSERV,
+ o->endpoint_.protocol().type(), o->ec_);
+ o->iter_ = iterator_type::create(o->endpoint_, host_name, service_name);
+
+ // Pass operation back to main io_service for completion.
+ o->io_service_impl_.post_deferred_completion(o);
+ p.v = p.p = 0;
+ }
+ else
+ {
+ // The operation has been returned to the main io_service. 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+ }
+
+private:
+ socket_ops::weak_cancel_token_type cancel_token_;
+ endpoint_type endpoint_;
+ io_service_impl& io_service_impl_;
+ Handler handler_;
+ boost::system::error_code ec_;
+ iterator_type iter_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_RESOLVER_ENDPOINT_OP_HPP

Added: trunk/boost/asio/detail/resolve_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/resolve_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,128 @@
+//
+// detail/resolve_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_RESOLVE_OP_HPP
+#define BOOST_ASIO_DETAIL_RESOLVE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/ip/basic_resolver_iterator.hpp>
+#include <boost/asio/ip/basic_resolver_query.hpp>
+#include <boost/asio/detail/bind_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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Protocol, typename Handler>
+class resolve_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(resolve_op);
+
+ typedef boost::asio::ip::basic_resolver_query<Protocol> query_type;
+ typedef boost::asio::ip::basic_resolver_iterator<Protocol> iterator_type;
+
+ resolve_op(socket_ops::weak_cancel_token_type cancel_token,
+ const query_type& query, io_service_impl& ios, Handler handler)
+ : operation(&resolve_op::do_complete),
+ cancel_token_(cancel_token),
+ query_(query),
+ io_service_impl_(ios),
+ handler_(handler),
+ addrinfo_(0)
+ {
+ }
+
+ ~resolve_op()
+ {
+ if (addrinfo_)
+ socket_ops::freeaddrinfo(addrinfo_);
+ }
+
+ 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.
+ resolve_op* o(static_cast<resolve_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ if (owner && owner != &o->io_service_impl_)
+ {
+ // The operation is being run on the worker io_service. Time to perform
+ // the resolver operation.
+
+ // Perform the blocking host resolution operation.
+ socket_ops::background_getaddrinfo(o->cancel_token_,
+ o->query_.host_name().c_str(), o->query_.service_name().c_str(),
+ o->query_.hints(), &o->addrinfo_, o->ec_);
+
+ // Pass operation back to main io_service for completion.
+ o->io_service_impl_.post_deferred_completion(o);
+ p.v = p.p = 0;
+ }
+ else
+ {
+ // The operation has been returned to the main io_service. 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_, iterator_type());
+ p.h = boost::addressof(handler.handler_);
+ if (o->addrinfo_)
+ {
+ handler.arg2_ = iterator_type::create(o->addrinfo_,
+ o->query_.host_name(), o->query_.service_name());
+ }
+ p.reset();
+
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+ }
+
+private:
+ socket_ops::weak_cancel_token_type cancel_token_;
+ query_type query_;
+ io_service_impl& io_service_impl_;
+ Handler handler_;
+ boost::system::error_code ec_;
+ boost::asio::detail::addrinfo_type* addrinfo_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_RESOLVE_OP_HPP

Modified: trunk/boost/asio/detail/resolver_service.hpp
==============================================================================
--- trunk/boost/asio/detail/resolver_service.hpp (original)
+++ trunk/boost/asio/detail/resolver_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// resolver_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/resolver_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,69 +15,26 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <cstring>
-#include <boost/scoped_ptr.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.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>
-#include <boost/asio/detail/thread.hpp>
+#include <boost/asio/detail/resolve_endpoint_op.hpp>
+#include <boost/asio/detail/resolve_op.hpp>
+#include <boost/asio/detail/resolver_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
 template <typename Protocol>
-class resolver_service
- : public boost::asio::detail::service_base<resolver_service<Protocol> >
+class resolver_service : public resolver_service_base
 {
-private:
- // Helper class to perform exception-safe cleanup of addrinfo objects.
- class auto_addrinfo
- : private boost::asio::detail::noncopyable
- {
- public:
- explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai)
- : ai_(ai)
- {
- }
-
- ~auto_addrinfo()
- {
- if (ai_)
- socket_ops::freeaddrinfo(ai_);
- }
-
- operator boost::asio::detail::addrinfo_type*()
- {
- return ai_;
- }
-
- private:
- boost::asio::detail::addrinfo_type* ai_;
- };
-
 public:
- // The implementation type of the resolver. The shared pointer is used as a
- // cancellation token to indicate to the background thread that the operation
- // has been cancelled.
- typedef boost::shared_ptr<void> implementation_type;
- struct noop_deleter { void operator()(void*) {} };
+ // The implementation type of the resolver. A cancellation token is used to
+ // indicate to the background thread that the operation has been cancelled.
+ typedef socket_ops::shared_cancel_token_type implementation_type;
 
   // The endpoint type.
   typedef typename Protocol::endpoint endpoint_type;
@@ -90,55 +47,8 @@
 
   // Constructor.
   resolver_service(boost::asio::io_service& io_service)
- : 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)
- {
- }
-
- // Destructor.
- ~resolver_service()
- {
- shutdown_service();
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
+ : resolver_service_base(io_service)
   {
- work_.reset();
- if (work_io_service_)
- {
- work_io_service_->stop();
- if (work_thread_)
- {
- work_thread_->join();
- work_thread_.reset();
- }
- work_io_service_.reset();
- }
- }
-
- // Construct a new resolver implementation.
- void construct(implementation_type& impl)
- {
- impl.reset(static_cast<void*>(0), noop_deleter());
- }
-
- // Destroy a resolver implementation.
- void destroy(implementation_type&)
- {
- }
-
- // Cancel pending asynchronous operations.
- void cancel(implementation_type& impl)
- {
- impl.reset(static_cast<void*>(0), noop_deleter());
   }
 
   // Resolve a query to a list of entries.
@@ -146,293 +56,60 @@
       boost::system::error_code& ec)
   {
     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();
 
- socket_ops::getaddrinfo(!host_name.empty() ? host_name.c_str() : 0,
- service_name.c_str(), &hints, &address_info, ec);
+ socket_ops::getaddrinfo(query.host_name().c_str(),
+ query.service_name().c_str(), query.hints(), &address_info, ec);
     auto_addrinfo auto_address_info(address_info);
 
- if (ec)
- return iterator_type();
-
- return iterator_type::create(address_info, host_name, service_name);
+ return ec ? iterator_type() : iterator_type::create(
+ address_info, query.host_name(), query.service_name());
   }
 
- template <typename Handler>
- class resolve_op
- : public operation
- {
- public:
- 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_impl_(io_service_impl),
- 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 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)
- {
- 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);
- }
- }
- }
-
- private:
- boost::weak_ptr<void> impl_;
- query_type query_;
- 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.
   template <typename Handler>
   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();
- io_service_impl_.work_started();
- work_io_service_impl_.post_immediate_completion(ptr.get());
- ptr.release();
- }
+ typedef resolve_op<Protocol, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl, query, io_service_impl_, handler);
+
+ start_resolve_op(p.p);
+ p.v = p.p = 0;
   }
 
   // Resolve an endpoint to a list of entries.
   iterator_type resolve(implementation_type&,
       const endpoint_type& endpoint, boost::system::error_code& ec)
   {
- // 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;
- socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
- host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
- if (ec)
- {
- flags |= NI_NUMERICSERV;
- socket_ops::getnameinfo(endpoint.data(), endpoint.size(),
- host_name, NI_MAXHOST, service_name, NI_MAXSERV, flags, ec);
- }
-
- if (ec)
- return iterator_type();
+ socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(),
+ host_name, NI_MAXHOST, service_name, NI_MAXSERV,
+ endpoint.protocol().type(), ec);
 
- return iterator_type::create(endpoint, host_name, service_name);
+ return ec ? iterator_type() : iterator_type::create(
+ endpoint, host_name, service_name);
   }
 
- template <typename Handler>
- class resolve_endpoint_op
- : public operation
- {
- public:
- 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)
- {
- }
-
- 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.
- 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);
-
- if (owner)
- {
- 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);
- }
- }
- }
-
- private:
- boost::weak_ptr<void> impl_;
- 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.
   template <typename Handler>
   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();
- io_service_impl_.work_started();
- work_io_service_impl_.post_immediate_completion(ptr.get());
- ptr.release();
- }
- }
-
-private:
- // Helper class to run the work io_service in a thread.
- class work_io_service_runner
- {
- public:
- work_io_service_runner(boost::asio::io_service& io_service)
- : io_service_(io_service) {}
- void operator()() { io_service_.run(); }
- private:
- boost::asio::io_service& io_service_;
- };
+ typedef resolve_endpoint_op<Protocol, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl, endpoint, io_service_impl_, handler);
 
- // Start the work thread if it's not already running.
- void start_work_thread()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (!work_thread_)
- {
- work_thread_.reset(new boost::asio::detail::thread(
- work_io_service_runner(*work_io_service_)));
- }
+ start_resolve_op(p.p);
+ p.v = p.p = 0;
   }
-
- // 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_;
-
- // Thread used for running the work io_service's run loop.
- boost::scoped_ptr<boost::asio::detail::thread> work_thread_;
 };
 
 } // namespace detail

Added: trunk/boost/asio/detail/resolver_service_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/resolver_service_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,125 @@
+//
+// detail/resolver_service_base.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_RESOLVER_SERVICE_BASE_HPP
+#define BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/mutex.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/thread.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class resolver_service_base
+{
+public:
+ // The implementation type of the resolver. A cancellation token is used to
+ // indicate to the background thread that the operation has been cancelled.
+ typedef socket_ops::shared_cancel_token_type implementation_type;
+
+ // Constructor.
+ BOOST_ASIO_DECL resolver_service_base(boost::asio::io_service& io_service);
+
+ // Destructor.
+ BOOST_ASIO_DECL ~resolver_service_base();
+
+ // Destroy all user-defined handler objects owned by the service.
+ BOOST_ASIO_DECL void shutdown_service();
+
+ // Construct a new resolver implementation.
+ BOOST_ASIO_DECL void construct(implementation_type& impl);
+
+ // Destroy a resolver implementation.
+ BOOST_ASIO_DECL void destroy(implementation_type&);
+
+ // Cancel pending asynchronous operations.
+ BOOST_ASIO_DECL void cancel(implementation_type& impl);
+
+protected:
+ // Helper function to start an asynchronous resolve operation.
+ BOOST_ASIO_DECL void start_resolve_op(operation* op);
+
+ // Helper class to perform exception-safe cleanup of addrinfo objects.
+ class auto_addrinfo
+ : private boost::asio::detail::noncopyable
+ {
+ public:
+ explicit auto_addrinfo(boost::asio::detail::addrinfo_type* ai)
+ : ai_(ai)
+ {
+ }
+
+ ~auto_addrinfo()
+ {
+ if (ai_)
+ socket_ops::freeaddrinfo(ai_);
+ }
+
+ operator boost::asio::detail::addrinfo_type*()
+ {
+ return ai_;
+ }
+
+ private:
+ boost::asio::detail::addrinfo_type* ai_;
+ };
+
+ // Helper class to run the work io_service in a thread.
+ class work_io_service_runner;
+
+ // Start the work thread if it's not already running.
+ BOOST_ASIO_DECL void start_work_thread();
+
+ // The io_service implementation used to post completions.
+ io_service_impl& io_service_impl_;
+
+private:
+ // Mutex to protect access to internal data.
+ boost::asio::detail::mutex mutex_;
+
+ // 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_;
+
+ // Thread used for running the work io_service's run loop.
+ boost::scoped_ptr<boost::asio::detail::thread> work_thread_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/resolver_service_base.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_DETAIL_RESOLVER_SERVICE_BASE_HPP

Modified: trunk/boost/asio/detail/scoped_lock.hpp
==============================================================================
--- trunk/boost/asio/detail/scoped_lock.hpp (original)
+++ trunk/boost/asio/detail/scoped_lock.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// scoped_lock.hpp
-// ~~~~~~~~~~~~~~~
+// detail/scoped_lock.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/select_interrupter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// select_interrupter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,13 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 # include <boost/asio/detail/socket_select_interrupter.hpp>
-#else
+#elif defined(BOOST_ASIO_HAS_EVENTFD)
 # include <boost/asio/detail/eventfd_select_interrupter.hpp>
+#else
 # include <boost/asio/detail/pipe_select_interrupter.hpp>
 #endif
 
@@ -44,6 +41,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_SELECT_INTERRUPTER_HPP

Modified: trunk/boost/asio/detail/select_reactor.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor.hpp (original)
+++ trunk/boost/asio/detail/select_reactor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// select_reactor.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/select_reactor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,42 +15,39 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/socket_types.hpp> // Must come before posix_time.
+#if defined(BOOST_ASIO_HAS_IOCP) \
+ || (!defined(BOOST_ASIO_HAS_DEV_POLL) \
+ && !defined(BOOST_ASIO_HAS_EPOLL) \
+ && !defined(BOOST_ASIO_HAS_KQUEUE))
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
-#include <boost/config.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/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>
-#include <boost/asio/detail/service_base.hpp>
-#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/thread.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/io_service.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/thread.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class select_reactor
- : public boost::asio::detail::service_base<select_reactor<Own_Thread> >
+ : public boost::asio::detail::service_base<select_reactor>
 {
 public:
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -67,280 +64,89 @@
   };
 
   // Constructor.
- 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_(),
- interrupter_(),
- stop_thread_(false),
- thread_(0),
- shutdown_(false)
- {
- if (Own_Thread)
- {
- boost::asio::detail::signal_blocker sb;
- thread_ = new boost::asio::detail::thread(
- bind_handler(&select_reactor::call_run_thread, this));
- }
- }
+ BOOST_ASIO_DECL select_reactor(boost::asio::io_service& io_service);
 
   // Destructor.
- ~select_reactor()
- {
- shutdown_service();
- }
+ BOOST_ASIO_DECL ~select_reactor();
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- shutdown_ = true;
- stop_thread_ = true;
- lock.unlock();
-
- if (Own_Thread)
- {
- 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);
-
- timer_queues_.get_all_timers(ops);
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task, but only if the reactor is not in its own thread.
- void init_task()
- {
- io_service_.init_task();
- }
+ BOOST_ASIO_DECL void 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&)
+ BOOST_ASIO_DECL int register_descriptor(socket_type, per_descriptor_data&);
+
+ // Post a reactor operation for immediate completion.
+ void post_immediate_completion(reactor_op* op)
   {
- return 0;
+ io_service_.post_immediate_completion(op);
   }
 
   // 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_)
- {
- bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
- io_service_.work_started();
- if (first)
- interrupter_.interrupt();
- }
- }
+ BOOST_ASIO_DECL void start_op(int op_type, socket_type descriptor,
+ per_descriptor_data&, reactor_op* op, bool);
 
   // 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&)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
- }
+ BOOST_ASIO_DECL void cancel_ops(socket_type descriptor, per_descriptor_data&);
 
   // 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&)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- cancel_ops_unlocked(descriptor, boost::asio::error::operation_aborted);
- }
+ BOOST_ASIO_DECL void close_descriptor(socket_type descriptor,
+ per_descriptor_data&);
 
   // 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_.insert(&timer_queue);
- }
+ void add_timer_queue(timer_queue<Time_Traits>& 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_);
- timer_queues_.erase(&timer_queue);
- }
+ void remove_timer_queue(timer_queue<Time_Traits>& queue);
 
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
- void schedule_timer(timer_queue<Time_Traits>& timer_queue,
- const typename Time_Traits::time_type& time, timer_op* op, void* token)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (!shutdown_)
- {
- bool earliest = timer_queue.enqueue_timer(time, op, token);
- io_service_.work_started();
- if (earliest)
- interrupter_.interrupt();
- }
- }
+ void schedule_timer(timer_queue<Time_Traits>& queue,
+ const typename Time_Traits::time_type& time, timer_op* op, void* token);
 
   // 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_);
- op_queue<operation> ops;
- std::size_t n = timer_queue.cancel_timer(token, ops);
- lock.unlock();
- io_service_.post_deferred_completions(ops);
- return n;
- }
+ std::size_t cancel_timer(timer_queue<Time_Traits>& queue, void* token);
 
   // Run select once until interrupted or events are ready to be dispatched.
- void run(bool block, op_queue<operation>& ops)
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- // Check if the thread is supposed to stop.
- 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 && !have_work_to_do)
- return;
-
- // Determine how long to block while waiting for events.
- timeval tv_buf = { 0, 0 };
- timeval* tv = block ? get_timeout(tv_buf) : &tv_buf;
-
- 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),
- fds[read_op], fds[write_op], fds[except_op], tv, ec);
-
- // Reset the interrupter.
- 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.
- 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);
- }
+ BOOST_ASIO_DECL void run(bool block, op_queue<operation>& ops);
 
   // Interrupt the select loop.
- void interrupt()
- {
- interrupter_.interrupt();
- }
+ BOOST_ASIO_DECL void interrupt();
 
 private:
+#if defined(BOOST_ASIO_HAS_IOCP)
   // Run the select loop in the thread.
- void run_thread()
- {
- if (Own_Thread)
- {
- 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();
- }
- }
- }
+ BOOST_ASIO_DECL void run_thread();
 
   // Entry point for the select loop thread.
- static void call_run_thread(select_reactor* reactor)
- {
- if (Own_Thread)
- {
- reactor->run_thread();
- }
- }
+ BOOST_ASIO_DECL static void call_run_thread(select_reactor* reactor);
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+ // Helper function to add a new timer queue.
+ BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
+
+ // Helper function to remove a timer queue.
+ BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
 
   // Get the timeout value for the select call.
- timeval* get_timeout(timeval& tv)
- {
- // 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.
- long usec = timer_queues_.wait_duration_usec(5 * 60 * 1000 * 1000);
- tv.tv_sec = usec / 1000000;
- tv.tv_usec = usec % 1000000;
- return &tv;
- }
+ BOOST_ASIO_DECL timeval* get_timeout(timeval& tv);
 
   // 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();
- }
+ BOOST_ASIO_DECL void cancel_ops_unlocked(socket_type descriptor,
+ const boost::system::error_code& ec);
 
   // The io_service implementation used to post completions.
   io_service_impl& io_service_;
@@ -357,11 +163,13 @@
   // The timer queues.
   timer_queue_set timer_queues_;
 
+#if defined(BOOST_ASIO_HAS_IOCP)
   // Does the reactor loop thread need to stop.
   bool stop_thread_;
 
   // The thread that is running the reactor loop.
   boost::asio::detail::thread* thread_;
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
   // Whether the service has been shut down.
   bool shutdown_;
@@ -373,4 +181,14 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/select_reactor.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/select_reactor.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+ // || (!defined(BOOST_ASIO_HAS_DEV_POLL)
+ // && !defined(BOOST_ASIO_HAS_EPOLL)
+ // && !defined(BOOST_ASIO_HAS_KQUEUE))
+
 #endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_HPP

Modified: trunk/boost/asio/detail/select_reactor_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/select_reactor_fwd.hpp (original)
+++ trunk/boost/asio/detail/select_reactor_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// select_reactor_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/select_reactor_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,19 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <bool Own_Thread>
 class select_reactor;
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_SELECT_REACTOR_FWD_HPP

Deleted: trunk/boost/asio/detail/service_base.hpp
==============================================================================
--- trunk/boost/asio/detail/service_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,51 +0,0 @@
-//
-// service_base.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_SERVICE_BASE_HPP
-#define BOOST_ASIO_DETAIL_SERVICE_BASE_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/service_id.hpp>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-// Special service base class to keep classes header-file only.
-template <typename Type>
-class service_base
- : public boost::asio::io_service::service
-{
-public:
- static boost::asio::detail::service_id<Type> id;
-
- // Constructor.
- service_base(boost::asio::io_service& io_service)
- : boost::asio::io_service::service(io_service)
- {
- }
-};
-
-template <typename Type>
-boost::asio::detail::service_id<Type> service_base<Type>::id;
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_SERVICE_BASE_HPP

Deleted: trunk/boost/asio/detail/service_id.hpp
==============================================================================
--- trunk/boost/asio/detail/service_id.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,39 +0,0 @@
-//
-// service_id.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_SERVICE_ID_HPP
-#define BOOST_ASIO_DETAIL_SERVICE_ID_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>
-
-namespace boost {
-namespace asio {
-namespace detail {
-
-// Special derived service id type to keep classes header-file only.
-template <typename Type>
-class service_id
- : public boost::asio::io_service::id
-{
-};
-
-} // namespace detail
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_DETAIL_SERVICE_ID_HPP

Modified: trunk/boost/asio/detail/service_registry.hpp
==============================================================================
--- trunk/boost/asio/detail/service_registry.hpp (original)
+++ trunk/boost/asio/detail/service_registry.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// service_registry.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/service_registry.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,11 @@
 # 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/asio/detail/config.hpp>
 #include <typeinfo>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/mutex.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/service_id.hpp>
+#include <boost/asio/io_service.hpp>
 
 #if defined(BOOST_NO_TYPEID)
 # if !defined(BOOST_ASIO_NO_TYPEID)
@@ -32,6 +27,8 @@
 # endif // !defined(BOOST_ASIO_NO_TYPEID)
 #endif // defined(BOOST_NO_TYPEID)
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -56,98 +53,42 @@
 {
 public:
   // Constructor.
- service_registry(boost::asio::io_service& o)
- : owner_(o),
- first_service_(0)
- {
- }
+ BOOST_ASIO_DECL service_registry(boost::asio::io_service& o);
 
   // Destructor.
- ~service_registry()
- {
- // Shutdown all services. This must be done in a separate loop before the
- // services are destroyed since the destructors of user-defined handler
- // objects may try to access other service objects.
- boost::asio::io_service::service* service = first_service_;
- while (service)
- {
- service->shutdown_service();
- service = service->next_;
- }
-
- // Destroy all services.
- while (first_service_)
- {
- boost::asio::io_service::service* next_service = first_service_->next_;
- destroy(first_service_);
- first_service_ = next_service;
- }
- }
+ BOOST_ASIO_DECL ~service_registry();
 
   // Get the service object corresponding to the specified service type. Will
   // create a new service object automatically if no such object already
   // exists. Ownership of the service object is not transferred to the caller.
   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));
- }
+ Service& use_service();
 
- // Add a service object. Returns false on error, in which case ownership of
- // the object is retained by the caller.
+ // Add a service object. Throws 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);
- }
+ void add_service(Service* 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);
- }
+ bool has_service() const;
 
 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;
- }
+ BOOST_ASIO_DECL void init_key(boost::asio::io_service::service::key& key,
+ const boost::asio::io_service::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;
- }
+ const boost::asio::detail::service_id<Service>& /*id*/);
 #endif // !defined(BOOST_ASIO_NO_TYPEID)
 
   // Check if a service matches the given id.
- static bool keys_match(
+ BOOST_ASIO_DECL 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;
- }
+ const boost::asio::io_service::service::key& key2);
 
   // The type of a factory function used for creating a service instance.
   typedef boost::asio::io_service::service*
@@ -156,16 +97,11 @@
   // 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);
- }
+ boost::asio::io_service& owner);
 
   // Destroy a service instance.
- static void destroy(boost::asio::io_service::service* service)
- {
- delete service;
- }
+ BOOST_ASIO_DECL static void destroy(
+ boost::asio::io_service::service* service);
 
   // Helper class to manage service pointers.
   struct auto_service_ptr
@@ -177,86 +113,19 @@
   // 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(
+ BOOST_ASIO_DECL 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 with the given key.
- boost::asio::io_service::service* service = first_service_;
- while (service)
- {
- if (keys_match(service->key_, key))
- return service;
- service = service->next_;
- }
-
- // Create a new service object. The service registry's mutex is not locked
- // at this time to allow for nested calls into this function from the new
- // service's constructor.
- lock.unlock();
- 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
- // while the lock was released.
- service = first_service_;
- while (service)
- {
- if (keys_match(service->key_, key))
- return service;
- service = service->next_;
- }
-
- // Service was successfully initialised, pass ownership to registry.
- new_service.ptr_->next_ = first_service_;
- first_service_ = new_service.ptr_;
- new_service.ptr_ = 0;
- return first_service_;
- }
+ factory_type factory);
 
   // Add a service object. Returns false on error, in which case ownership of
   // the object is retained by the caller.
- bool do_add_service(
+ BOOST_ASIO_DECL void 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 with the given key.
- boost::asio::io_service::service* service = first_service_;
- while (service)
- {
- if (keys_match(service->key_, key))
- return false;
- service = service->next_;
- }
-
- // Take ownership of the service object.
- new_service->key_ = key;
- new_service->next_ = first_service_;
- first_service_ = new_service;
-
- return true;
- }
+ boost::asio::io_service::service* new_service);
 
   // 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 (keys_match(service->key_, key))
- return true;
- service = service->next_;
- }
-
- return false;
- }
+ BOOST_ASIO_DECL bool do_has_service(
+ const boost::asio::io_service::service::key& key) const;
 
   // Mutex to protect access to internal data.
   mutable boost::asio::detail::mutex mutex_;
@@ -274,4 +143,9 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/service_registry.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/service_registry.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_HPP

Modified: trunk/boost/asio/detail/service_registry_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/service_registry_fwd.hpp (original)
+++ trunk/boost/asio/detail/service_registry_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// service_registry_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/service_registry_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,8 +15,6 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 namespace detail {
@@ -27,6 +25,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_SERVICE_REGISTRY_FWD_HPP

Added: trunk/boost/asio/detail/shared_ptr.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/shared_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,40 @@
+//
+// detail/shared_ptr.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_SHARED_PTR_HPP
+#define BOOST_ASIO_DETAIL_SHARED_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+# include <memory>
+#else
+# include <boost/shared_ptr.hpp>
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+using std::shared_ptr;
+#else
+using boost::shared_ptr;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_SHARED_PTR_HPP

Modified: trunk/boost/asio/detail/signal_blocker.hpp
==============================================================================
--- trunk/boost/asio/detail/signal_blocker.hpp (original)
+++ trunk/boost/asio/detail/signal_blocker.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// signal_blocker.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/signal_blocker.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_signal_blocker.hpp>
@@ -47,6 +43,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_SIGNAL_BLOCKER_HPP

Modified: trunk/boost/asio/detail/signal_init.hpp
==============================================================================
--- trunk/boost/asio/detail/signal_init.hpp (original)
+++ trunk/boost/asio/detail/signal_init.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// signal_init.hpp
-// ~~~~~~~~~~~~~~~
+// detail/signal_init.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,13 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <csignal>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -46,8 +42,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_SIGNAL_INIT_HPP

Modified: trunk/boost/asio/detail/socket_holder.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_holder.hpp (original)
+++ trunk/boost/asio/detail/socket_holder.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_holder.hpp
-// ~~~~~~~~~~~~~~~~~
+// detail/socket_holder.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,12 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -47,7 +48,8 @@
     if (socket_ != invalid_socket)
     {
       boost::system::error_code ec;
- socket_ops::close(socket_, ec);
+ socket_ops::state_type state = 0;
+ socket_ops::close(socket_, state, true, ec);
     }
   }
 
@@ -63,7 +65,8 @@
     if (socket_ != invalid_socket)
     {
       boost::system::error_code ec;
- socket_ops::close(socket_, ec);
+ socket_ops::state_type state = 0;
+ socket_ops::close(socket_, state, true, ec);
       socket_ = invalid_socket;
     }
   }

Modified: trunk/boost/asio/detail/socket_ops.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_ops.hpp (original)
+++ trunk/boost/asio/detail/socket_ops.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_ops.hpp
-// ~~~~~~~~~~~~~~
+// detail/socket_ops.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,1894 +15,267 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/assert.hpp>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cerrno>
-#include <boost/detail/workaround.hpp>
-#include <new>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/shared_ptr.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/weak_ptr.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 namespace socket_ops {
 
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-struct msghdr { int msg_namelen; };
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
-#if defined(__hpux)
-// HP-UX doesn't declare these functions extern "C", so they are declared again
-// here to avoid linker errors about undefined symbols.
-extern "C" char* if_indextoname(unsigned int, char*);
-extern "C" unsigned int if_nametoindex(const char*);
-#endif // defined(__hpux)
-
-inline void clear_error(boost::system::error_code& ec)
+// Socket state bits.
+enum
 {
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- WSASetLastError(0);
-#else
- errno = 0;
-#endif
- ec = boost::system::error_code();
-}
-
-template <typename ReturnType>
-inline ReturnType error_wrapper(ReturnType return_value,
- boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- ec = boost::system::error_code(WSAGetLastError(),
- boost::asio::error::get_system_category());
-#else
- ec = boost::system::error_code(errno,
- boost::asio::error::get_system_category());
-#endif
- return return_value;
-}
-
-template <typename SockLenType>
-inline socket_type call_accept(SockLenType msghdr::*,
- socket_type s, socket_addr_type* addr, std::size_t* addrlen)
-{
- SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
- socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
- if (addrlen)
- *addrlen = (std::size_t)tmp_addrlen;
- return result;
-}
+ // The user wants a non-blocking socket.
+ user_set_non_blocking = 1,
 
-inline socket_type accept(socket_type s, socket_addr_type* addr,
- std::size_t* addrlen, boost::system::error_code& ec)
-{
- clear_error(ec);
+ // The socket has been set non-blocking.
+ internal_non_blocking = 2,
 
- socket_type new_s = error_wrapper(call_accept(
- &msghdr::msg_namelen, s, addr, addrlen), ec);
- if (new_s == invalid_socket)
- return new_s;
-
-#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
- int optval = 1;
- int result = error_wrapper(::setsockopt(new_s,
- SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
- if (result != 0)
- {
- ::close(new_s);
- return invalid_socket;
- }
-#endif
-
- clear_error(ec);
- return new_s;
-}
-
-template <typename SockLenType>
-inline int call_bind(SockLenType msghdr::*,
- socket_type s, const socket_addr_type* addr, std::size_t addrlen)
-{
- return ::bind(s, addr, (SockLenType)addrlen);
-}
+ // Helper "state" used to determine whether the socket is non-blocking.
+ non_blocking = user_set_non_blocking | internal_non_blocking,
 
-inline int bind(socket_type s, const socket_addr_type* addr,
- std::size_t addrlen, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(call_bind(
- &msghdr::msg_namelen, s, addr, addrlen), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
+ // User wants connection_aborted errors, which are disabled by default.
+ enable_connection_aborted = 4,
 
-inline int close(socket_type s, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- int result = error_wrapper(::closesocket(s), ec);
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- int result = error_wrapper(::close(s), ec);
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- if (result == 0)
- clear_error(ec);
- return result;
-}
+ // The user set the linger option. Needs to be checked when closing.
+ user_set_linger = 8,
 
-inline int shutdown(socket_type s, int what, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::shutdown(s, what), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
-
-template <typename SockLenType>
-inline int call_connect(SockLenType msghdr::*,
- socket_type s, const socket_addr_type* addr, std::size_t addrlen)
-{
- return ::connect(s, addr, (SockLenType)addrlen);
-}
+ // The socket is stream-oriented.
+ stream_oriented = 16,
 
-inline int connect(socket_type s, const socket_addr_type* addr,
- std::size_t addrlen, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(call_connect(
- &msghdr::msg_namelen, s, addr, addrlen), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
+ // The socket is datagram-oriented.
+ datagram_oriented = 32
+};
 
-inline int socketpair(int af, int type, int protocol,
- socket_type sv[2], boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- (void)(af);
- (void)(type);
- (void)(protocol);
- (void)(sv);
- ec = boost::asio::error::operation_not_supported;
- return -1;
-#else
- clear_error(ec);
- int result = error_wrapper(::socketpair(af, type, protocol, sv), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-#endif
-}
+typedef unsigned char state_type;
 
-inline int listen(socket_type s, int backlog, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::listen(s, backlog), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
+struct noop_deleter { void operator()(void*) {} };
+typedef shared_ptr<void> shared_cancel_token_type;
+typedef weak_ptr<void> weak_cancel_token_type;
 
-inline void init_buf_iov_base(void*& base, void* addr)
-{
- base = addr;
-}
+BOOST_ASIO_DECL socket_type accept(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec);
 
-template <typename T>
-inline void init_buf_iov_base(T& base, void* addr)
-{
- base = static_cast<T>(addr);
-}
+BOOST_ASIO_DECL socket_type sync_accept(socket_type s,
+ state_type state, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec);
 
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-typedef WSABUF buf;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-typedef iovec buf;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+#if defined(BOOST_ASIO_HAS_IOCP)
 
-inline void init_buf(buf& b, void* data, size_t size)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- b.buf = static_cast<char*>(data);
- b.len = static_cast<u_long>(size);
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- init_buf_iov_base(b.iov_base, data);
- b.iov_len = size;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL void complete_iocp_accept(socket_type s,
+ void* output_buffer, DWORD address_length,
+ socket_addr_type* addr, std::size_t* addrlen,
+ socket_type new_socket, boost::system::error_code& ec);
 
-inline void init_buf(buf& b, const void* data, size_t size)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- b.buf = static_cast<char*>(const_cast<void*>(data));
- b.len = static_cast<u_long>(size);
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- init_buf_iov_base(b.iov_base, const_cast<void*>(data));
- b.iov_len = size;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+#else // defined(BOOST_ASIO_HAS_IOCP)
 
-inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
-{
- name = addr;
-}
+BOOST_ASIO_DECL bool non_blocking_accept(socket_type s,
+ state_type state, socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, socket_type& new_socket);
 
-inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
-{
- name = const_cast<socket_addr_type*>(addr);
-}
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
-template <typename T>
-inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
-{
- name = reinterpret_cast<T>(addr);
-}
+BOOST_ASIO_DECL int bind(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec);
 
-template <typename T>
-inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
-{
- name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
-}
+BOOST_ASIO_DECL int close(socket_type s, state_type& state,
+ bool destruction, boost::system::error_code& ec);
 
-inline int recv(socket_type s, buf* bufs, size_t count, int flags,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- // Receive some data.
- DWORD recv_buf_count = static_cast<DWORD>(count);
- DWORD bytes_transferred = 0;
- DWORD recv_flags = flags;
- int result = error_wrapper(::WSARecv(s, bufs,
- recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec);
- if (result != 0)
- return -1;
- clear_error(ec);
- return bytes_transferred;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- msghdr msg = msghdr();
- msg.msg_iov = bufs;
- msg.msg_iovlen = count;
- int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL bool set_internal_non_blocking(socket_type s,
+ state_type& state, boost::system::error_code& ec);
 
-inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
- socket_addr_type* addr, std::size_t* addrlen,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- // Receive some data.
- DWORD recv_buf_count = static_cast<DWORD>(count);
- DWORD bytes_transferred = 0;
- DWORD recv_flags = flags;
- int tmp_addrlen = (int)*addrlen;
- int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
- &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
- *addrlen = (std::size_t)tmp_addrlen;
- if (result != 0)
- return -1;
- clear_error(ec);
- return bytes_transferred;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- msghdr msg = msghdr();
- init_msghdr_msg_name(msg.msg_name, addr);
- msg.msg_namelen = *addrlen;
- msg.msg_iov = bufs;
- msg.msg_iovlen = count;
- int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
- *addrlen = msg.msg_namelen;
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL int shutdown(socket_type s,
+ int what, boost::system::error_code& ec);
 
-inline int send(socket_type s, const buf* bufs, size_t count, int flags,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- // Send the data.
- DWORD send_buf_count = static_cast<DWORD>(count);
- DWORD bytes_transferred = 0;
- DWORD send_flags = flags;
- int result = error_wrapper(::WSASend(s, const_cast<buf*>(bufs),
- send_buf_count, &bytes_transferred, send_flags, 0, 0), ec);
- if (result != 0)
- return -1;
- clear_error(ec);
- return bytes_transferred;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- msghdr msg = msghdr();
- msg.msg_iov = const_cast<buf*>(bufs);
- msg.msg_iovlen = count;
-#if defined(__linux__)
- flags |= MSG_NOSIGNAL;
-#endif // defined(__linux__)
- int result = error_wrapper(::sendmsg(s, &msg, flags), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL int connect(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec);
 
-inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
- const socket_addr_type* addr, std::size_t addrlen,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- // Send the data.
- DWORD send_buf_count = static_cast<DWORD>(count);
- DWORD bytes_transferred = 0;
- int result = error_wrapper(::WSASendTo(s, const_cast<buf*>(bufs),
- send_buf_count, &bytes_transferred, flags, addr,
- static_cast<int>(addrlen), 0, 0), ec);
- if (result != 0)
- return -1;
- clear_error(ec);
- return bytes_transferred;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- msghdr msg = msghdr();
- init_msghdr_msg_name(msg.msg_name, addr);
- msg.msg_namelen = addrlen;
- msg.msg_iov = const_cast<buf*>(bufs);
- msg.msg_iovlen = count;
-#if defined(__linux__)
- flags |= MSG_NOSIGNAL;
-#endif // defined(__linux__)
- int result = error_wrapper(::sendmsg(s, &msg, flags), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL void sync_connect(socket_type s, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec);
 
-inline socket_type socket(int af, int type, int protocol,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- socket_type s = error_wrapper(::WSASocket(af, type, protocol, 0, 0,
- WSA_FLAG_OVERLAPPED), ec);
- if (s == invalid_socket)
- return s;
-
- if (af == AF_INET6)
- {
- // Try to enable the POSIX default behaviour of having IPV6_V6ONLY set to
- // false. This will only succeed on Windows Vista and later versions of
- // Windows, where a dual-stack IPv4/v6 implementation is available.
- DWORD optval = 0;
- ::setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
- reinterpret_cast<const char*>(&optval), sizeof(optval));
- }
-
- clear_error(ec);
-
- return s;
-#elif defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
- socket_type s = error_wrapper(::socket(af, type, protocol), ec);
- if (s == invalid_socket)
- return s;
-
- int optval = 1;
- int result = error_wrapper(::setsockopt(s,
- SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
- if (result != 0)
- {
- ::close(s);
- return invalid_socket;
- }
-
- return s;
-#else
- int s = error_wrapper(::socket(af, type, protocol), ec);
- if (s >= 0)
- clear_error(ec);
- return s;
-#endif
-}
-
-template <typename SockLenType>
-inline int call_setsockopt(SockLenType msghdr::*,
- socket_type s, int level, int optname,
- const void* optval, std::size_t optlen)
-{
- return ::setsockopt(s, level, optname,
- (const char*)optval, (SockLenType)optlen);
-}
+BOOST_ASIO_DECL bool non_blocking_connect(
+ socket_type s, boost::system::error_code& ec);
 
-inline int setsockopt(socket_type s, int level, int optname,
- const void* optval, std::size_t optlen, boost::system::error_code& ec)
-{
- if (level == custom_socket_option_level && optname == always_fail_option)
- {
- ec = boost::asio::error::invalid_argument;
- return -1;
- }
-
-#if defined(__BORLANDC__)
- // Mysteriously, using the getsockopt and setsockopt functions directly with
- // Borland C++ results in incorrect values being set and read. The bug can be
- // worked around by using function addresses resolved with GetProcAddress.
- if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
- {
- typedef int (WSAAPI *sso_t)(SOCKET, int, int, const char*, int);
- if (sso_t sso = (sso_t)::GetProcAddress(winsock_module, "setsockopt"))
- {
- clear_error(ec);
- return error_wrapper(sso(s, level, optname,
- reinterpret_cast<const char*>(optval),
- static_cast<int>(optlen)), ec);
- }
- }
- ec = boost::asio::error::fault;
- return -1;
-#else // defined(__BORLANDC__)
- clear_error(ec);
- int result = error_wrapper(call_setsockopt(&msghdr::msg_namelen,
- s, level, optname, optval, optlen), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-#endif // defined(__BORLANDC__)
-}
-
-template <typename SockLenType>
-inline int call_getsockopt(SockLenType msghdr::*,
- socket_type s, int level, int optname,
- void* optval, std::size_t* optlen)
-{
- SockLenType tmp_optlen = (SockLenType)*optlen;
- int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
- *optlen = (std::size_t)tmp_optlen;
- return result;
-}
+BOOST_ASIO_DECL int socketpair(int af, int type, int protocol,
+ socket_type sv[2], boost::system::error_code& ec);
 
-inline int getsockopt(socket_type s, int level, int optname, void* optval,
- size_t* optlen, boost::system::error_code& ec)
-{
- if (level == custom_socket_option_level && optname == always_fail_option)
- {
- ec = boost::asio::error::invalid_argument;
- return -1;
- }
-
-#if defined(__BORLANDC__)
- // Mysteriously, using the getsockopt and setsockopt functions directly with
- // Borland C++ results in incorrect values being set and read. The bug can be
- // worked around by using function addresses resolved with GetProcAddress.
- if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
- {
- typedef int (WSAAPI *gso_t)(SOCKET, int, int, char*, int*);
- if (gso_t gso = (gso_t)::GetProcAddress(winsock_module, "getsockopt"))
- {
- clear_error(ec);
- int tmp_optlen = static_cast<int>(*optlen);
- int result = error_wrapper(gso(s, level, optname,
- reinterpret_cast<char*>(optval), &tmp_optlen), ec);
- *optlen = static_cast<size_t>(tmp_optlen);
- if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
- && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
- {
- // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are
- // only supported on Windows Vista and later. To simplify program logic
- // we will fake success of getting this option and specify that the
- // value is non-zero (i.e. true). This corresponds to the behavior of
- // IPv6 sockets on Windows platforms pre-Vista.
- *static_cast<DWORD*>(optval) = 1;
- clear_error(ec);
- }
- return result;
- }
- }
- ec = boost::asio::error::fault;
- return -1;
-#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- clear_error(ec);
- int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
- s, level, optname, optval, optlen), ec);
- if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
- && ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
- {
- // Dual-stack IPv4/v6 sockets, and the IPV6_V6ONLY socket option, are only
- // supported on Windows Vista and later. To simplify program logic we will
- // fake success of getting this option and specify that the value is
- // non-zero (i.e. true). This corresponds to the behavior of IPv6 sockets
- // on Windows platforms pre-Vista.
- *static_cast<DWORD*>(optval) = 1;
- clear_error(ec);
- }
- if (result == 0)
- clear_error(ec);
- return result;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- clear_error(ec);
- int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
- s, level, optname, optval, optlen), ec);
-#if defined(__linux__)
- if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
- && (optname == SO_SNDBUF || optname == SO_RCVBUF))
- {
- // On Linux, setting SO_SNDBUF or SO_RCVBUF to N actually causes the kernel
- // to set the buffer size to N*2. Linux puts additional stuff into the
- // buffers so that only about half is actually available to the application.
- // The retrieved value is divided by 2 here to make it appear as though the
- // correct value has been set.
- *static_cast<int*>(optval) /= 2;
- }
-#endif // defined(__linux__)
- if (result == 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL bool sockatmark(socket_type s, boost::system::error_code& ec);
 
-template <typename SockLenType>
-inline int call_getpeername(SockLenType msghdr::*,
- socket_type s, socket_addr_type* addr, std::size_t* addrlen)
-{
- SockLenType tmp_addrlen = (SockLenType)*addrlen;
- int result = ::getpeername(s, addr, &tmp_addrlen);
- *addrlen = (std::size_t)tmp_addrlen;
- return result;
-}
+BOOST_ASIO_DECL size_t available(socket_type s, boost::system::error_code& ec);
 
-inline int getpeername(socket_type s, socket_addr_type* addr,
- std::size_t* addrlen, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(call_getpeername(
- &msghdr::msg_namelen, s, addr, addrlen), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
-
-template <typename SockLenType>
-inline int call_getsockname(SockLenType msghdr::*,
- socket_type s, socket_addr_type* addr, std::size_t* addrlen)
-{
- SockLenType tmp_addrlen = (SockLenType)*addrlen;
- int result = ::getsockname(s, addr, &tmp_addrlen);
- *addrlen = (std::size_t)tmp_addrlen;
- return result;
-}
-
-inline int getsockname(socket_type s, socket_addr_type* addr,
- std::size_t* addrlen, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(call_getsockname(
- &msghdr::msg_namelen, s, addr, addrlen), ec);
- if (result == 0)
- clear_error(ec);
- return result;
-}
+BOOST_ASIO_DECL int listen(socket_type s,
+ int backlog, boost::system::error_code& ec);
 
-inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
- boost::system::error_code& ec)
-{
- clear_error(ec);
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- int result = error_wrapper(::ioctlsocket(s, cmd, arg), ec);
+typedef WSABUF buf;
 #else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- int result = error_wrapper(::ioctl(s, cmd, arg), ec);
+typedef iovec buf;
 #endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- if (result >= 0)
- clear_error(ec);
- return result;
-}
 
-inline int select(int nfds, fd_set* readfds, fd_set* writefds,
- fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- if (!readfds && !writefds && !exceptfds && timeout)
- {
- DWORD milliseconds = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
- if (milliseconds == 0)
- milliseconds = 1; // Force context switch.
- ::Sleep(milliseconds);
- ec = boost::system::error_code();
- return 0;
- }
-
- // The select() call allows timeout values measured in microseconds, but the
- // system clock (as wrapped by boost::posix_time::microsec_clock) typically
- // has a resolution of 10 milliseconds. This can lead to a spinning select
- // reactor, meaning increased CPU usage, when waiting for the earliest
- // scheduled timeout if it's less than 10 milliseconds away. To avoid a tight
- // spin we'll use a minimum timeout of 1 millisecond.
- if (timeout && timeout->tv_sec == 0
- && timeout->tv_usec > 0 && timeout->tv_usec < 1000)
- timeout->tv_usec = 1000;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+BOOST_ASIO_DECL void init_buf(buf& b, void* data, size_t size);
 
-#if defined(__hpux) && defined(__HP_aCC)
- timespec ts;
- ts.tv_sec = timeout ? timeout->tv_sec : 0;
- ts.tv_nsec = timeout ? timeout->tv_usec * 1000 : 0;
- return error_wrapper(::pselect(nfds, readfds,
- writefds, exceptfds, timeout ? &ts : 0, 0), ec);
-#else
- int result = error_wrapper(::select(nfds, readfds,
- writefds, exceptfds, timeout), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif
-}
+BOOST_ASIO_DECL void init_buf(buf& b, const void* data, size_t size);
 
-inline int poll_read(socket_type s, boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- FD_SET fds;
- FD_ZERO(&fds);
- FD_SET(s, &fds);
- clear_error(ec);
- int result = error_wrapper(::select(s, &fds, 0, 0, 0), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- pollfd fds;
- fds.fd = s;
- fds.events = POLLIN;
- fds.revents = 0;
- clear_error(ec);
- int result = error_wrapper(::poll(&fds, 1, -1), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL int recv(socket_type s, buf* bufs, size_t count, int flags,
+ boost::system::error_code& ec);
 
-inline int poll_write(socket_type s, boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- FD_SET fds;
- FD_ZERO(&fds);
- FD_SET(s, &fds);
- clear_error(ec);
- int result = error_wrapper(::select(s, 0, &fds, 0, 0), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- pollfd fds;
- fds.fd = s;
- fds.events = POLLOUT;
- fds.revents = 0;
- clear_error(ec);
- int result = error_wrapper(::poll(&fds, 1, -1), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs,
+ size_t count, int flags, bool all_empty, boost::system::error_code& ec);
 
-inline int poll_connect(socket_type s, boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- FD_SET write_fds;
- FD_ZERO(&write_fds);
- FD_SET(s, &write_fds);
- FD_SET except_fds;
- FD_ZERO(&except_fds);
- FD_SET(s, &except_fds);
- clear_error(ec);
- int result = error_wrapper(::select(s, 0, &write_fds, &except_fds, 0), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- pollfd fds;
- fds.fd = s;
- fds.events = POLLOUT;
- fds.revents = 0;
- clear_error(ec);
- int result = error_wrapper(::poll(&fds, 1, -1), ec);
- if (result >= 0)
- clear_error(ec);
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+#if defined(BOOST_ASIO_HAS_IOCP)
 
-inline const char* inet_ntop(int af, const void* src, char* dest, size_t length,
- unsigned long scope_id, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- using namespace std; // For memcpy.
+BOOST_ASIO_DECL void complete_iocp_recv(state_type state,
+ const weak_cancel_token_type& cancel_token, bool all_empty,
+ boost::system::error_code& ec, size_t bytes_transferred);
 
- if (af != AF_INET && af != AF_INET6)
- {
- ec = boost::asio::error::address_family_not_supported;
- return 0;
- }
-
- union
- {
- socket_addr_type base;
- sockaddr_storage_type storage;
- sockaddr_in4_type v4;
- sockaddr_in6_type v6;
- } address;
- DWORD address_length;
- if (af == AF_INET)
- {
- address_length = sizeof(sockaddr_in4_type);
- address.v4.sin_family = AF_INET;
- address.v4.sin_port = 0;
- memcpy(&address.v4.sin_addr, src, sizeof(in4_addr_type));
- }
- else // AF_INET6
- {
- address_length = sizeof(sockaddr_in6_type);
- address.v6.sin6_family = AF_INET6;
- address.v6.sin6_port = 0;
- address.v6.sin6_flowinfo = 0;
- address.v6.sin6_scope_id = scope_id;
- memcpy(&address.v6.sin6_addr, src, sizeof(in6_addr_type));
- }
-
- DWORD string_length = static_cast<DWORD>(length);
-#if defined(BOOST_NO_ANSI_APIS)
- LPWSTR string_buffer = (LPWSTR)_alloca(length * sizeof(WCHAR));
- int result = error_wrapper(::WSAAddressToStringW(&address.base,
- address_length, 0, string_buffer, &string_length), ec);
- ::WideCharToMultiByte(CP_ACP, 0, string_buffer, -1, dest, length, 0, 0);
-#else
- int result = error_wrapper(::WSAAddressToStringA(
- &address.base, address_length, 0, dest, &string_length), ec);
-#endif
-
- // Windows may set error code on success.
- if (result != socket_error_retval)
- clear_error(ec);
-
- // Windows may not set an error code on failure.
- else if (result == socket_error_retval && !ec)
- ec = boost::asio::error::invalid_argument;
+#else // defined(BOOST_ASIO_HAS_IOCP)
 
- return result == socket_error_retval ? 0 : dest;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- const char* result = error_wrapper(::inet_ntop(af, src, dest, length), ec);
- if (result == 0 && !ec)
- ec = boost::asio::error::invalid_argument;
- if (result != 0 && af == AF_INET6 && scope_id != 0)
- {
- using namespace std; // For strcat and sprintf.
- char if_name[IF_NAMESIZE + 1] = "%";
- const in6_addr_type* ipv6_address = static_cast<const in6_addr_type*>(src);
- bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);
- if (!is_link_local || if_indextoname(scope_id, if_name + 1) == 0)
- sprintf(if_name + 1, "%lu", scope_id);
- strcat(dest, if_name);
- }
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+BOOST_ASIO_DECL bool non_blocking_recv(socket_type s,
+ buf* bufs, size_t count, int flags, bool is_stream,
+ boost::system::error_code& ec, size_t& bytes_transferred);
 
-inline int inet_pton(int af, const char* src, void* dest,
- unsigned long* scope_id, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- using namespace std; // For memcpy and strcmp.
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
- if (af != AF_INET && af != AF_INET6)
- {
- ec = boost::asio::error::address_family_not_supported;
- return -1;
- }
-
- union
- {
- socket_addr_type base;
- sockaddr_storage_type storage;
- sockaddr_in4_type v4;
- sockaddr_in6_type v6;
- } address;
- int address_length = sizeof(sockaddr_storage_type);
-#if defined(BOOST_NO_ANSI_APIS)
- int num_wide_chars = strlen(src) + 1;
- LPWSTR wide_buffer = (LPWSTR)_alloca(num_wide_chars * sizeof(WCHAR));
- ::MultiByteToWideChar(CP_ACP, 0, src, -1, wide_buffer, num_wide_chars);
- int result = error_wrapper(::WSAStringToAddressW(
- wide_buffer, af, 0, &address.base, &address_length), ec);
-#else
- int result = error_wrapper(::WSAStringToAddressA(
- const_cast<char*>(src), af, 0, &address.base, &address_length), ec);
-#endif
-
- if (af == AF_INET)
- {
- if (result != socket_error_retval)
- {
- memcpy(dest, &address.v4.sin_addr, sizeof(in4_addr_type));
- clear_error(ec);
- }
- else if (strcmp(src, "255.255.255.255") == 0)
- {
- static_cast<in4_addr_type*>(dest)->s_addr = INADDR_NONE;
- clear_error(ec);
- }
- }
- else // AF_INET6
- {
- if (result != socket_error_retval)
- {
- memcpy(dest, &address.v6.sin6_addr, sizeof(in6_addr_type));
- if (scope_id)
- *scope_id = address.v6.sin6_scope_id;
- clear_error(ec);
- }
- }
-
- // Windows may not set an error code on failure.
- if (result == socket_error_retval && !ec)
- ec = boost::asio::error::invalid_argument;
+BOOST_ASIO_DECL int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec);
 
- if (result != socket_error_retval)
- clear_error(ec);
+BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state,
+ buf* bufs, size_t count, int flags, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec);
 
- return result == socket_error_retval ? -1 : 1;
-#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- int result = error_wrapper(::inet_pton(af, src, dest), ec);
- if (result <= 0 && !ec)
- ec = boost::asio::error::invalid_argument;
- if (result > 0 && af == AF_INET6 && scope_id)
- {
- using namespace std; // For strchr and atoi.
- *scope_id = 0;
- if (const char* if_name = strchr(src, '%'))
- {
- in6_addr_type* ipv6_address = static_cast<in6_addr_type*>(dest);
- bool is_link_local = IN6_IS_ADDR_LINKLOCAL(ipv6_address);
- if (is_link_local)
- *scope_id = if_nametoindex(if_name + 1);
- if (*scope_id == 0)
- *scope_id = atoi(if_name + 1);
- }
- }
- return result;
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-}
+#if defined(BOOST_ASIO_HAS_IOCP)
 
-inline int gethostname(char* name, int namelen, boost::system::error_code& ec)
-{
- clear_error(ec);
- int result = error_wrapper(::gethostname(name, namelen), ec);
-#if defined(BOOST_WINDOWS)
- if (result == 0)
- clear_error(ec);
-#endif
- return result;
-}
+BOOST_ASIO_DECL void complete_iocp_recvfrom(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec);
 
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) \
- || defined(__MACH__) && defined(__APPLE__)
+#else // defined(BOOST_ASIO_HAS_IOCP)
 
-// The following functions are only needed for emulation of getaddrinfo and
-// getnameinfo.
+BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s,
+ buf* bufs, size_t count, int flags,
+ socket_addr_type* addr, std::size_t* addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred);
 
-inline boost::system::error_code translate_netdb_error(int error)
-{
- switch (error)
- {
- case 0:
- return boost::system::error_code();
- case HOST_NOT_FOUND:
- return boost::asio::error::host_not_found;
- case TRY_AGAIN:
- return boost::asio::error::host_not_found_try_again;
- case NO_RECOVERY:
- return boost::asio::error::no_recovery;
- case NO_DATA:
- return boost::asio::error::no_data;
- default:
- BOOST_ASSERT(false);
- return boost::asio::error::invalid_argument;
- }
-}
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
-inline hostent* gethostbyaddr(const char* addr, int length, int af,
- hostent* result, char* buffer, int buflength, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- (void)(buffer);
- (void)(buflength);
- hostent* retval = error_wrapper(::gethostbyaddr(addr, length, af), ec);
- if (!retval)
- return 0;
- clear_error(ec);
- *result = *retval;
- return retval;
-#elif defined(__sun) || defined(__QNX__)
- int error = 0;
- hostent* retval = error_wrapper(::gethostbyaddr_r(addr, length, af, result,
- buffer, buflength, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- return retval;
-#elif defined(__MACH__) && defined(__APPLE__)
- (void)(buffer);
- (void)(buflength);
- int error = 0;
- hostent* retval = error_wrapper(::getipnodebyaddr(
- addr, length, af, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- if (!retval)
- return 0;
- *result = *retval;
- return retval;
-#else
- hostent* retval = 0;
- int error = 0;
- error_wrapper(::gethostbyaddr_r(addr, length, af, result, buffer,
- buflength, &retval, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- return retval;
-#endif
-}
+BOOST_ASIO_DECL int send(socket_type s, const buf* bufs,
+ size_t count, int flags, boost::system::error_code& ec);
 
-inline hostent* gethostbyname(const char* name, int af, struct hostent* result,
- char* buffer, int buflength, int ai_flags, boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- (void)(buffer);
- (void)(buflength);
- (void)(ai_flags);
- if (af != AF_INET)
- {
- ec = boost::asio::error::address_family_not_supported;
- return 0;
- }
- hostent* retval = error_wrapper(::gethostbyname(name), ec);
- if (!retval)
- return 0;
- clear_error(ec);
- *result = *retval;
- return result;
-#elif defined(__sun) || defined(__QNX__)
- (void)(ai_flags);
- if (af != AF_INET)
- {
- ec = boost::asio::error::address_family_not_supported;
- return 0;
- }
- int error = 0;
- hostent* retval = error_wrapper(::gethostbyname_r(name, result, buffer,
- buflength, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- return retval;
-#elif defined(__MACH__) && defined(__APPLE__)
- (void)(buffer);
- (void)(buflength);
- int error = 0;
- hostent* retval = error_wrapper(::getipnodebyname(
- name, af, ai_flags, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- if (!retval)
- return 0;
- *result = *retval;
- return retval;
-#else
- (void)(ai_flags);
- if (af != AF_INET)
- {
- ec = boost::asio::error::address_family_not_supported;
- return 0;
- }
- hostent* retval = 0;
- int error = 0;
- error_wrapper(::gethostbyname_r(name, result,
- buffer, buflength, &retval, &error), ec);
- if (error)
- ec = translate_netdb_error(error);
- return retval;
-#endif
-}
+BOOST_ASIO_DECL size_t sync_send(socket_type s, state_type state,
+ const buf* bufs, size_t count, int flags,
+ bool all_empty, boost::system::error_code& ec);
 
-inline void freehostent(hostent* h)
-{
-#if defined(__MACH__) && defined(__APPLE__)
- if (h)
- ::freehostent(h);
-#else
- (void)(h);
-#endif
-}
+#if defined(BOOST_ASIO_HAS_IOCP)
 
-// Emulation of getaddrinfo based on implementation in:
-// Stevens, W. R., UNIX Network Programming Vol. 1, 2nd Ed., Prentice-Hall 1998.
+BOOST_ASIO_DECL void complete_iocp_send(
+ const weak_cancel_token_type& cancel_token,
+ boost::system::error_code& ec);
 
-struct gai_search
-{
- const char* host;
- int family;
-};
+#else // defined(BOOST_ASIO_HAS_IOCP)
 
-inline int gai_nsearch(const char* host,
- const addrinfo_type* hints, gai_search (&search)[2])
-{
- int search_count = 0;
- if (host == 0 || host[0] == '\0')
- {
- if (hints->ai_flags & AI_PASSIVE)
- {
- // No host and AI_PASSIVE implies wildcard bind.
- switch (hints->ai_family)
- {
- case AF_INET:
- search[search_count].host = "0.0.0.0";
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- case AF_INET6:
- search[search_count].host = "0::0";
- search[search_count].family = AF_INET6;
- ++search_count;
- break;
- case AF_UNSPEC:
- search[search_count].host = "0::0";
- search[search_count].family = AF_INET6;
- ++search_count;
- search[search_count].host = "0.0.0.0";
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- default:
- break;
- }
- }
- else
- {
- // No host and not AI_PASSIVE means connect to local host.
- switch (hints->ai_family)
- {
- case AF_INET:
- search[search_count].host = "localhost";
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- case AF_INET6:
- search[search_count].host = "localhost";
- search[search_count].family = AF_INET6;
- ++search_count;
- break;
- case AF_UNSPEC:
- search[search_count].host = "localhost";
- search[search_count].family = AF_INET6;
- ++search_count;
- search[search_count].host = "localhost";
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- default:
- break;
- }
- }
- }
- else
- {
- // Host is specified.
- switch (hints->ai_family)
- {
- case AF_INET:
- search[search_count].host = host;
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- case AF_INET6:
- search[search_count].host = host;
- search[search_count].family = AF_INET6;
- ++search_count;
- break;
- case AF_UNSPEC:
- search[search_count].host = host;
- search[search_count].family = AF_INET6;
- ++search_count;
- search[search_count].host = host;
- search[search_count].family = AF_INET;
- ++search_count;
- break;
- default:
- break;
- }
- }
- return search_count;
-}
-
-template <typename T>
-inline T* gai_alloc(std::size_t size = sizeof(T))
-{
- using namespace std;
- T* p = static_cast<T*>(::operator new(size, std::nothrow));
- if (p)
- memset(p, 0, size);
- return p;
-}
+BOOST_ASIO_DECL bool non_blocking_send(socket_type s,
+ const buf* bufs, size_t count, int flags,
+ boost::system::error_code& ec, size_t& bytes_transferred);
 
-inline void gai_free(void* p)
-{
- ::operator delete(p);
-}
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
-inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
-{
- using namespace std;
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
- strcpy_s(target, max_size, source);
-#else
- *target = 0;
- strncat(target, source, max_size);
-#endif
-}
+BOOST_ASIO_DECL int sendto(socket_type s, const buf* bufs, size_t count,
+ int flags, const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec);
 
-enum { gai_clone_flag = 1 << 30 };
+BOOST_ASIO_DECL size_t sync_sendto(socket_type s, state_type state,
+ const buf* bufs, size_t count, int flags, const socket_addr_type* addr,
+ std::size_t addrlen, boost::system::error_code& ec);
 
-inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
- const void* addr, int family)
-{
- using namespace std;
+#if !defined(BOOST_ASIO_HAS_IOCP)
 
- addrinfo_type* ai = gai_alloc<addrinfo_type>();
- if (ai == 0)
- return EAI_MEMORY;
-
- ai->ai_next = 0;
- **next = ai;
- *next = &ai->ai_next;
-
- ai->ai_canonname = 0;
- ai->ai_socktype = hints->ai_socktype;
- if (ai->ai_socktype == 0)
- ai->ai_flags |= gai_clone_flag;
- ai->ai_protocol = hints->ai_protocol;
- ai->ai_family = family;
-
- switch (ai->ai_family)
- {
- case AF_INET:
- {
- sockaddr_in4_type* sinptr = gai_alloc<sockaddr_in4_type>();
- if (sinptr == 0)
- return EAI_MEMORY;
- sinptr->sin_family = AF_INET;
- memcpy(&sinptr->sin_addr, addr, sizeof(in4_addr_type));
- ai->ai_addr = reinterpret_cast<sockaddr*>(sinptr);
- ai->ai_addrlen = sizeof(sockaddr_in4_type);
- break;
- }
- case AF_INET6:
- {
- sockaddr_in6_type* sin6ptr = gai_alloc<sockaddr_in6_type>();
- if (sin6ptr == 0)
- return EAI_MEMORY;
- sin6ptr->sin6_family = AF_INET6;
- memcpy(&sin6ptr->sin6_addr, addr, sizeof(in6_addr_type));
- ai->ai_addr = reinterpret_cast<sockaddr*>(sin6ptr);
- ai->ai_addrlen = sizeof(sockaddr_in6_type);
- break;
- }
- default:
- break;
- }
+BOOST_ASIO_DECL bool non_blocking_sendto(socket_type s,
+ const buf* bufs, size_t count, int flags,
+ const socket_addr_type* addr, std::size_t addrlen,
+ boost::system::error_code& ec, size_t& bytes_transferred);
 
- return 0;
-}
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
 
-inline addrinfo_type* gai_clone(addrinfo_type* ai)
-{
- using namespace std;
+BOOST_ASIO_DECL socket_type socket(int af, int type, int protocol,
+ boost::system::error_code& ec);
 
- addrinfo_type* new_ai = gai_alloc<addrinfo_type>();
- if (new_ai == 0)
- return new_ai;
-
- new_ai->ai_next = ai->ai_next;
- ai->ai_next = new_ai;
-
- new_ai->ai_flags = 0;
- new_ai->ai_family = ai->ai_family;
- new_ai->ai_socktype = ai->ai_socktype;
- new_ai->ai_protocol = ai->ai_protocol;
- new_ai->ai_canonname = 0;
- new_ai->ai_addrlen = ai->ai_addrlen;
- new_ai->ai_addr = gai_alloc<sockaddr>(ai->ai_addrlen);
- memcpy(new_ai->ai_addr, ai->ai_addr, ai->ai_addrlen);
+BOOST_ASIO_DECL int setsockopt(socket_type s, state_type& state,
+ int level, int optname, const void* optval,
+ std::size_t optlen, boost::system::error_code& ec);
 
- return new_ai;
-}
+BOOST_ASIO_DECL int getsockopt(socket_type s, state_type state,
+ int level, int optname, void* optval,
+ size_t* optlen, boost::system::error_code& ec);
 
-inline int gai_port(addrinfo_type* aihead, int port, int socktype)
-{
- int num_found = 0;
+BOOST_ASIO_DECL int getpeername(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, bool cached, boost::system::error_code& ec);
 
- for (addrinfo_type* ai = aihead; ai; ai = ai->ai_next)
- {
- if (ai->ai_flags & gai_clone_flag)
- {
- if (ai->ai_socktype != 0)
- {
- ai = gai_clone(ai);
- if (ai == 0)
- return -1;
- // ai now points to newly cloned entry.
- }
- }
- else if (ai->ai_socktype != socktype)
- {
- // Ignore if mismatch on socket type.
- continue;
- }
-
- ai->ai_socktype = socktype;
-
- switch (ai->ai_family)
- {
- case AF_INET:
- {
- sockaddr_in4_type* sinptr =
- reinterpret_cast<sockaddr_in4_type*>(ai->ai_addr);
- sinptr->sin_port = port;
- ++num_found;
- break;
- }
- case AF_INET6:
- {
- sockaddr_in6_type* sin6ptr =
- reinterpret_cast<sockaddr_in6_type*>(ai->ai_addr);
- sin6ptr->sin6_port = port;
- ++num_found;
- break;
- }
- default:
- break;
- }
- }
+BOOST_ASIO_DECL int getsockname(socket_type s, socket_addr_type* addr,
+ std::size_t* addrlen, boost::system::error_code& ec);
 
- return num_found;
-}
+BOOST_ASIO_DECL int ioctl(socket_type s, state_type& state,
+ long cmd, ioctl_arg_type* arg, boost::system::error_code& ec);
 
-inline int gai_serv(addrinfo_type* aihead,
- const addrinfo_type* hints, const char* serv)
-{
- using namespace std;
+BOOST_ASIO_DECL int select(int nfds, fd_set* readfds, fd_set* writefds,
+ fd_set* exceptfds, timeval* timeout, boost::system::error_code& ec);
 
- int num_found = 0;
+BOOST_ASIO_DECL int poll_read(socket_type s, boost::system::error_code& ec);
 
- if (
-#if defined(AI_NUMERICSERV)
- (hints->ai_flags & AI_NUMERICSERV) ||
-#endif
- isdigit(serv[0]))
- {
- int port = htons(atoi(serv));
- if (hints->ai_socktype)
- {
- // Caller specifies socket type.
- int rc = gai_port(aihead, port, hints->ai_socktype);
- if (rc < 0)
- return EAI_MEMORY;
- num_found += rc;
- }
- else
- {
- // Caller does not specify socket type.
- int rc = gai_port(aihead, port, SOCK_STREAM);
- if (rc < 0)
- return EAI_MEMORY;
- num_found += rc;
- rc = gai_port(aihead, port, SOCK_DGRAM);
- if (rc < 0)
- return EAI_MEMORY;
- num_found += rc;
- }
- }
- else
- {
- // Try service name with TCP first, then UDP.
- if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_STREAM)
- {
- servent* sptr = getservbyname(serv, "tcp");
- if (sptr != 0)
- {
- int rc = gai_port(aihead, sptr->s_port, SOCK_STREAM);
- if (rc < 0)
- return EAI_MEMORY;
- num_found += rc;
- }
- }
- if (hints->ai_socktype == 0 || hints->ai_socktype == SOCK_DGRAM)
- {
- servent* sptr = getservbyname(serv, "udp");
- if (sptr != 0)
- {
- int rc = gai_port(aihead, sptr->s_port, SOCK_DGRAM);
- if (rc < 0)
- return EAI_MEMORY;
- num_found += rc;
- }
- }
- }
-
- if (num_found == 0)
- {
- if (hints->ai_socktype == 0)
- {
- // All calls to getservbyname() failed.
- return EAI_NONAME;
- }
- else
- {
- // Service not supported for socket type.
- return EAI_SERVICE;
- }
- }
+BOOST_ASIO_DECL int poll_write(socket_type s, boost::system::error_code& ec);
 
- return 0;
-}
+BOOST_ASIO_DECL int poll_connect(socket_type s, boost::system::error_code& ec);
 
-inline int gai_echeck(const char* host, const char* service,
- int flags, int family, int socktype, int protocol)
-{
- (void)(flags);
- (void)(protocol);
+BOOST_ASIO_DECL const char* inet_ntop(int af, const void* src, char* dest,
+ size_t length, unsigned long scope_id, boost::system::error_code& ec);
 
- // Host or service must be specified.
- if (host == 0 || host[0] == '\0')
- if (service == 0 || service[0] == '\0')
- return EAI_NONAME;
-
- // Check combination of family and socket type.
- switch (family)
- {
- case AF_UNSPEC:
- break;
- case AF_INET:
- case AF_INET6:
- if (service != 0 && service[0] != '\0')
- if (socktype != 0 && socktype != SOCK_STREAM && socktype != SOCK_DGRAM)
- return EAI_SOCKTYPE;
- break;
- default:
- return EAI_FAMILY;
- }
+BOOST_ASIO_DECL int inet_pton(int af, const char* src, void* dest,
+ unsigned long* scope_id, boost::system::error_code& ec);
 
- return 0;
-}
+BOOST_ASIO_DECL int gethostname(char* name,
+ int namelen, boost::system::error_code& ec);
 
-inline void freeaddrinfo_emulation(addrinfo_type* aihead)
-{
- addrinfo_type* ai = aihead;
- while (ai)
- {
- gai_free(ai->ai_addr);
- gai_free(ai->ai_canonname);
- addrinfo_type* ainext = ai->ai_next;
- gai_free(ai);
- ai = ainext;
- }
-}
+BOOST_ASIO_DECL boost::system::error_code getaddrinfo(const char* host,
+ const char* service, const addrinfo_type& hints,
+ addrinfo_type** result, boost::system::error_code& ec);
 
-inline int getaddrinfo_emulation(const char* host, const char* service,
- const addrinfo_type* hintsp, addrinfo_type** result)
-{
- // Set up linked list of addrinfo structures.
- addrinfo_type* aihead = 0;
- addrinfo_type** ainext = &aihead;
- char* canon = 0;
-
- // Supply default hints if not specified by caller.
- addrinfo_type hints = addrinfo_type();
- hints.ai_family = AF_UNSPEC;
- if (hintsp)
- hints = *hintsp;
-
- // If the resolution is not specifically for AF_INET6, remove the AI_V4MAPPED
- // and AI_ALL flags.
-#if defined(AI_V4MAPPED)
- if (hints.ai_family != AF_INET6)
- hints.ai_flags &= ~AI_V4MAPPED;
-#endif
-#if defined(AI_ALL)
- if (hints.ai_family != AF_INET6)
- hints.ai_flags &= ~AI_ALL;
-#endif
-
- // Basic error checking.
- int rc = gai_echeck(host, service, hints.ai_flags, hints.ai_family,
- hints.ai_socktype, hints.ai_protocol);
- if (rc != 0)
- {
- freeaddrinfo_emulation(aihead);
- return rc;
- }
-
- gai_search search[2];
- int search_count = gai_nsearch(host, &hints, search);
- for (gai_search* sptr = search; sptr < search + search_count; ++sptr)
- {
- // Check for IPv4 dotted decimal string.
- in4_addr_type inaddr;
- boost::system::error_code ec;
- if (socket_ops::inet_pton(AF_INET, sptr->host, &inaddr, 0, ec) == 1)
- {
- if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- return EAI_FAMILY;
- }
- if (sptr->family == AF_INET)
- {
- rc = gai_aistruct(&ainext, &hints, &inaddr, AF_INET);
- if (rc != 0)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- return rc;
- }
- }
- continue;
- }
-
- // Check for IPv6 hex string.
- in6_addr_type in6addr;
- if (socket_ops::inet_pton(AF_INET6, sptr->host, &in6addr, 0, ec) == 1)
- {
- if (hints.ai_family != AF_UNSPEC && hints.ai_family != AF_INET6)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- return EAI_FAMILY;
- }
- if (sptr->family == AF_INET6)
- {
- rc = gai_aistruct(&ainext, &hints, &in6addr, AF_INET6);
- if (rc != 0)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- return rc;
- }
- }
- continue;
- }
-
- // Look up hostname.
- hostent hent;
- char hbuf[8192] = "";
- hostent* hptr = socket_ops::gethostbyname(sptr->host,
- sptr->family, &hent, hbuf, sizeof(hbuf), hints.ai_flags, ec);
- if (hptr == 0)
- {
- if (search_count == 2)
- {
- // Failure is OK if there are multiple searches.
- continue;
- }
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- if (ec == boost::asio::error::host_not_found)
- return EAI_NONAME;
- if (ec == boost::asio::error::host_not_found_try_again)
- return EAI_AGAIN;
- if (ec == boost::asio::error::no_recovery)
- return EAI_FAIL;
- if (ec == boost::asio::error::no_data)
- return EAI_NONAME;
- return EAI_NONAME;
- }
-
- // Check for address family mismatch if one was specified.
- if (hints.ai_family != AF_UNSPEC && hints.ai_family != hptr->h_addrtype)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- socket_ops::freehostent(hptr);
- return EAI_FAMILY;
- }
-
- // Save canonical name first time.
- if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
- && (hints.ai_flags & AI_CANONNAME) && canon == 0)
- {
- std::size_t canon_len = strlen(hptr->h_name) + 1;
- canon = gai_alloc<char>(canon_len);
- if (canon == 0)
- {
- freeaddrinfo_emulation(aihead);
- socket_ops::freehostent(hptr);
- return EAI_MEMORY;
- }
- gai_strcpy(canon, hptr->h_name, canon_len);
- }
-
- // Create an addrinfo structure for each returned address.
- for (char** ap = hptr->h_addr_list; *ap; ++ap)
- {
- rc = gai_aistruct(&ainext, &hints, *ap, hptr->h_addrtype);
- if (rc != 0)
- {
- freeaddrinfo_emulation(aihead);
- gai_free(canon);
- socket_ops::freehostent(hptr);
- return EAI_FAMILY;
- }
- }
-
- socket_ops::freehostent(hptr);
- }
-
- // Check if we found anything.
- if (aihead == 0)
- {
- gai_free(canon);
- return EAI_NONAME;
- }
-
- // Return canonical name in first entry.
- if (host != 0 && host[0] != '\0' && (hints.ai_flags & AI_CANONNAME))
- {
- if (canon)
- {
- aihead->ai_canonname = canon;
- canon = 0;
- }
- else
- {
- std::size_t canonname_len = strlen(search[0].host) + 1;
- aihead->ai_canonname = gai_alloc<char>(canonname_len);
- if (aihead->ai_canonname == 0)
- {
- freeaddrinfo_emulation(aihead);
- return EAI_MEMORY;
- }
- gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
- }
- }
- gai_free(canon);
-
- // Process the service name.
- if (service != 0 && service[0] != '\0')
- {
- rc = gai_serv(aihead, &hints, service);
- if (rc != 0)
- {
- freeaddrinfo_emulation(aihead);
- return rc;
- }
- }
-
- // Return result to caller.
- *result = aihead;
- return 0;
-}
-
-inline boost::system::error_code getnameinfo_emulation(
- const socket_addr_type* sa, std::size_t salen, char* host,
- std::size_t hostlen, char* serv, std::size_t servlen, int flags,
- boost::system::error_code& ec)
-{
- using namespace std;
+BOOST_ASIO_DECL boost::system::error_code background_getaddrinfo(
+ const weak_cancel_token_type& cancel_token, const char* host,
+ const char* service, const addrinfo_type& hints,
+ addrinfo_type** result, boost::system::error_code& ec);
 
- const char* addr;
- size_t addr_len;
- unsigned short port;
- switch (sa->sa_family)
- {
- case AF_INET:
- if (salen != sizeof(sockaddr_in4_type))
- {
- return ec = boost::asio::error::invalid_argument;
- }
- addr = reinterpret_cast<const char*>(
- &reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_addr);
- addr_len = sizeof(in4_addr_type);
- port = reinterpret_cast<const sockaddr_in4_type*>(sa)->sin_port;
- break;
- case AF_INET6:
- if (salen != sizeof(sockaddr_in6_type))
- {
- return ec = boost::asio::error::invalid_argument;
- }
- addr = reinterpret_cast<const char*>(
- &reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_addr);
- addr_len = sizeof(in6_addr_type);
- port = reinterpret_cast<const sockaddr_in6_type*>(sa)->sin6_port;
- break;
- default:
- return ec = boost::asio::error::address_family_not_supported;
- }
-
- if (host && hostlen > 0)
- {
- if (flags & NI_NUMERICHOST)
- {
- if (socket_ops::inet_ntop(sa->sa_family, addr, host, hostlen, 0, ec) == 0)
- {
- return ec;
- }
- }
- else
- {
- hostent hent;
- char hbuf[8192] = "";
- hostent* hptr = socket_ops::gethostbyaddr(addr,
- static_cast<int>(addr_len), sa->sa_family,
- &hent, hbuf, sizeof(hbuf), ec);
- if (hptr && hptr->h_name && hptr->h_name[0] != '\0')
- {
- if (flags & NI_NOFQDN)
- {
- char* dot = strchr(hptr->h_name, '.');
- if (dot)
- {
- *dot = 0;
- }
- }
- gai_strcpy(host, hptr->h_name, hostlen);
- socket_ops::freehostent(hptr);
- }
- else
- {
- socket_ops::freehostent(hptr);
- if (flags & NI_NAMEREQD)
- {
- return ec = boost::asio::error::host_not_found;
- }
- if (socket_ops::inet_ntop(sa->sa_family,
- addr, host, hostlen, 0, ec) == 0)
- {
- return ec;
- }
- }
- }
- }
-
- if (serv && servlen > 0)
- {
- if (flags & NI_NUMERICSERV)
- {
- if (servlen < 6)
- {
- return ec = boost::asio::error::no_buffer_space;
- }
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
- sprintf_s(serv, servlen, "%u", ntohs(port));
-#else
- sprintf(serv, "%u", ntohs(port));
-#endif
- }
- else
- {
-#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
- static ::pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
- ::pthread_mutex_lock(&mutex);
-#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
- servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
- if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
- {
- gai_strcpy(serv, sptr->s_name, servlen);
- }
- else
- {
- if (servlen < 6)
- {
- return ec = boost::asio::error::no_buffer_space;
- }
-#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(UNDER_CE)
- sprintf_s(serv, servlen, "%u", ntohs(port));
-#else
- sprintf(serv, "%u", ntohs(port));
-#endif
- }
-#if defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
- ::pthread_mutex_unlock(&mutex);
-#endif // defined(BOOST_HAS_THREADS) && defined(BOOST_HAS_PTHREADS)
- }
- }
-
- clear_error(ec);
- return ec;
-}
+BOOST_ASIO_DECL void freeaddrinfo(addrinfo_type* ai);
 
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- // || defined(__MACH__) && defined(__APPLE__)
+BOOST_ASIO_DECL boost::system::error_code getnameinfo(
+ const socket_addr_type* addr, std::size_t addrlen,
+ char* host, std::size_t hostlen, char* serv,
+ std::size_t servlen, int flags, boost::system::error_code& ec);
 
-inline boost::system::error_code translate_addrinfo_error(int error)
-{
- switch (error)
- {
- case 0:
- return boost::system::error_code();
- case EAI_AGAIN:
- return boost::asio::error::host_not_found_try_again;
- case EAI_BADFLAGS:
- return boost::asio::error::invalid_argument;
- case EAI_FAIL:
- return boost::asio::error::no_recovery;
- case EAI_FAMILY:
- return boost::asio::error::address_family_not_supported;
- case EAI_MEMORY:
- return boost::asio::error::no_memory;
- case EAI_NONAME:
-#if defined(EAI_ADDRFAMILY)
- case EAI_ADDRFAMILY:
-#endif
-#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
- case EAI_NODATA:
-#endif
- return boost::asio::error::host_not_found;
- case EAI_SERVICE:
- return boost::asio::error::service_not_found;
- case EAI_SOCKTYPE:
- return boost::asio::error::socket_type_not_supported;
- default: // Possibly the non-portable EAI_SYSTEM.
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
- return boost::system::error_code(
- WSAGetLastError(), boost::asio::error::get_system_category());
-#else
- return boost::system::error_code(
- errno, boost::asio::error::get_system_category());
-#endif
- }
-}
-
-inline boost::system::error_code getaddrinfo(const char* host,
- const char* service, const addrinfo_type* hints, addrinfo_type** result,
- boost::system::error_code& ec)
-{
- clear_error(ec);
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
- // Building for Windows XP, Windows Server 2003, or later.
- int error = ::getaddrinfo(host, service, hints, result);
- return ec = translate_addrinfo_error(error);
-# else
- // Building for Windows 2000 or earlier.
- typedef int (WSAAPI *gai_t)(const char*,
- const char*, const addrinfo_type*, addrinfo_type**);
- if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
- {
- if (gai_t gai = (gai_t)::GetProcAddress(winsock_module, "getaddrinfo"))
- {
- int error = gai(host, service, hints, result);
- return ec = translate_addrinfo_error(error);
- }
- }
- int error = getaddrinfo_emulation(host, service, hints, result);
- return ec = translate_addrinfo_error(error);
-# endif
-#elif defined(__MACH__) && defined(__APPLE__)
- int error = getaddrinfo_emulation(host, service, hints, result);
- return ec = translate_addrinfo_error(error);
-#else
- int error = ::getaddrinfo(host, service, hints, result);
- return ec = translate_addrinfo_error(error);
-#endif
-}
+BOOST_ASIO_DECL boost::system::error_code sync_getnameinfo(
+ const socket_addr_type* addr, std::size_t addrlen,
+ char* host, std::size_t hostlen, char* serv,
+ std::size_t servlen, int sock_type, boost::system::error_code& ec);
 
-inline void freeaddrinfo(addrinfo_type* ai)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
- // Building for Windows XP, Windows Server 2003, or later.
- ::freeaddrinfo(ai);
-# else
- // Building for Windows 2000 or earlier.
- typedef int (WSAAPI *fai_t)(addrinfo_type*);
- if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
- {
- if (fai_t fai = (fai_t)::GetProcAddress(winsock_module, "freeaddrinfo"))
- {
- fai(ai);
- return;
- }
- }
- freeaddrinfo_emulation(ai);
-# endif
-#elif defined(__MACH__) && defined(__APPLE__)
- freeaddrinfo_emulation(ai);
-#else
- ::freeaddrinfo(ai);
-#endif
-}
-
-inline boost::system::error_code getnameinfo(const socket_addr_type* addr,
- std::size_t addrlen, char* host, std::size_t hostlen,
- char* serv, std::size_t servlen, int flags, boost::system::error_code& ec)
-{
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) || defined(UNDER_CE)
- // Building for Windows XP, Windows Server 2003, or later.
- clear_error(ec);
- int error = ::getnameinfo(addr, static_cast<socklen_t>(addrlen),
- host, static_cast<DWORD>(hostlen),
- serv, static_cast<DWORD>(servlen), flags);
- return ec = translate_addrinfo_error(error);
-# else
- // Building for Windows 2000 or earlier.
- typedef int (WSAAPI *gni_t)(const socket_addr_type*,
- int, char*, DWORD, char*, DWORD, int);
- if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
- {
- if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
- {
- clear_error(ec);
- int error = gni(addr, static_cast<int>(addrlen),
- host, static_cast<DWORD>(hostlen),
- serv, static_cast<DWORD>(servlen), flags);
- return ec = translate_addrinfo_error(error);
- }
- }
- clear_error(ec);
- return getnameinfo_emulation(addr, addrlen,
- host, hostlen, serv, servlen, flags, ec);
-# endif
-#elif defined(__MACH__) && defined(__APPLE__)
- using namespace std; // For memcpy.
- sockaddr_storage_type tmp_addr;
- memcpy(&tmp_addr, addr, addrlen);
- tmp_addr.ss_len = addrlen;
- addr = reinterpret_cast<socket_addr_type*>(&tmp_addr);
- clear_error(ec);
- return getnameinfo_emulation(addr, addrlen,
- host, hostlen, serv, servlen, flags, ec);
-#else
- clear_error(ec);
- int error = ::getnameinfo(addr, addrlen, host, hostlen, serv, servlen, flags);
- return ec = translate_addrinfo_error(error);
-#endif
-}
+BOOST_ASIO_DECL boost::system::error_code background_getnameinfo(
+ const weak_cancel_token_type& cancel_token,
+ const socket_addr_type* addr, std::size_t addrlen,
+ char* host, std::size_t hostlen, char* serv,
+ std::size_t servlen, int sock_type, boost::system::error_code& ec);
 
-inline u_long_type network_to_host_long(u_long_type value)
-{
- return ntohl(value);
-}
+BOOST_ASIO_DECL u_long_type network_to_host_long(u_long_type value);
 
-inline u_long_type host_to_network_long(u_long_type value)
-{
- return htonl(value);
-}
+BOOST_ASIO_DECL u_long_type host_to_network_long(u_long_type value);
 
-inline u_short_type network_to_host_short(u_short_type value)
-{
- return ntohs(value);
-}
+BOOST_ASIO_DECL u_short_type network_to_host_short(u_short_type value);
 
-inline u_short_type host_to_network_short(u_short_type value)
-{
- return htons(value);
-}
+BOOST_ASIO_DECL u_short_type host_to_network_short(u_short_type value);
 
 } // namespace socket_ops
 } // namespace detail
@@ -1911,4 +284,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/socket_ops.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_DETAIL_SOCKET_OPS_HPP

Modified: trunk/boost/asio/detail/socket_option.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_option.hpp (original)
+++ trunk/boost/asio/detail/socket_option.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_option.hpp
-// ~~~~~~~~~~~~~~~~~
+// detail/socket_option.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,15 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <stdexcept>
 #include <boost/config.hpp>
 #include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/socket_select_interrupter.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_select_interrupter.hpp (original)
+++ trunk/boost/asio/detail/socket_select_interrupter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_select_interrupter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/socket_select_interrupter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,19 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstdlib>
-#include <boost/throw_exception.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_holder.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -36,135 +31,16 @@
 {
 public:
   // Constructor.
- socket_select_interrupter()
- {
- boost::system::error_code ec;
- socket_holder acceptor(socket_ops::socket(
- AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
- if (acceptor.get() == invalid_socket)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- int opt = 1;
- socket_ops::setsockopt(acceptor.get(),
- SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt), ec);
-
- using namespace std; // For memset.
- sockaddr_in4_type addr;
- std::size_t addr_len = sizeof(addr);
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
- addr.sin_port = 0;
- if (socket_ops::bind(acceptor.get(), (const socket_addr_type*)&addr,
- addr_len, ec) == socket_error_retval)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- if (socket_ops::getsockname(acceptor.get(), (socket_addr_type*)&addr,
- &addr_len, ec) == socket_error_retval)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- // Some broken firewalls on Windows will intermittently cause getsockname to
- // return 0.0.0.0 when the socket is actually bound to 127.0.0.1. We
- // explicitly specify the target address here to work around this problem.
- addr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
- if (socket_ops::listen(acceptor.get(),
- SOMAXCONN, ec) == socket_error_retval)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- socket_holder client(socket_ops::socket(
- AF_INET, SOCK_STREAM, IPPROTO_TCP, ec));
- if (client.get() == invalid_socket)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- if (socket_ops::connect(client.get(), (const socket_addr_type*)&addr,
- addr_len, ec) == socket_error_retval)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- socket_holder server(socket_ops::accept(acceptor.get(), 0, 0, ec));
- if (server.get() == invalid_socket)
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- ioctl_arg_type non_blocking = 1;
- if (socket_ops::ioctl(client.get(), FIONBIO, &non_blocking, ec))
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- opt = 1;
- socket_ops::setsockopt(client.get(),
- IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
-
- non_blocking = 1;
- if (socket_ops::ioctl(server.get(), FIONBIO, &non_blocking, ec))
- {
- boost::system::system_error e(ec, "socket_select_interrupter");
- boost::throw_exception(e);
- }
-
- opt = 1;
- socket_ops::setsockopt(server.get(),
- IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt), ec);
-
- read_descriptor_ = server.release();
- write_descriptor_ = client.release();
- }
+ BOOST_ASIO_DECL socket_select_interrupter();
 
   // Destructor.
- ~socket_select_interrupter()
- {
- boost::system::error_code ec;
- if (read_descriptor_ != invalid_socket)
- socket_ops::close(read_descriptor_, ec);
- if (write_descriptor_ != invalid_socket)
- socket_ops::close(write_descriptor_, ec);
- }
+ BOOST_ASIO_DECL ~socket_select_interrupter();
 
   // Interrupt the select call.
- void interrupt()
- {
- char byte = 0;
- socket_ops::buf b;
- socket_ops::init_buf(b, &byte, 1);
- boost::system::error_code ec;
- socket_ops::send(write_descriptor_, &b, 1, 0, ec);
- }
+ BOOST_ASIO_DECL void interrupt();
 
   // Reset the select interrupt. Returns true if the call was interrupted.
- bool reset()
- {
- char data[1024];
- socket_ops::buf b;
- socket_ops::init_buf(b, data, sizeof(data));
- boost::system::error_code ec;
- int bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
- bool was_interrupted = (bytes_read > 0);
- while (bytes_read == sizeof(data))
- bytes_read = socket_ops::recv(read_descriptor_, &b, 1, 0, ec);
- return was_interrupted;
- }
+ BOOST_ASIO_DECL bool reset();
 
   // Get the read descriptor to be passed to select.
   socket_type read_descriptor() const
@@ -191,4 +67,10 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/socket_select_interrupter.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_SOCKET_SELECT_INTERRUPTER_HPP

Modified: trunk/boost/asio/detail/socket_types.hpp
==============================================================================
--- trunk/boost/asio/detail/socket_types.hpp (original)
+++ trunk/boost/asio/detail/socket_types.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_types.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/socket_types.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,69 +15,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 # if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
 # error WinSock.h has already been included
 # endif // defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
-# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
-# if defined(_MSC_VER) || defined(__BORLANDC__)
-# pragma message( \
- "Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
- "- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
- "- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
- "Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
-# else // defined(_MSC_VER) || defined(__BORLANDC__)
-# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
-# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
-# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
-# endif // defined(_MSC_VER) || defined(__BORLANDC__)
-# define _WIN32_WINNT 0x0501
-# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
-# if defined(_MSC_VER)
-# if defined(_WIN32) && !defined(WIN32)
-# if !defined(_WINSOCK2API_)
-# define WIN32 // Needed for correct types in winsock2.h
-# else // !defined(_WINSOCK2API_)
-# error Please define the macro WIN32 in your compiler options
-# endif // !defined(_WINSOCK2API_)
-# endif // defined(_WIN32) && !defined(WIN32)
-# endif // defined(_MSC_VER)
 # if defined(__BORLANDC__)
 # include <stdlib.h> // Needed for __errno
-# if defined(__WIN32__) && !defined(WIN32)
-# if !defined(_WINSOCK2API_)
-# define WIN32 // Needed for correct types in winsock2.h
-# else // !defined(_WINSOCK2API_)
-# error Please define the macro WIN32 in your compiler options
-# endif // !defined(_WINSOCK2API_)
-# endif // defined(__WIN32__) && !defined(WIN32)
 # if !defined(_WSPIAPI_H_)
 # define _WSPIAPI_H_
 # define BOOST_ASIO_WSPIAPI_H_DEFINED
 # endif // !defined(_WSPIAPI_H_)
 # endif // defined(__BORLANDC__)
-# if !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
-# if !defined(WIN32_LEAN_AND_MEAN)
-# define WIN32_LEAN_AND_MEAN
-# endif // !defined(WIN32_LEAN_AND_MEAN)
-# endif // !defined(BOOST_ASIO_NO_WIN32_LEAN_AND_MEAN)
-# if !defined(BOOST_ASIO_NO_NOMINMAX)
-# if !defined(NOMINMAX)
-# define NOMINMAX 1
-# endif // !defined(NOMINMAX)
-# endif // !defined(BOOST_ASIO_NO_NOMINMAX)
-# if defined(__CYGWIN__)
-# if !defined(__USE_W32_SOCKETS)
-# error You must add -D__USE_W32_SOCKETS to your compiler options.
-# endif // !defined(__USE_W32_SOCKETS)
-# endif // defined(__CYGWIN__)
 # include <winsock2.h>
 # include <ws2tcpip.h>
 # include <mswsock.h>
@@ -98,6 +48,8 @@
 # include <sys/ioctl.h>
 # include <sys/poll.h>
 # include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
 # if defined(__hpux) && !defined(__HP_aCC)
 # include <sys/time.h>
 # else
@@ -117,7 +69,8 @@
 # include <sys/sockio.h>
 # endif
 #endif
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/detail/solaris_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/solaris_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/solaris_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// solaris_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/solaris_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,13 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(__sun)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <atomic.h>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -52,8 +48,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(__sun)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(__sun)
+
 #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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// strand_service.hpp
-// ~~~~~~~~~~~~~~~~~~
+// detail/strand_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,23 +15,14 @@
 # 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/functional/hash.hpp>
+#include <boost/asio/detail/config.hpp>
 #include <boost/scoped_ptr.hpp>
-#include <boost/asio/detail/pop_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/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/operation.hpp>
-#include <boost/asio/detail/service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -42,7 +33,10 @@
   : public boost::asio::detail::service_base<strand_service>
 {
 private:
+ // Helper class to re-post the strand on exit.
   struct on_do_complete_exit;
+
+ // Helper class to re-post the strand on exit.
   struct on_dispatch_exit;
 
 public:
@@ -52,11 +46,7 @@
     : public operation
   {
   public:
- strand_impl()
- : operation(&strand_service::do_complete),
- count_(0)
- {
- }
+ strand_impl();
 
   private:
     // Only this service will have access to the internal values.
@@ -77,180 +67,29 @@
   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)
- {
- }
+ BOOST_ASIO_DECL explicit strand_service(boost::asio::io_service& io_service);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- op_queue<operation> ops;
-
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- for (std::size_t i = 0; i < num_implementations; ++i)
- if (strand_impl* impl = implementations_[i].get())
- ops.push(impl->queue_);
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Construct a new strand implementation.
- void construct(implementation_type& impl)
- {
- std::size_t index = boost::hash_value(&impl);
- boost::hash_combine(index, salt_++);
- index = index % num_implementations;
-
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- if (!implementations_[index])
- implementations_[index].reset(new strand_impl);
- impl = implementations_[index].get();
- }
+ BOOST_ASIO_DECL void construct(implementation_type& impl);
 
   // Destroy a strand implementation.
- void destroy(implementation_type& impl)
- {
- impl = 0;
- }
+ void destroy(implementation_type& impl);
 
   // Request the io_service to invoke the given handler.
   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;
- }
-
- // 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)
- {
- // 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);
- }
+ void dispatch(implementation_type& impl, Handler handler);
 
   // Request the io_service to invoke the given handler and return immediately.
   template <typename Handler>
- void post(implementation_type& impl, Handler handler)
- {
- // 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);
-
- // 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);
- }
+ void post(implementation_type& impl, Handler handler);
 
 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_;
-
- ~on_do_complete_exit()
- {
- impl_->mutex_.lock();
- bool more_handlers = (--impl_->count_ > 0);
- impl_->mutex_.unlock();
-
- if (more_handlers)
- owner_->post_immediate_completion(impl_);
- }
- };
-
- // Helper class to re-post the strand on exit.
- struct on_dispatch_exit
- {
- io_service_impl* io_service_;
- strand_impl* impl_;
-
- ~on_dispatch_exit()
- {
- impl_->mutex_.lock();
- bool more_handlers = (--impl_->count_ > 0);
- impl_->mutex_.unlock();
-
- if (more_handlers)
- io_service_->post_immediate_completion(impl_);
- }
- };
+ BOOST_ASIO_DECL static void do_complete(io_service_impl* owner,
+ operation* base, boost::system::error_code ec,
+ std::size_t bytes_transferred);
 
   // The io_service implementation used to post completions.
   io_service_impl& io_service_;
@@ -275,4 +114,9 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/strand_service.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/strand_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_DETAIL_STRAND_SERVICE_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// task_io_service.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// detail/task_io_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,181 +15,60 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if !defined(BOOST_ASIO_HAS_IOCP)
 
+#include <boost/detail/atomic_count.hpp>
+#include <boost/system/error_code.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/mutex.hpp>
 #include <boost/asio/detail/op_queue.hpp>
-#include <boost/asio/detail/service_base.hpp>
+#include <boost/asio/detail/reactor_fwd.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 {
 namespace detail {
 
-template <typename Task>
 class task_io_service
- : public boost::asio::detail::service_base<task_io_service<Task> >
+ : public boost::asio::detail::service_base<task_io_service>
 {
 public:
- typedef task_io_service_operation<Task> operation;
+ typedef task_io_service_operation operation;
 
   // Constructor.
- task_io_service(boost::asio::io_service& io_service)
- : boost::asio::detail::service_base<task_io_service<Task> >(io_service),
- mutex_(),
- task_(0),
- task_interrupted_(true),
- outstanding_work_(0),
- stopped_(false),
- shutdown_(false),
- first_idle_thread_(0)
- {
- }
+ BOOST_ASIO_DECL task_io_service(boost::asio::io_service& io_service);
 
- void init(size_t /*concurrency_hint*/)
- {
- }
+ // How many concurrent threads are likely to run the io_service.
+ BOOST_ASIO_DECL void init(std::size_t concurrency_hint);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- shutdown_ = true;
- lock.unlock();
-
- // Destroy handler objects.
- while (!op_queue_.empty())
- {
- operation* o = op_queue_.front();
- op_queue_.pop();
- if (o != &task_operation_)
- o->destroy();
- }
-
- // Reset to initial state.
- task_ = 0;
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task, if required.
- void init_task()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (!shutdown_ && !task_)
- {
- task_ = &use_service<Task>(this->get_io_service());
- op_queue_.push(&task_operation_);
- wake_one_thread_and_unlock(lock);
- }
- }
+ BOOST_ASIO_DECL void init_task();
 
   // 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;
- this_idle_thread.next = 0;
-
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- size_t n = 0;
- for (; do_one(lock, &this_idle_thread); lock.lock())
- if (n != (std::numeric_limits<size_t>::max)())
- ++n;
- return n;
- }
+ BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec);
 
   // 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;
- this_idle_thread.next = 0;
-
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- return do_one(lock, &this_idle_thread);
- }
+ BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& 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);
-
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
-
- size_t n = 0;
- for (; do_one(lock, 0); lock.lock())
- if (n != (std::numeric_limits<size_t>::max)())
- ++n;
- return n;
- }
+ BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec);
 
   // 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);
- }
+ BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec);
 
   // Interrupt the event processing loop.
- void stop()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- stop_all_threads(lock);
- }
+ BOOST_ASIO_DECL void stop();
 
   // Reset in preparation for a subsequent run invocation.
- void reset()
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- stopped_ = false;
- }
+ BOOST_ASIO_DECL void reset();
 
   // Notify that some work has started.
   void work_started()
@@ -206,228 +85,60 @@
 
   // Request invocation of the given handler.
   template <typename Handler>
- 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);
- }
+ void dispatch(Handler 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.
- 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);
-
- post_immediate_completion(ptr.get());
- ptr.release();
- }
+ void post(Handler handler);
 
   // 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);
- }
+ BOOST_ASIO_DECL void post_immediate_completion(operation* 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);
- }
+ BOOST_ASIO_DECL void post_deferred_completion(operation* op);
 
   // 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())
- {
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- op_queue_.push(ops);
- wake_one_thread_and_unlock(lock);
- }
- }
+ BOOST_ASIO_DECL void post_deferred_completions(op_queue<operation>& ops);
 
 private:
+ // Structure containing information about an idle thread.
   struct idle_thread_info;
 
- size_t do_one(boost::asio::detail::mutex::scoped_lock& lock,
- idle_thread_info* this_idle_thread)
- {
- bool polling = !this_idle_thread;
- bool task_has_run = false;
- while (!stopped_)
- {
- if (!op_queue_.empty())
- {
- // Prepare to execute first handler from queue.
- operation* o = op_queue_.front();
- op_queue_.pop();
- bool more_handlers = (!op_queue_.empty());
-
- if (o == &task_operation_)
- {
- 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;
- op_queue_.push(&task_operation_);
- return 0;
- }
- task_has_run = true;
-
- if (!more_handlers || !wake_one_idle_thread_and_unlock(lock))
- 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
- {
- 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;
-
- // Complete the operation. May throw an exception.
- o->complete(*this); // deletes the operation object
-
- return 1;
- }
- }
- else if (this_idle_thread)
- {
- // Nothing to run right now, so just wait for work to do.
- this_idle_thread->next = first_idle_thread_;
- first_idle_thread_ = this_idle_thread;
- this_idle_thread->wakeup_event.clear(lock);
- this_idle_thread->wakeup_event.wait(lock);
- }
- else
- {
- return 0;
- }
- }
-
- return 0;
- }
+ // Run at most one operation. Blocks only if this_idle_thread is non-null.
+ BOOST_ASIO_DECL std::size_t do_one(mutex::scoped_lock& lock,
+ idle_thread_info* this_idle_thread);
 
   // Stop the task and all idle threads.
- void stop_all_threads(
- boost::asio::detail::mutex::scoped_lock& lock)
- {
- stopped_ = true;
-
- 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;
- task_->interrupt();
- }
- }
+ BOOST_ASIO_DECL void stop_all_threads(mutex::scoped_lock& lock);
 
   // 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_)
- {
- idle_thread_info* idle_thread = first_idle_thread_;
- first_idle_thread_ = idle_thread->next;
- idle_thread->next = 0;
- idle_thread->wakeup_event.signal_and_unlock(lock);
- return true;
- }
- return false;
- }
+ BOOST_ASIO_DECL bool wake_one_idle_thread_and_unlock(
+ mutex::scoped_lock& lock);
 
   // 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)
- {
- if (!wake_one_idle_thread_and_unlock(lock))
- {
- if (!task_interrupted_ && task_)
- {
- task_interrupted_ = true;
- task_->interrupt();
- }
- lock.unlock();
- }
- }
+ BOOST_ASIO_DECL void wake_one_thread_and_unlock(
+ mutex::scoped_lock& lock);
 
   // Helper class to perform task-related operations on block exit.
   struct task_cleanup;
   friend struct task_cleanup;
- struct task_cleanup
- {
- ~task_cleanup()
- {
- // 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_);
- }
-
- task_io_service* task_io_service_;
- boost::asio::detail::mutex::scoped_lock* lock_;
- op_queue<operation>* ops_;
- };
 
   // Helper class to call work_finished() on block exit.
- struct work_finished_on_block_exit
- {
- ~work_finished_on_block_exit()
- {
- task_io_service_->work_finished();
- }
-
- task_io_service* task_io_service_;
- };
+ struct work_finished_on_block_exit;
 
   // Mutex to protect access to internal data.
- boost::asio::detail::mutex mutex_;
+ mutex mutex_;
 
   // The task to be run by this service.
- Task* task_;
+ reactor* task_;
 
   // Operation object to represent the position of the task in the queue.
- struct task_operation : public operation
+ struct task_operation : operation
   {
     task_operation() : operation(0) {}
   } task_operation_;
@@ -447,13 +158,6 @@
   // Flag to indicate that the dispatcher has been shut down.
   bool shutdown_;
 
- // Structure containing information about an idle thread.
- struct idle_thread_info
- {
- event wakeup_event;
- idle_thread_info* next;
- };
-
   // The threads that are currently idle.
   idle_thread_info* first_idle_thread_;
 };
@@ -464,4 +168,11 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/task_io_service.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/task_io_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // !defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP

Modified: trunk/boost/asio/detail/task_io_service_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service_fwd.hpp (original)
+++ trunk/boost/asio/detail/task_io_service_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// task_io_service_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// detail/task_io_service_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,19 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <typename Task>
 class task_io_service;
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_FWD_HPP

Modified: trunk/boost/asio/detail/task_io_service_operation.hpp
==============================================================================
--- trunk/boost/asio/detail/task_io_service_operation.hpp (original)
+++ trunk/boost/asio/detail/task_io_service_operation.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// task_io_service_operation.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/task_io_service_operation.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,22 +15,22 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/system/error_code.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/task_io_service_fwd.hpp>
 
+#include <boost/asio/detail/push_options.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)
+ void complete(task_io_service& owner)
   {
     func_(&owner, this, boost::system::error_code(), 0);
   }
@@ -41,8 +41,9 @@
   }
 
 protected:
- typedef void (*func_type)(task_io_service<Task>*,
- task_io_service_operation*, boost::system::error_code, std::size_t);
+ typedef void (*func_type)(task_io_service*,
+ task_io_service_operation*,
+ boost::system::error_code, std::size_t);
 
   task_io_service_operation(func_type func)
     : next_(0),
@@ -65,7 +66,6 @@
 } // 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

Modified: trunk/boost/asio/detail/thread.hpp
==============================================================================
--- trunk/boost/asio/detail/thread.hpp (original)
+++ trunk/boost/asio/detail/thread.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// thread.hpp
-// ~~~~~~~~~~
+// detail/thread.hpp
+// ~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_thread.hpp>
@@ -55,6 +51,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_THREAD_HPP

Modified: trunk/boost/asio/detail/throw_error.hpp
==============================================================================
--- trunk/boost/asio/detail/throw_error.hpp (original)
+++ trunk/boost/asio/detail/throw_error.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// throw_error.hpp
-// ~~~~~~~~~~~~~~~
+// detail/throw_error.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,26 +15,31 @@
 # 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/throw_exception.hpp>
+#include <boost/asio/detail/config.hpp>
 #include <boost/system/error_code.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
+BOOST_ASIO_DECL void do_throw_error(const boost::system::error_code& err);
+
+BOOST_ASIO_DECL void do_throw_error(const boost::system::error_code& err,
+ const char* location);
+
 inline void throw_error(const boost::system::error_code& err)
 {
   if (err)
- {
- boost::system::system_error e(err);
- boost::throw_exception(e);
- }
+ do_throw_error(err);
+}
+
+inline void throw_error(const boost::system::error_code& err,
+ const char* location)
+{
+ if (err)
+ do_throw_error(err, location);
 }
 
 } // namespace detail
@@ -43,4 +48,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/throw_error.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_DETAIL_THROW_ERROR_HPP

Modified: trunk/boost/asio/detail/timer_op.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_op.hpp (original)
+++ trunk/boost/asio/detail/timer_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_op.hpp
-// ~~~~~~~~~~~~
+// detail/timer_op.hpp
+// ~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/operation.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/timer_queue.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue.hpp (original)
+++ trunk/boost/asio/detail/timer_queue.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_queue.hpp
-// ~~~~~~~~~~~~~~~
+// detail/timer_queue.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,21 +15,24 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <memory>
 #include <vector>
 #include <boost/config.hpp>
 #include <boost/limits.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/hash_map.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/timer_op.hpp>
 #include <boost/asio/detail/timer_queue_base.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/time_traits.hpp>
+
+#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/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -273,6 +276,59 @@
   std::vector<timer*> heap_;
 };
 
+#if !defined(BOOST_ASIO_HEADER_ONLY)
+
+struct forwarding_posix_time_traits : time_traits<boost::posix_time::ptime> {};
+
+// Template specialisation for the commonly used instantation.
+template <>
+class timer_queue<time_traits<boost::posix_time::ptime> >
+ : public timer_queue_base
+{
+public:
+ // The time type.
+ typedef boost::posix_time::ptime time_type;
+
+ // The duration type.
+ typedef boost::posix_time::time_duration duration_type;
+
+ // Constructor.
+ BOOST_ASIO_DECL timer_queue();
+
+ // Destructor.
+ BOOST_ASIO_DECL virtual ~timer_queue();
+
+ // 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.
+ BOOST_ASIO_DECL bool enqueue_timer(const time_type& time,
+ timer_op* op, void* token);
+
+ // Whether there are no timers in the queue.
+ BOOST_ASIO_DECL virtual bool empty() const;
+
+ // Get the time for the timer that is earliest in the queue.
+ BOOST_ASIO_DECL virtual long wait_duration_msec(long max_duration) const;
+
+ // Get the time for the timer that is earliest in the queue.
+ BOOST_ASIO_DECL virtual long wait_duration_usec(long max_duration) const;
+
+ // Dequeue all timers not later than the current time.
+ BOOST_ASIO_DECL virtual void get_ready_timers(op_queue<operation>& ops);
+
+ // Dequeue all timers.
+ BOOST_ASIO_DECL virtual void get_all_timers(op_queue<operation>& ops);
+
+ // Cancel and dequeue the timers with the given token.
+ BOOST_ASIO_DECL std::size_t cancel_timer(
+ void* timer_token, op_queue<operation>& ops);
+
+private:
+ timer_queue<forwarding_posix_time_traits> impl_;
+};
+
+#endif // !defined(BOOST_ASIO_HEADER_ONLY)
+
 } // namespace detail
 } // namespace asio
 } // namespace boost

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_queue_base.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/timer_queue_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,12 +15,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/op_queue.hpp>
 #include <boost/asio/detail/operation.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Modified: trunk/boost/asio/detail/timer_queue_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue_fwd.hpp (original)
+++ trunk/boost/asio/detail/timer_queue_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_queue_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// detail/timer_queue_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,8 +15,6 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
 namespace boost {
 namespace asio {
 namespace detail {
@@ -28,6 +26,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_FWD_HPP

Modified: trunk/boost/asio/detail/timer_queue_set.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_queue_set.hpp (original)
+++ trunk/boost/asio/detail/timer_queue_set.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_queue_set.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// detail/timer_queue_set.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/timer_queue_base.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -27,82 +28,28 @@
 {
 public:
   // Constructor.
- timer_queue_set()
- : first_(0)
- {
- }
+ BOOST_ASIO_DECL timer_queue_set();
 
   // Add a timer queue to the set.
- void insert(timer_queue_base* q)
- {
- q->next_ = first_;
- first_ = q;
- }
+ BOOST_ASIO_DECL void insert(timer_queue_base* 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;
- }
- }
- }
- }
+ BOOST_ASIO_DECL void erase(timer_queue_base* q);
 
   // 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;
- }
+ BOOST_ASIO_DECL bool all_empty() const;
 
   // 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;
- }
+ BOOST_ASIO_DECL long wait_duration_msec(long max_duration) const;
 
   // 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;
- }
+ BOOST_ASIO_DECL long wait_duration_usec(long max_duration) const;
 
   // 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);
- }
+ BOOST_ASIO_DECL void get_ready_timers(op_queue<operation>& 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);
- }
+ BOOST_ASIO_DECL void get_all_timers(op_queue<operation>& ops);
 
 private:
   timer_queue_base* first_;
@@ -114,4 +61,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/timer_queue_set.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_DETAIL_TIMER_QUEUE_SET_HPP

Modified: trunk/boost/asio/detail/timer_scheduler.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_scheduler.hpp (original)
+++ trunk/boost/asio/detail/timer_scheduler.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_scheduler.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// detail/timer_scheduler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,8 +15,7 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/timer_scheduler_fwd.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
@@ -31,6 +30,4 @@
 # include <boost/asio/detail/select_reactor.hpp>
 #endif
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_DETAIL_TIMER_SCHEDULER_HPP

Modified: trunk/boost/asio/detail/timer_scheduler_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/timer_scheduler_fwd.hpp (original)
+++ trunk/boost/asio/detail/timer_scheduler_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// timer_scheduler_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// detail/timer_scheduler_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.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>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_EPOLL)
+# include <boost/asio/detail/epoll_reactor_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_KQUEUE)
+# include <boost/asio/detail/kqueue_reactor_fwd.hpp>
+#elif defined(BOOST_ASIO_HAS_DEV_POLL)
+# include <boost/asio/detail/dev_poll_reactor_fwd.hpp>
+#else
+# include <boost/asio/detail/select_reactor_fwd.hpp>
+#endif
 
 namespace boost {
 namespace asio {
@@ -36,13 +42,11 @@
 #elif defined(BOOST_ASIO_HAS_DEV_POLL)
 typedef dev_poll_reactor timer_scheduler;
 #else
-typedef select_reactor<false> timer_scheduler;
+typedef select_reactor 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/tss_ptr.hpp
==============================================================================
--- trunk/boost/asio/detail/tss_ptr.hpp (original)
+++ trunk/boost/asio/detail/tss_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// tss_ptr.hpp
-// ~~~~~~~~~~~
+// detail/tss_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,7 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_HAS_THREADS) || defined(BOOST_ASIO_DISABLE_THREADS)
 # include <boost/asio/detail/null_tss_ptr.hpp>
@@ -31,6 +27,8 @@
 # error Only Windows and POSIX are supported!
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {

Added: trunk/boost/asio/detail/wait_handler.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/wait_handler.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,78 @@
+//
+// detail/wait_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_WAIT_HANDLER_HPP
+#define BOOST_ASIO_DETAIL_WAIT_HANDLER_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.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/timer_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class wait_handler : public timer_op
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(wait_handler);
+
+ wait_handler(Handler h)
+ : timer_op(&wait_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.
+ wait_handler* h(static_cast<wait_handler*>(base));
+ ptr p = { boost::addressof(h->handler_), h, h };
+
+ // 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_);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_WAIT_HANDLER_HPP

Added: trunk/boost/asio/detail/weak_ptr.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/weak_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,41 @@
+//
+// detail/weak_ptr.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_WEAK_PTR_HPP
+#define BOOST_ASIO_DETAIL_WEAK_PTR_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/version.hpp>
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+# include <memory>
+#else
+# include <boost/weak_ptr.hpp>
+#endif
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1600)
+using std::weak_ptr;
+#else
+using boost::weak_ptr;
+#endif
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#endif // BOOST_ASIO_DETAIL_WEAK_PTR_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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_event.hpp
-// ~~~~~~~~~~~~~
+// detail/win_event.hpp
+// ~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,23 +15,15 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS)
 
-#include <boost/asio/error.hpp>
+#include <boost/assert.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/assert.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -42,19 +34,7 @@
 {
 public:
   // Constructor.
- win_event()
- : event_(::CreateEvent(0, true, false, 0))
- {
- if (!event_)
- {
- DWORD last_error = ::GetLastError();
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "event");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL win_event();
 
   // Destructor.
   ~win_event()
@@ -107,8 +87,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_event.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS)
+
 #endif // BOOST_ASIO_DETAIL_WIN_EVENT_HPP

Modified: trunk/boost/asio/detail/win_fd_set_adapter.hpp
==============================================================================
--- trunk/boost/asio/detail/win_fd_set_adapter.hpp (original)
+++ trunk/boost/asio/detail/win_fd_set_adapter.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_fd_set_adapter.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_fd_set_adapter.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
 #include <boost/asio/detail/socket_types.hpp>
 
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -83,8 +85,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_WIN_FD_SET_ADAPTER_HPP

Modified: trunk/boost/asio/detail/win_fenced_block.hpp
==============================================================================
--- trunk/boost/asio/detail/win_fenced_block.hpp (original)
+++ trunk/boost/asio/detail/win_fenced_block.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_fenced_block.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// detail/win_fenced_block.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,14 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
 
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -70,8 +68,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
 #endif // BOOST_ASIO_DETAIL_WIN_FENCED_BLOCK_HPP

Added: trunk/boost/asio/detail/win_iocp_handle_read_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_handle_read_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,103 @@
+//
+// detail/win_iocp_handle_read_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_HANDLE_READ_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/error.hpp>
+#include <boost/utility/addressof.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/operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Handler>
+class win_iocp_handle_read_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_read_op);
+
+ win_iocp_handle_read_op(const MutableBufferSequence& buffers, Handler handler)
+ : operation(&win_iocp_handle_read_op::do_complete),
+ buffers_(buffers),
+ 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 operation object.
+ win_iocp_handle_read_op* o(static_cast<win_iocp_handle_read_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ if (owner)
+ {
+ // 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.
+ if (ec.value() == 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. 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ MutableBufferSequence buffers_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_READ_OP_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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_handle_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
@@ -16,26 +16,23 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <boost/cstdint.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/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_handle_read_op.hpp>
+#include <boost/asio/detail/win_iocp_handle_write_op.hpp>
 #include <boost/asio/detail/win_iocp_io_service.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -77,75 +74,20 @@
     implementation_type* prev_;
   };
 
- win_iocp_handle_service(boost::asio::io_service& io_service)
- : iocp_service_(boost::asio::use_service<win_iocp_io_service>(io_service)),
- mutex_(),
- impl_list_(0)
- {
- }
+ BOOST_ASIO_DECL win_iocp_handle_service(boost::asio::io_service& io_service);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- // Close all implementations, causing all operations to complete.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- implementation_type* impl = impl_list_;
- while (impl)
- {
- close_for_destruction(*impl);
- impl = impl->next_;
- }
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Construct a new handle implementation.
- void construct(implementation_type& impl)
- {
- impl.handle_ = INVALID_HANDLE_VALUE;
- impl.safe_cancellation_thread_id_ = 0;
-
- // Insert implementation into linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- impl.next_ = impl_list_;
- impl.prev_ = 0;
- if (impl_list_)
- impl_list_->prev_ = &impl;
- impl_list_ = &impl;
- }
+ BOOST_ASIO_DECL void construct(implementation_type& impl);
 
   // Destroy a handle implementation.
- void destroy(implementation_type& impl)
- {
- close_for_destruction(impl);
-
- // Remove implementation from linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (impl_list_ == &impl)
- impl_list_ = impl.next_;
- if (impl.prev_)
- impl.prev_->next_ = impl.next_;
- if (impl.next_)
- impl.next_->prev_= impl.prev_;
- impl.next_ = 0;
- impl.prev_ = 0;
- }
+ BOOST_ASIO_DECL void destroy(implementation_type& impl);
 
   // Assign a native handle to a handle implementation.
- boost::system::error_code assign(implementation_type& impl,
- const native_type& native_handle, boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- if (iocp_service_.register_handle(native_handle, ec))
- return ec;
-
- impl.handle_ = native_handle;
- ec = boost::system::error_code();
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code assign(implementation_type& impl,
+ const native_type& native_handle, boost::system::error_code& ec);
 
   // Determine whether the handle is open.
   bool is_open(const implementation_type& impl) const
@@ -154,26 +96,8 @@
   }
 
   // Destroy a handle implementation.
- boost::system::error_code close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- if (!::CloseHandle(impl.handle_))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- impl.handle_ = INVALID_HANDLE_VALUE;
- impl.safe_cancellation_thread_id_ = 0;
- }
-
- ec = boost::system::error_code();
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code close(implementation_type& impl,
+ boost::system::error_code& ec);
 
   // Get the native handle representation.
   native_type native(const implementation_type& impl) const
@@ -182,106 +106,8 @@
   }
 
   // Cancel all operations associated with the handle.
- boost::system::error_code cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- }
- else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
- ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
- {
- // The version of Windows supports cancellation from any thread.
- typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
- cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
- if (!cancel_io_ex(impl.handle_, 0))
- {
- DWORD last_error = ::GetLastError();
- if (last_error == ERROR_NOT_FOUND)
- {
- // ERROR_NOT_FOUND means that there were no operations to be
- // cancelled. We swallow this error to match the behaviour on other
- // platforms.
- ec = boost::system::error_code();
- }
- else
- {
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- }
- else
- {
- ec = boost::system::error_code();
- }
- }
- else if (impl.safe_cancellation_thread_id_ == 0)
- {
- // No operations have been started, so there's nothing to cancel.
- ec = boost::system::error_code();
- }
- else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId())
- {
- // Asynchronous operations have been started from the current thread only,
- // so it is safe to try to cancel them using CancelIo.
- if (!::CancelIo(impl.handle_))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- else
- {
- ec = boost::system::error_code();
- }
- }
- else
- {
- // Asynchronous operations have been started from more than one thread,
- // so cancellation is not safe.
- ec = boost::asio::error::operation_not_supported;
- }
-
- return ec;
- }
-
- class overlapped_wrapper
- : public OVERLAPPED
- {
- public:
- explicit overlapped_wrapper(boost::system::error_code& ec)
- {
- Internal = 0;
- InternalHigh = 0;
- Offset = 0;
- OffsetHigh = 0;
-
- // Create a non-signalled manual-reset event, for GetOverlappedResult.
- hEvent = ::CreateEvent(0, TRUE, FALSE, 0);
- if (hEvent)
- {
- // As documented in GetQueuedCompletionStatus, setting the low order
- // bit of this event prevents our synchronous writes from being treated
- // as completion port events.
- *reinterpret_cast<DWORD_PTR*>(&hEvent) |= 1;
- }
- else
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- }
-
- ~overlapped_wrapper()
- {
- if (hEvent)
- {
- ::CloseHandle(hEvent);
- }
- }
- };
+ BOOST_ASIO_DECL boost::system::error_code cancel(implementation_type& impl,
+ boost::system::error_code& ec);
 
   // Write the given data. Returns the number of bytes written.
   template <typename ConstBufferSequence>
@@ -297,109 +123,13 @@
   size_t write_some_at(implementation_type& impl, boost::uint64_t offset,
       const ConstBufferSequence& buffers, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- overlapped_wrapper overlapped(ec);
- if (ec)
- {
- return 0;
- }
-
- // Write the data.
- overlapped.Offset = offset & 0xFFFFFFFF;
- overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
- BOOL ok = ::WriteFile(impl.handle_,
- boost::asio::buffer_cast<LPCVOID>(buffer),
- static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
- if (!ok)
- {
- DWORD last_error = ::GetLastError();
- if (last_error != ERROR_IO_PENDING)
- {
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
- }
-
- // Wait for the operation to complete.
- DWORD bytes_transferred = 0;
- ok = ::GetOverlappedResult(impl.handle_,
- &overlapped, &bytes_transferred, TRUE);
- if (!ok)
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
+ return do_write(impl, offset, buffer, ec);
   }
 
- template <typename ConstBufferSequence, typename Handler>
- class write_op : public operation
- {
- public:
- write_op(const ConstBufferSequence& buffers, Handler handler)
- : operation(&write_op::do_complete),
- buffers_(buffers),
- 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 operation 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)
- {
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- // 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. 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:
- ConstBufferSequence buffers_;
- Handler handler_;
- };
-
   // Start an asynchronous write. The data being written must be valid for the
   // lifetime of the asynchronous operation.
   template <typename ConstBufferSequence, typename Handler>
@@ -416,15 +146,16 @@
       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, buffers, handler);
+ typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(buffers, handler);
 
     start_write_op(impl, offset,
         buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence>::first(buffers), ptr.get());
- ptr.release();
+ ConstBufferSequence>::first(buffers), p.p);
+ p.v = p.p = 0;
   }
 
   // Read some data. Returns the number of bytes received.
@@ -440,129 +171,13 @@
   size_t read_some_at(implementation_type& impl, boost::uint64_t offset,
       const MutableBufferSequence& buffers, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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)
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- overlapped_wrapper overlapped(ec);
- if (ec)
- {
- return 0;
- }
-
- // Read some data.
- overlapped.Offset = offset & 0xFFFFFFFF;
- overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF;
- BOOL ok = ::ReadFile(impl.handle_,
- boost::asio::buffer_cast<LPVOID>(buffer),
- static_cast<DWORD>(boost::asio::buffer_size(buffer)), 0, &overlapped);
- if (!ok)
- {
- DWORD last_error = ::GetLastError();
- if (last_error != ERROR_IO_PENDING && last_error != ERROR_MORE_DATA)
- {
- if (last_error == ERROR_HANDLE_EOF)
- {
- ec = boost::asio::error::eof;
- }
- else
- {
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- return 0;
- }
- }
-
- // Wait for the operation to complete.
- DWORD bytes_transferred = 0;
- ok = ::GetOverlappedResult(impl.handle_,
- &overlapped, &bytes_transferred, TRUE);
- if (!ok)
- {
- DWORD last_error = ::GetLastError();
- if (last_error == ERROR_HANDLE_EOF)
- {
- ec = boost::asio::error::eof;
- }
- else
- {
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
+ return do_read(impl, offset, buffer, ec);
   }
 
- template <typename MutableBufferSequence, typename Handler>
- class read_op : public operation
- {
- public:
- read_op(const MutableBufferSequence& buffers, Handler handler)
- : operation(&read_op::do_complete),
- buffers_(buffers),
- 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 operation 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)
- {
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- // 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.
- if (ec.value() == 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. 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:
- MutableBufferSequence buffers_;
- Handler handler_;
- };
-
   // Start an asynchronous read. The buffer for the data being received must be
   // valid for the lifetime of the asynchronous operation.
   template <typename MutableBufferSequence, typename Handler>
@@ -580,15 +195,16 @@
       const MutableBufferSequence& buffers, Handler handler)
   {
     // 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, buffers, handler);
+ typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(buffers, handler);
 
     start_read_op(impl, offset,
         buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence>::first(buffers), ptr.get());
- ptr.release();
+ MutableBufferSequence>::first(buffers), p.p);
+ p.v = p.p = 0;
   }
 
 private:
@@ -614,113 +230,42 @@
   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(impl);
- iocp_service_.work_started();
+ // Helper class for waiting for synchronous operations to complete.
+ class overlapped_wrapper;
 
- 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 perform a synchronous write operation.
+ BOOST_ASIO_DECL size_t do_write(implementation_type& impl,
+ boost::uint64_t offset, const boost::asio::const_buffer& buffer,
+ boost::system::error_code& ec);
 
- // 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(impl);
- iocp_service_.work_started();
+ // Helper function to start a write operation.
+ BOOST_ASIO_DECL void start_write_op(implementation_type& impl,
+ boost::uint64_t offset, const boost::asio::const_buffer& buffer,
+ operation* op);
+
+ // Helper function to perform a synchronous write operation.
+ BOOST_ASIO_DECL size_t do_read(implementation_type& impl,
+ boost::uint64_t offset, const boost::asio::mutable_buffer& buffer,
+ boost::system::error_code& ec);
 
- 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);
- }
- }
- }
+ // Helper function to start a read operation.
+ BOOST_ASIO_DECL void start_read_op(implementation_type& impl,
+ boost::uint64_t offset, const boost::asio::mutable_buffer& buffer,
+ operation* op);
 
   // Update the ID of the thread from which cancellation is safe.
- void update_cancellation_thread_id(implementation_type& impl)
- {
-#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);
-#else // defined(BOOST_ASIO_ENABLE_CANCELIO)
- (void)impl;
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
- }
+ BOOST_ASIO_DECL void update_cancellation_thread_id(implementation_type& impl);
 
   // Helper function to close a handle when the associated object is being
   // destroyed.
- void close_for_destruction(implementation_type& impl)
- {
- if (is_open(impl))
- {
- ::CloseHandle(impl.handle_);
- impl.handle_ = INVALID_HANDLE_VALUE;
- impl.safe_cancellation_thread_id_ = 0;
- }
- }
+ BOOST_ASIO_DECL void close_for_destruction(implementation_type& impl);
 
   // The IOCP service used for running asynchronous operations and dispatching
   // handlers.
   win_iocp_io_service& iocp_service_;
 
   // Mutex to protect access to the linked list of implementations.
- boost::asio::detail::mutex mutex_;
+ mutex mutex_;
 
   // The head of a linked list of all implementations.
   implementation_type* impl_list_;
@@ -730,8 +275,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_iocp_handle_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_SERVICE_HPP

Added: trunk/boost/asio/detail/win_iocp_handle_write_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_handle_write_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,99 @@
+//
+// detail/win_iocp_handle_write_op.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_HANDLE_WRITE_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/error.hpp>
+#include <boost/utility/addressof.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/operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence, typename Handler>
+class win_iocp_handle_write_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_handle_write_op);
+
+ win_iocp_handle_write_op(const ConstBufferSequence& buffers, Handler handler)
+ : operation(&win_iocp_handle_write_op::do_complete),
+ buffers_(buffers),
+ 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 operation object.
+ win_iocp_handle_write_op* o(static_cast<win_iocp_handle_write_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ if (owner)
+ {
+ // 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. 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ ConstBufferSequence buffers_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_HANDLE_WRITE_OP_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_io_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_io_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,33 +15,24 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/limits.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/scoped_ptr.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/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_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_io_service_fwd.hpp>
 #include <boost/asio/detail/win_iocp_operation.hpp>
+#include <boost/asio/detail/thread.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -53,69 +44,13 @@
   : public boost::asio::detail::service_base<win_iocp_io_service>
 {
 public:
- 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),
- stopped_(0),
- shutdown_(0),
- timer_thread_(0),
- timer_interrupt_issued_(false)
- {
- }
+ BOOST_ASIO_DECL win_iocp_io_service(boost::asio::io_service& io_service);
 
- void init(size_t concurrency_hint)
- {
- iocp_.handle = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0,
- static_cast<DWORD>((std::min<size_t>)(concurrency_hint, DWORD(~0))));
- if (!iocp_.handle)
- {
- DWORD last_error = ::GetLastError();
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "iocp");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL void init(size_t concurrency_hint);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- ::InterlockedExchange(&shutdown_, 1);
-
- while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0)
- {
- 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();
- }
- }
- }
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
   // Initialise the task. Nothing to do here.
   void init_task()
@@ -123,106 +58,23 @@
   }
 
   // Register a handle with the IO completion port.
- boost::system::error_code register_handle(
- HANDLE handle, boost::system::error_code& ec)
- {
- if (::CreateIoCompletionPort(handle, iocp_.handle, 0, 0) == 0)
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- else
- {
- ec = boost::system::error_code();
- }
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code register_handle(
+ HANDLE handle, boost::system::error_code& ec);
 
   // Run the event loop until stopped or no more work.
- size_t run(boost::system::error_code& ec)
- {
- if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
- {
- stop();
- ec = boost::system::error_code();
- return 0;
- }
-
- call_stack<win_iocp_io_service>::context ctx(this);
-
- size_t n = 0;
- while (do_one(true, ec))
- if (n != (std::numeric_limits<size_t>::max)())
- ++n;
- return n;
- }
+ BOOST_ASIO_DECL size_t run(boost::system::error_code& ec);
 
   // Run until stopped or one operation is performed.
- size_t run_one(boost::system::error_code& ec)
- {
- if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
- {
- stop();
- ec = boost::system::error_code();
- return 0;
- }
-
- call_stack<win_iocp_io_service>::context ctx(this);
-
- return do_one(true, ec);
- }
+ BOOST_ASIO_DECL size_t run_one(boost::system::error_code& ec);
 
   // Poll for operations without blocking.
- size_t poll(boost::system::error_code& ec)
- {
- if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
- {
- stop();
- ec = boost::system::error_code();
- return 0;
- }
-
- call_stack<win_iocp_io_service>::context ctx(this);
-
- size_t n = 0;
- while (do_one(false, ec))
- if (n != (std::numeric_limits<size_t>::max)())
- ++n;
- return n;
- }
+ BOOST_ASIO_DECL size_t poll(boost::system::error_code& ec);
 
   // Poll for one operation without blocking.
- size_t poll_one(boost::system::error_code& ec)
- {
- if (::InterlockedExchangeAdd(&outstanding_work_, 0) == 0)
- {
- stop();
- ec = boost::system::error_code();
- return 0;
- }
-
- call_stack<win_iocp_io_service>::context ctx(this);
-
- return do_one(false, ec);
- }
+ BOOST_ASIO_DECL size_t poll_one(boost::system::error_code& ec);
 
   // Stop the event processing loop.
- void stop()
- {
- if (::InterlockedExchange(&stopped_, 1) == 0)
- {
- if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
- {
- 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);
- }
- }
- }
+ BOOST_ASIO_DECL void stop();
 
   // Reset in preparation for a subsequent run invocation.
   void reset()
@@ -245,34 +97,15 @@
 
   // Request invocation of the given handler.
   template <typename Handler>
- 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);
- }
+ void dispatch(Handler 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.
- 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);
-
- post_immediate_completion(ptr.get());
- ptr.release();
- }
+ void post(Handler handler);
 
   // 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)
+ void post_immediate_completion(win_iocp_operation* op)
   {
     work_started();
     post_deferred_completion(op);
@@ -280,171 +113,48 @@
 
   // 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.
- 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);
- }
- }
+ BOOST_ASIO_DECL void post_deferred_completion(win_iocp_operation* op);
 
   // 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);
- }
- }
- }
+ BOOST_ASIO_DECL void post_deferred_completions(
+ op_queue<win_iocp_operation>& ops);
 
   // 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);
- }
- }
- }
+ BOOST_ASIO_DECL void on_pending(win_iocp_operation* 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,
- 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);
- }
- }
+ BOOST_ASIO_DECL void on_completion(win_iocp_operation* op,
+ DWORD last_error = 0, DWORD bytes_transferred = 0);
 
   // 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);
- }
- }
+ BOOST_ASIO_DECL void on_completion(win_iocp_operation* op,
+ const boost::system::error_code& ec, DWORD bytes_transferred = 0);
 
   // Add a new timer queue to the service.
   template <typename Time_Traits>
- void add_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
- timer_queues_.insert(&timer_queue);
- }
+ void add_timer_queue(timer_queue<Time_Traits>& timer_queue);
 
   // Remove a timer queue from the service.
   template <typename Time_Traits>
- void remove_timer_queue(timer_queue<Time_Traits>& timer_queue)
- {
- boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
- timer_queues_.erase(&timer_queue);
- }
+ void remove_timer_queue(timer_queue<Time_Traits>& timer_queue);
 
   // Schedule a new operation in the given timer queue to expire at the
   // specified absolute time.
   template <typename Time_Traits>
   void schedule_timer(timer_queue<Time_Traits>& timer_queue,
- const typename Time_Traits::time_type& time, timer_op* op, void* token)
- {
- // 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_);
- bool interrupt = timer_queue.enqueue_timer(time, op, token);
- work_started();
- if (interrupt && !timer_interrupt_issued_)
- {
- timer_interrupt_issued_ = true;
- lock.unlock();
- ::PostQueuedCompletionStatus(iocp_.handle,
- 0, steal_timer_dispatching, 0);
- }
- }
+ const typename Time_Traits::time_type& time, timer_op* op, void* token);
 
   // Cancel the timer associated with the given token. Returns the number of
   // handlers that have been posted or dispatched.
   template <typename Time_Traits>
- std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
- {
- // If the service has been shut down we silently ignore the cancellation.
- if (::InterlockedExchangeAdd(&shutdown_, 0) != 0)
- return 0;
-
- boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
- 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;
- lock.unlock();
- ::PostQueuedCompletionStatus(iocp_.handle,
- 0, steal_timer_dispatching, 0);
- }
- return n;
- }
+ std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token);
 
 private:
 #if defined(WINVER) && (WINVER < 0x0500)
@@ -458,181 +168,30 @@
   // 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).
- size_t do_one(bool block, boost::system::error_code& ec)
- {
- long this_thread_id = static_cast<long>(::GetCurrentThreadId());
+ BOOST_ASIO_DECL size_t do_one(bool block, boost::system::error_code& ec);
 
- for (;;)
- {
- // Try to acquire responsibility for dispatching timers.
- bool dispatching_timers = (::InterlockedCompareExchange(
- &timer_thread_, this_thread_id, 0) == 0);
-
- // Calculate timeout for GetQueuedCompletionStatus call.
- DWORD timeout = max_timeout;
- if (dispatching_timers)
- {
- boost::asio::detail::mutex::scoped_lock lock(timer_mutex_);
- timer_interrupt_issued_ = false;
- timeout = get_timeout();
- }
-
- // Get the next operation from the queue.
- DWORD bytes_transferred = 0;
- dword_ptr_t completion_key = 0;
- LPOVERLAPPED overlapped = 0;
- ::SetLastError(0);
- BOOL ok = ::GetQueuedCompletionStatus(iocp_.handle, &bytes_transferred,
- &completion_key, &overlapped, block ? timeout : 0);
- DWORD last_error = ::GetLastError();
-
- // Dispatch any pending timers.
- if (dispatching_timers)
- {
- 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)
- {
- if (block && last_error == WAIT_TIMEOUT)
- {
- // Relinquish responsibility for dispatching timers.
- if (dispatching_timers)
- {
- ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
- }
-
- continue;
- }
-
- // Transfer responsibility for dispatching timers to another thread.
- if (dispatching_timers && ::InterlockedCompareExchange(
- &timer_thread_, 0, this_thread_id) == this_thread_id)
- {
- ::PostQueuedCompletionStatus(iocp_.handle,
- 0, transfer_timer_dispatching, 0);
- }
-
- ec = boost::system::error_code();
- return 0;
- }
- else if (overlapped)
- {
- 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(
- &timer_thread_, 0, this_thread_id) == this_thread_id)
- {
- ::PostQueuedCompletionStatus(iocp_.handle,
- 0, transfer_timer_dispatching, 0);
- }
-
- // 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;
- }
-
- // 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;
- }
- }
- else if (completion_key == transfer_timer_dispatching)
- {
- // Woken up to try to acquire responsibility for dispatching timers.
- ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
- }
- else if (completion_key == steal_timer_dispatching)
- {
- // Woken up to steal responsibility for dispatching timers.
- ::InterlockedExchange(&timer_thread_, 0);
- }
- else
- {
- // Relinquish responsibility for dispatching timers. If the io_service
- // is not being stopped then the thread will get an opportunity to
- // reacquire timer responsibility on the next loop iteration.
- if (dispatching_timers)
- {
- ::InterlockedCompareExchange(&timer_thread_, 0, this_thread_id);
- }
-
- // The stopped_ flag is always checked to ensure that any leftover
- // interrupts from a previous run invocation are ignored.
- if (::InterlockedExchangeAdd(&stopped_, 0) != 0)
- {
- // Wake up next thread that is blocked on GetQueuedCompletionStatus.
- if (!::PostQueuedCompletionStatus(iocp_.handle, 0, 0, 0))
- {
- last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
-
- ec = boost::system::error_code();
- return 0;
- }
- }
- }
- }
+ // Helper function to add a new timer queue.
+ BOOST_ASIO_DECL void do_add_timer_queue(timer_queue_base& queue);
 
- // 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()
- {
- return timer_queues_.wait_duration_msec(max_timeout);
- }
+ // Helper function to remove a timer queue.
+ BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
+
+ // Called to recalculate and update the timeout.
+ BOOST_ASIO_DECL void update_timeout();
 
   // Helper class to call work_finished() on block exit.
- struct work_finished_on_block_exit
- {
- ~work_finished_on_block_exit()
- {
- io_service_->work_finished();
- }
+ struct work_finished_on_block_exit;
 
- win_iocp_io_service* io_service_;
+ // Helper class for managing a HANDLE.
+ struct auto_handle
+ {
+ HANDLE handle;
+ auto_handle() : handle(0) {}
+ ~auto_handle() { if (handle) ::CloseHandle(handle); }
   };
 
   // The IO completion port used for queueing operations.
- struct iocp_holder
- {
- HANDLE handle;
- iocp_holder() : handle(0) {}
- ~iocp_holder() { if (handle) ::CloseHandle(handle); }
- } iocp_;
+ auto_handle iocp_;
 
   // The count of unfinished work.
   long outstanding_work_;
@@ -645,45 +204,62 @@
 
   enum
   {
- // Maximum GetQueuedCompletionStatus timeout, in milliseconds.
- max_timeout = 500,
-
- // Completion key value to indicate that responsibility for dispatching
- // timers is being cooperatively transferred from one thread to another.
- transfer_timer_dispatching = 1,
-
- // Completion key value to indicate that responsibility for dispatching
- // timers should be stolen from another thread.
- steal_timer_dispatching = 2,
+ // Timeout to use with GetQueuedCompletionStatus. Some versions of windows
+ // have a "bug" where a call to GetQueuedCompletionStatus can appear stuck
+ // even though there are events waiting on the queue. Using a timeout helps
+ // to work around the issue.
+ gqcs_timeout = 500,
+
+ // Maximum waitable timer timeout, in milliseconds.
+ max_timeout_msec = 5 * 60 * 1000,
+
+ // Maximum waitable timer timeout, in microseconds.
+ max_timeout_usec = max_timeout_msec * 1000,
+
+ // Completion key value used to wake up a thread to dispatch timers or
+ // completed operations.
+ wake_for_dispatch = 1,
 
     // 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
+ overlapped_contains_result = 2
   };
 
- // The thread that's currently in charge of dispatching timers.
- long timer_thread_;
+ // Function object for processing timeouts in a background thread.
+ struct timer_thread_function;
+ friend struct timer_thread_function;
+
+ // Background thread used for processing timeouts.
+ boost::scoped_ptr<thread> timer_thread_;
+
+ // A waitable timer object used for waiting for timeouts.
+ auto_handle waitable_timer_;
 
- // Mutex for protecting access to the timer queues.
- mutex timer_mutex_;
+ // Non-zero if timers or completed operations need to be dispatched.
+ long dispatch_required_;
 
- // Whether a thread has been interrupted to process a new timeout.
- bool timer_interrupt_issued_;
+ // Mutex for protecting access to the timer queues and completed operations.
+ mutex dispatch_mutex_;
 
   // The timer queues.
   timer_queue_set timer_queues_;
 
   // The operations that are ready to dispatch.
- op_queue<operation> completed_ops_;
+ op_queue<win_iocp_operation> completed_ops_;
 };
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/detail/impl/win_iocp_io_service.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_iocp_io_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_HPP

Modified: trunk/boost/asio/detail/win_iocp_io_service_fwd.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_io_service_fwd.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_io_service_fwd.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_io_service_fwd.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_io_service_fwd.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,22 +15,9 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/detail/socket_types.hpp>
-
-// This service is only supported on Win32 (NT4 and later).
-#if !defined(BOOST_ASIO_DISABLE_IOCP)
-#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
-#if !defined(UNDER_CE)
-
-// Define this to indicate that IOCP is supported on the target platform.
-#define BOOST_ASIO_HAS_IOCP 1
+#if defined(BOOST_ASIO_HAS_IOCP)
 
 namespace boost {
 namespace asio {
@@ -43,11 +30,6 @@
 } // namespace asio
 } // namespace boost
 
-#endif // !defined(UNDER_CE)
-#endif // defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400)
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-#endif // !defined(BOOST_ASIO_DISABLE_IOCP)
-
-#include <boost/asio/detail/pop_options.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
 
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_IO_SERVICE_FWD_HPP

Added: trunk/boost/asio/detail/win_iocp_null_buffers_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_null_buffers_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,114 @@
+//
+// detail/win_iocp_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_WIN_IOCP_NULL_BUFFERS_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/reactor_op.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class win_iocp_null_buffers_op : public reactor_op
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_null_buffers_op);
+
+ win_iocp_null_buffers_op(socket_ops::weak_cancel_token_type cancel_token,
+ Handler handler)
+ : reactor_op(&win_iocp_null_buffers_op::do_perform,
+ &win_iocp_null_buffers_op::do_complete),
+ cancel_token_(cancel_token),
+ 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 operation object.
+ win_iocp_null_buffers_op* o(static_cast<win_iocp_null_buffers_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // The reactor may have stored a result in the operation object.
+ if (o->ec_)
+ ec = o->ec_;
+
+ // 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;
+ }
+
+ // 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ socket_ops::weak_cancel_token_type cancel_token_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_NULL_BUFFERS_OP_HPP

Modified: trunk/boost/asio/detail/win_iocp_operation.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_operation.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_operation.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_operation.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_operation.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,15 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
 #include <boost/asio/detail/op_queue.hpp>
+#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -83,9 +85,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
-#include <boost/system/error_code.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_OPERATION_HPP

Added: trunk/boost/asio/detail/win_iocp_overlapped_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_overlapped_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,86 @@
+//
+// detail/win_iocp_overlapped_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_WIN_IOCP_OVERLAPPED_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/asio/error.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/detail/bind_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/operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Handler>
+class win_iocp_overlapped_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_overlapped_op);
+
+ win_iocp_overlapped_op(Handler handler)
+ : operation(&win_iocp_overlapped_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 operation object.
+ win_iocp_overlapped_op* o(static_cast<win_iocp_overlapped_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ // 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_OP_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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_overlapped_ptr.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,18 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
-#include <boost/asio/detail/fenced_block.hpp>
+#include <boost/utility/addressof.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
+#include <boost/asio/detail/win_iocp_overlapped_op.hpp>
 #include <boost/asio/detail/win_iocp_io_service.hpp>
-#include <boost/asio/detail/win_iocp_operation.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -75,13 +77,15 @@
   template <typename Handler>
   void reset(boost::asio::io_service& io_service, Handler handler)
   {
- 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, handler);
+ typedef win_iocp_overlapped_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(handler);
     io_service.impl_.work_started();
     reset();
- ptr_ = ptr.release();
+ ptr_ = p.p;
+ p.v = p.p = 0;
     iocp_service_ = &io_service.impl_;
   }
 
@@ -123,44 +127,6 @@
   }
 
 private:
- template <typename Handler>
- struct overlapped_op : public win_iocp_operation
- {
- overlapped_op(Handler handler)
- : win_iocp_operation(&overlapped_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 operation object.
- 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_;
- };
-
   win_iocp_operation* ptr_;
   win_iocp_io_service* iocp_service_;
 };
@@ -169,8 +135,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_OVERLAPPED_PTR_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_serial_port_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_serial_port_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
@@ -16,21 +16,17 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <cstring>
-#include <string>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
-
-#if defined(BOOST_ASIO_HAS_IOCP)
+#if defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
 
+#include <string>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/win_iocp_handle_service.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -39,133 +35,56 @@
 class win_iocp_serial_port_service
 {
 public:
- // The native type of a stream handle.
+ // The native type of a serial port.
   typedef win_iocp_handle_service::native_type native_type;
 
- // The implementation type of the stream handle.
+ // The implementation type of the serial port.
   typedef win_iocp_handle_service::implementation_type implementation_type;
 
- win_iocp_serial_port_service(boost::asio::io_service& io_service)
- : handle_service_(io_service)
- {
- }
+ // Constructor.
+ BOOST_ASIO_DECL win_iocp_serial_port_service(
+ boost::asio::io_service& io_service);
 
   // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
- {
- }
+ BOOST_ASIO_DECL void shutdown_service();
 
- // Construct a new handle implementation.
+ // Construct a new serial port implementation.
   void construct(implementation_type& impl)
   {
     handle_service_.construct(impl);
   }
 
- // Destroy a handle implementation.
+ // Destroy a serial port implementation.
   void destroy(implementation_type& impl)
   {
     handle_service_.destroy(impl);
   }
 
   // Open the serial port using the specified device name.
- boost::system::error_code open(implementation_type& impl,
- const std::string& device, boost::system::error_code& ec)
- {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- // For convenience, add a leading \\.\ sequence if not already present.
- std::string name = (device[0] == '\\') ? device : "\\\\.\\" + device;
-
- // Open a handle to the serial port.
- ::HANDLE handle = ::CreateFileA(name.c_str(),
- GENERIC_READ | GENERIC_WRITE, 0, 0,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
- if (handle == INVALID_HANDLE_VALUE)
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- // Determine the initial serial port parameters.
- using namespace std; // For memcpy.
- ::DCB dcb;
- memset(&dcb, 0, sizeof(DCB));
- dcb.DCBlength = sizeof(DCB);
- if (!::GetCommState(handle, &dcb))
- {
- DWORD last_error = ::GetLastError();
- ::CloseHandle(handle);
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- // Set some default serial port parameters. This implementation does not
- // support changing these, so they might as well be in a known state.
- dcb.fBinary = TRUE; // Win32 only supports binary mode.
- dcb.fDsrSensitivity = FALSE;
- dcb.fNull = FALSE; // Do not ignore NULL characters.
- dcb.fAbortOnError = FALSE; // Ignore serial framing errors.
- if (!::SetCommState(handle, &dcb))
- {
- DWORD last_error = ::GetLastError();
- ::CloseHandle(handle);
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- // Set up timeouts so that the serial port will behave similarly to a
- // network socket. Reads wait for at least one byte, then return with
- // whatever they have. Writes return once everything is out the door.
- ::COMMTIMEOUTS timeouts;
- timeouts.ReadIntervalTimeout = 1;
- timeouts.ReadTotalTimeoutMultiplier = 0;
- timeouts.ReadTotalTimeoutConstant = 0;
- timeouts.WriteTotalTimeoutMultiplier = 0;
- timeouts.WriteTotalTimeoutConstant = 0;
- if (!::SetCommTimeouts(handle, &timeouts))
- {
- DWORD last_error = ::GetLastError();
- ::CloseHandle(handle);
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- // We're done. Take ownership of the serial port handle.
- if (handle_service_.assign(impl, handle, ec))
- ::CloseHandle(handle);
- return ec;
- }
+ BOOST_ASIO_DECL boost::system::error_code open(implementation_type& impl,
+ const std::string& device, boost::system::error_code& ec);
 
- // Assign a native handle to a handle implementation.
+ // Assign a native handle to a serial port implementation.
   boost::system::error_code assign(implementation_type& impl,
       const native_type& native_handle, boost::system::error_code& ec)
   {
     return handle_service_.assign(impl, native_handle, ec);
   }
 
- // Determine whether the handle is open.
+ // Determine whether the serial port is open.
   bool is_open(const implementation_type& impl) const
   {
     return handle_service_.is_open(impl);
   }
 
- // Destroy a handle implementation.
+ // Destroy a serial port implementation.
   boost::system::error_code close(implementation_type& impl,
       boost::system::error_code& ec)
   {
     return handle_service_.close(impl, ec);
   }
 
- // Get the native handle representation.
+ // Get the native serial port representation.
   native_type native(implementation_type& impl)
   {
     return handle_service_.native(impl);
@@ -183,32 +102,9 @@
   boost::system::error_code set_option(implementation_type& impl,
       const SettableSerialPortOption& option, boost::system::error_code& ec)
   {
- using namespace std; // For memcpy.
-
- ::DCB dcb;
- memset(&dcb, 0, sizeof(DCB));
- dcb.DCBlength = sizeof(DCB);
- if (!::GetCommState(handle_service_.native(impl), &dcb))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- if (option.store(dcb, ec))
- return ec;
-
- if (!::SetCommState(handle_service_.native(impl), &dcb))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- ec = boost::system::error_code();
- return ec;
+ return do_set_option(impl,
+ &win_iocp_serial_port_service::store_option<SettableSerialPortOption>,
+ &option, ec);
   }
 
   // Get an option from the serial port.
@@ -216,20 +112,9 @@
   boost::system::error_code get_option(const implementation_type& impl,
       GettableSerialPortOption& option, boost::system::error_code& ec) const
   {
- using namespace std; // For memcpy.
-
- ::DCB dcb;
- memset(&dcb, 0, sizeof(DCB));
- dcb.DCBlength = sizeof(DCB);
- if (!::GetCommState(handle_service_.native(impl), &dcb))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return ec;
- }
-
- return option.load(dcb, ec);
+ return do_get_option(impl,
+ &win_iocp_serial_port_service::load_option<GettableSerialPortOption>,
+ &option, ec);
   }
 
   // Send a break sequence to the serial port.
@@ -275,6 +160,41 @@
   }
 
 private:
+ // Function pointer type for storing a serial port option.
+ typedef boost::system::error_code (*store_function_type)(
+ const void*, ::DCB&, boost::system::error_code&);
+
+ // Helper function template to store a serial port option.
+ template <typename SettableSerialPortOption>
+ static boost::system::error_code store_option(const void* option,
+ ::DCB& storage, boost::system::error_code& ec)
+ {
+ return static_cast<const SettableSerialPortOption*>(option)->store(
+ storage, ec);
+ }
+
+ // Helper function to set a serial port option.
+ BOOST_ASIO_DECL boost::system::error_code do_set_option(
+ implementation_type& impl, store_function_type store,
+ const void* option, boost::system::error_code& ec);
+
+ // Function pointer type for loading a serial port option.
+ typedef boost::system::error_code (*load_function_type)(
+ void*, const ::DCB&, boost::system::error_code&);
+
+ // Helper function template to load a serial port option.
+ template <typename GettableSerialPortOption>
+ static boost::system::error_code load_option(void* option,
+ const ::DCB& storage, boost::system::error_code& ec)
+ {
+ return static_cast<GettableSerialPortOption*>(option)->load(storage, ec);
+ }
+
+ // Helper function to get a serial port option.
+ BOOST_ASIO_DECL boost::system::error_code do_get_option(
+ const implementation_type& impl, load_function_type load,
+ void* option, boost::system::error_code& ec) const;
+
   // The implementation used for initiating asynchronous operations.
   win_iocp_handle_service handle_service_;
 };
@@ -283,8 +203,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_iocp_serial_port_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_IOCP) && defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_SERIAL_PORT_SERVICE_HPP

Added: trunk/boost/asio/detail/win_iocp_socket_accept_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_socket_accept_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,160 @@
+//
+// detail/win_iocp_socket_accept_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_WIN_IOCP_SOCKET_ACCEPT_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/win_iocp_socket_service_base.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Socket, typename Protocol, typename Handler>
+class win_iocp_socket_accept_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_accept_op);
+
+ win_iocp_socket_accept_op(win_iocp_socket_service_base& socket_service,
+ socket_type socket, Socket& peer, const Protocol& protocol,
+ typename Protocol::endpoint* peer_endpoint,
+ bool enable_connection_aborted, Handler handler)
+ : operation(&win_iocp_socket_accept_op::do_complete),
+ socket_service_(socket_service),
+ socket_(socket),
+ peer_(peer),
+ protocol_(protocol),
+ peer_endpoint_(peer_endpoint),
+ enable_connection_aborted_(enable_connection_aborted),
+ handler_(handler)
+ {
+ }
+
+ socket_holder& new_socket()
+ {
+ return new_socket_;
+ }
+
+ void* output_buffer()
+ {
+ return output_buffer_;
+ }
+
+ DWORD address_length()
+ {
+ return sizeof(sockaddr_storage_type) + 16;
+ }
+
+ 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.
+ win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+ if (owner)
+ {
+ typename Protocol::endpoint peer_endpoint;
+ std::size_t addr_len = peer_endpoint.capacity();
+ socket_ops::complete_iocp_accept(o->socket_,
+ o->output_buffer(), o->address_length(),
+ peer_endpoint.data(), &addr_len,
+ o->new_socket_.get(), ec);
+
+ // 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_)
+ {
+ o->reset();
+ o->socket_service_.restart_accept_op(o->socket_,
+ o->new_socket_, o->protocol_.family(),
+ o->protocol_.type(), o->protocol_.protocol(),
+ o->output_buffer(), o->address_length(), o);
+ p.v = p.p = 0;
+ return;
+ }
+
+ // If the socket was successfully accepted, transfer ownership of the
+ // socket to the peer object.
+ if (!ec)
+ {
+ o->peer_.assign(o->protocol_,
+ typename Socket::native_type(
+ o->new_socket_.get(), peer_endpoint), ec);
+ if (!ec)
+ o->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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ win_iocp_socket_service_base& socket_service_;
+ socket_type socket_;
+ socket_holder new_socket_;
+ Socket& peer_;
+ Protocol protocol_;
+ typename Protocol::endpoint* peer_endpoint_;
+ unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
+ bool enable_connection_aborted_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_ACCEPT_OP_HPP

Added: trunk/boost/asio/detail/win_iocp_socket_recv_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_socket_recv_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,110 @@
+//
+// detail/win_iocp_socket_recv_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_WIN_IOCP_SOCKET_RECV_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Handler>
+class win_iocp_socket_recv_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recv_op);
+
+ win_iocp_socket_recv_op(socket_ops::state_type state,
+ socket_ops::weak_cancel_token_type cancel_token,
+ const MutableBufferSequence& buffers, Handler handler)
+ : operation(&win_iocp_socket_recv_op::do_complete),
+ state_(state),
+ cancel_token_(cancel_token),
+ buffers_(buffers),
+ 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 operation object.
+ win_iocp_socket_recv_op* o(static_cast<win_iocp_socket_recv_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ // Check whether buffers are still valid.
+ if (owner)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::validate(o->buffers_);
+ }
+#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+
+ socket_ops::complete_iocp_recv(o->state_, o->cancel_token_,
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::all_empty(o->buffers_),
+ ec, bytes_transferred);
+
+ // 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ socket_ops::state_type state_;
+ socket_ops::weak_cancel_token_type cancel_token_;
+ MutableBufferSequence buffers_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECV_OP_HPP

Added: trunk/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,118 @@
+//
+// detail/win_iocp_socket_recvfrom_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_WIN_IOCP_SOCKET_RECVFROM_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename MutableBufferSequence, typename Endpoint, typename Handler>
+class win_iocp_socket_recvfrom_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_recvfrom_op);
+
+ win_iocp_socket_recvfrom_op(Endpoint& endpoint,
+ socket_ops::weak_cancel_token_type cancel_token,
+ const MutableBufferSequence& buffers, Handler handler)
+ : operation(&win_iocp_socket_recvfrom_op::do_complete),
+ endpoint_(endpoint),
+ endpoint_size_(static_cast<int>(endpoint.capacity())),
+ cancel_token_(cancel_token),
+ buffers_(buffers),
+ handler_(handler)
+ {
+ }
+
+ int& endpoint_size()
+ {
+ return endpoint_size_;
+ }
+
+ 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.
+ win_iocp_socket_recvfrom_op* o(
+ static_cast<win_iocp_socket_recvfrom_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ // Check whether buffers are still valid.
+ if (owner)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::validate(o->buffers_);
+ }
+#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+
+ socket_ops::complete_iocp_recvfrom(o->cancel_token_, ec);
+
+ // 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. 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ Endpoint& endpoint_;
+ int endpoint_size_;
+ socket_ops::weak_cancel_token_type cancel_token_;
+ MutableBufferSequence buffers_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_RECVFROM_OP_HPP

Added: trunk/boost/asio/detail/win_iocp_socket_send_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_socket_send_op.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,104 @@
+//
+// detail/win_iocp_socket_send_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_WIN_IOCP_SOCKET_SEND_OP_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/utility/addressof.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/operation.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename ConstBufferSequence, typename Handler>
+class win_iocp_socket_send_op : public operation
+{
+public:
+ BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_send_op);
+
+ win_iocp_socket_send_op(socket_ops::weak_cancel_token_type cancel_token,
+ const ConstBufferSequence& buffers, Handler handler)
+ : operation(&win_iocp_socket_send_op::do_complete),
+ cancel_token_(cancel_token),
+ buffers_(buffers),
+ 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 operation object.
+ win_iocp_socket_send_op* o(static_cast<win_iocp_socket_send_op*>(base));
+ ptr p = { boost::addressof(o->handler_), o, o };
+
+#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+ // Check whether buffers are still valid.
+ if (owner)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence>::validate(o->buffers_);
+ }
+#endif // defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
+
+ socket_ops::complete_iocp_send(o->cancel_token_, ec);
+
+ // 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);
+ p.h = boost::addressof(handler.handler_);
+ p.reset();
+
+ // Make the upcall if required.
+ if (owner)
+ {
+ boost::asio::detail::fenced_block b;
+ boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
+ }
+ }
+
+private:
+ socket_ops::weak_cancel_token_type cancel_token_;
+ ConstBufferSequence buffers_;
+ Handler handler_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SEND_OP_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_iocp_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_iocp_socket_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,19 +15,12 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstring>
-#include <boost/shared_ptr.hpp>
-#include <boost/type_traits/is_same.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/utility/addressof.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/socket_base.hpp>
@@ -37,21 +30,28 @@
 #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/null_buffers_op.hpp>
 #include <boost/asio/detail/operation.hpp>
+#include <boost/asio/detail/reactive_socket_connect_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>
 #include <boost/asio/detail/win_iocp_io_service.hpp>
+#include <boost/asio/detail/win_iocp_null_buffers_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_accept_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_recvfrom_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_send_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
 template <typename Protocol>
-class win_iocp_socket_service
+class win_iocp_socket_service : public win_iocp_socket_service_base
 {
 public:
   // The protocol type.
@@ -60,10 +60,6 @@
   // The endpoint type.
   typedef typename Protocol::endpoint endpoint_type;
 
- struct noop_deleter { void operator()(void*) {} };
- typedef boost::shared_ptr<void> shared_cancel_token_type;
- typedef boost::weak_ptr<void> weak_cancel_token_type;
-
   // The native type of a socket.
   class native_type
   {
@@ -93,11 +89,6 @@
       return socket_;
     }
 
- HANDLE as_handle() const
- {
- return reinterpret_cast<HANDLE>(socket_);
- }
-
     bool have_remote_endpoint() const
     {
       return have_remote_endpoint_;
@@ -115,148 +106,44 @@
   };
 
   // The implementation type of the socket.
- class implementation_type
+ struct implementation_type :
+ win_iocp_socket_service_base::base_implementation_type
   {
- public:
     // Default constructor.
     implementation_type()
- : socket_(invalid_socket),
- flags_(0),
- cancel_token_(),
- protocol_(endpoint_type().protocol()),
- next_(0),
- prev_(0)
+ : protocol_(endpoint_type().protocol()),
+ have_remote_endpoint_(false),
+ remote_endpoint_()
     {
     }
 
- private:
- // Only this service will have access to the internal values.
- friend class win_iocp_socket_service;
-
- // The native socket representation.
- native_type socket_;
-
- enum
- {
- enable_connection_aborted = 1, // User wants connection_aborted errors.
- close_might_block = 2, // User set linger option for blocking close.
- user_set_non_blocking = 4 // The user wants a non-blocking socket.
- };
-
- // Flags indicating the current state of the socket.
- unsigned char flags_;
-
- // We use a shared pointer as a cancellation token here to work around the
- // broken Windows support for cancellation. MSDN says that when you call
- // closesocket any outstanding WSARecv or WSASend operations will complete
- // with the error ERROR_OPERATION_ABORTED. In practice they complete with
- // ERROR_NETNAME_DELETED, which means you can't tell the difference between
- // a local cancellation and the socket being hard-closed by the peer.
- shared_cancel_token_type cancel_token_;
-
     // The protocol associated with the socket.
     protocol_type protocol_;
 
- // Per-descriptor data used by the reactor.
- reactor::per_descriptor_data reactor_data_;
+ // Whether we have a cached remote endpoint.
+ bool have_remote_endpoint_;
 
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
- // The ID of the thread from which it is safe to cancel asynchronous
- // operations. 0 means no asynchronous operations have been started yet.
- // ~0 means asynchronous operations have been started from more than one
- // thread, and cancellation is not supported for the socket.
- DWORD safe_cancellation_thread_id_;
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
- // Pointers to adjacent socket implementations in linked list.
- implementation_type* next_;
- implementation_type* prev_;
+ // A cached remote endpoint.
+ endpoint_type remote_endpoint_;
   };
 
   // Constructor.
   win_iocp_socket_service(boost::asio::io_service& io_service)
- : io_service_(io_service),
- iocp_service_(use_service<win_iocp_io_service>(io_service)),
- reactor_(0),
- mutex_(),
- impl_list_(0)
- {
- }
-
- // Destroy all user-defined handler objects owned by the service.
- void shutdown_service()
+ : win_iocp_socket_service_base(io_service)
   {
- // Close all implementations, causing all operations to complete.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- implementation_type* impl = impl_list_;
- while (impl)
- {
- boost::system::error_code ignored_ec;
- close_for_destruction(*impl);
- impl = impl->next_;
- }
- }
-
- // Construct a new socket implementation.
- void construct(implementation_type& impl)
- {
- impl.socket_ = invalid_socket;
- impl.flags_ = 0;
- impl.cancel_token_.reset();
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
- impl.safe_cancellation_thread_id_ = 0;
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
- // Insert implementation into linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- impl.next_ = impl_list_;
- impl.prev_ = 0;
- if (impl_list_)
- impl_list_->prev_ = &impl;
- impl_list_ = &impl;
- }
-
- // Destroy a socket implementation.
- void destroy(implementation_type& impl)
- {
- close_for_destruction(impl);
-
- // Remove implementation from linked list of all implementations.
- boost::asio::detail::mutex::scoped_lock lock(mutex_);
- if (impl_list_ == &impl)
- impl_list_ = impl.next_;
- if (impl.prev_)
- impl.prev_->next_ = impl.next_;
- if (impl.next_)
- impl.next_->prev_= impl.prev_;
- impl.next_ = 0;
- impl.prev_ = 0;
   }
 
   // Open a new socket implementation.
   boost::system::error_code open(implementation_type& impl,
       const protocol_type& protocol, boost::system::error_code& ec)
   {
- if (is_open(impl))
+ if (!do_open(impl, protocol.family(),
+ protocol.type(), protocol.protocol(), ec))
     {
- ec = boost::asio::error::already_open;
- return ec;
+ impl.protocol_ = protocol;
+ impl.have_remote_endpoint_ = false;
+ impl.remote_endpoint_ = endpoint_type();
     }
-
- socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(),
- protocol.protocol(), ec));
- if (sock.get() == invalid_socket)
- return ec;
-
- HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock.get());
- if (iocp_service_.register_handle(sock_as_handle, ec))
- return ec;
-
- impl.socket_ = sock.release();
- impl.flags_ = 0;
- impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter());
- impl.protocol_ = protocol;
- ec = boost::system::error_code();
     return ec;
   }
 
@@ -265,247 +152,40 @@
       const protocol_type& protocol, const native_type& native_socket,
       boost::system::error_code& ec)
   {
- if (is_open(impl))
- {
- ec = boost::asio::error::already_open;
- return ec;
- }
-
- if (iocp_service_.register_handle(native_socket.as_handle(), ec))
- return ec;
-
- impl.socket_ = native_socket;
- impl.flags_ = 0;
- impl.cancel_token_.reset(static_cast<void*>(0), noop_deleter());
- impl.protocol_ = protocol;
- ec = boost::system::error_code();
- return ec;
- }
-
- // Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return impl.socket_ != invalid_socket;
- }
-
- // Destroy a socket implementation.
- boost::system::error_code close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (is_open(impl))
+ if (!do_assign(impl, protocol.type(), native_socket, ec))
     {
- // 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* r = static_cast<reactor*>(
- interlocked_compare_exchange_pointer(
- reinterpret_cast<void**>(&reactor_), 0, 0));
- if (r)
- r->close_descriptor(impl.socket_, impl.reactor_data_);
-
- if (socket_ops::close(impl.socket_, ec) == socket_error_retval)
- return ec;
-
- impl.socket_ = invalid_socket;
- impl.flags_ = 0;
- impl.cancel_token_.reset();
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
- impl.safe_cancellation_thread_id_ = 0;
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+ impl.protocol_ = protocol;
+ impl.have_remote_endpoint_ = native_socket.have_remote_endpoint();
+ impl.remote_endpoint_ = native_socket.remote_endpoint();
     }
-
- ec = boost::system::error_code();
     return ec;
   }
 
   // Get the native socket representation.
   native_type native(implementation_type& impl)
   {
- return impl.socket_;
- }
-
- // Cancel all operations associated with the socket.
- boost::system::error_code cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
- else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
- ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
- {
- // The version of Windows supports cancellation from any thread.
- typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
- cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
- socket_type sock = impl.socket_;
- HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
- if (!cancel_io_ex(sock_as_handle, 0))
- {
- DWORD last_error = ::GetLastError();
- if (last_error == ERROR_NOT_FOUND)
- {
- // ERROR_NOT_FOUND means that there were no operations to be
- // cancelled. We swallow this error to match the behaviour on other
- // platforms.
- ec = boost::system::error_code();
- }
- else
- {
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- }
- else
- {
- ec = boost::system::error_code();
- }
- }
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
- else if (impl.safe_cancellation_thread_id_ == 0)
- {
- // No operations have been started, so there's nothing to cancel.
- ec = boost::system::error_code();
- }
- else if (impl.safe_cancellation_thread_id_ == ::GetCurrentThreadId())
- {
- // Asynchronous operations have been started from the current thread only,
- // so it is safe to try to cancel them using CancelIo.
- socket_type sock = impl.socket_;
- HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
- if (!::CancelIo(sock_as_handle))
- {
- DWORD last_error = ::GetLastError();
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- }
- else
- {
- ec = boost::system::error_code();
- }
- }
- else
- {
- // Asynchronous operations have been started from more than one thread,
- // so cancellation is not safe.
- ec = boost::asio::error::operation_not_supported;
- }
-#else // defined(BOOST_ASIO_ENABLE_CANCELIO)
- else
- {
- // Cancellation is not supported as CancelIo may not be used.
- ec = boost::asio::error::operation_not_supported;
- }
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
-
- return ec;
- }
-
- // Determine whether the socket is at the out-of-band data mark.
- bool at_mark(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return false;
- }
-
- boost::asio::detail::ioctl_arg_type value = 0;
- socket_ops::ioctl(impl.socket_, SIOCATMARK, &value, ec);
- return ec ? false : value != 0;
- }
-
- // Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- boost::asio::detail::ioctl_arg_type value = 0;
- socket_ops::ioctl(impl.socket_, FIONREAD, &value, ec);
- return ec ? static_cast<std::size_t>(0) : static_cast<std::size_t>(value);
+ if (impl.have_remote_endpoint_)
+ return native_type(impl.socket_, impl.remote_endpoint_);
+ return native_type(impl.socket_);
   }
 
   // Bind the socket to the specified local endpoint.
   boost::system::error_code bind(implementation_type& impl,
       const endpoint_type& endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
     socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec);
     return ec;
   }
 
- // Place the socket into the state where it will listen for new connections.
- boost::system::error_code listen(implementation_type& impl, int backlog,
- boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::listen(impl.socket_, backlog, ec);
- return ec;
- }
-
   // Set a socket option.
   template <typename Option>
   boost::system::error_code set_option(implementation_type& impl,
       const Option& option, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- if (option.level(impl.protocol_) == custom_socket_option_level
- && option.name(impl.protocol_) == enable_connection_aborted_option)
- {
- if (option.size(impl.protocol_) != sizeof(int))
- {
- ec = boost::asio::error::invalid_argument;
- }
- else
- {
- if (*reinterpret_cast<const int*>(option.data(impl.protocol_)))
- impl.flags_ |= implementation_type::enable_connection_aborted;
- else
- impl.flags_ &= ~implementation_type::enable_connection_aborted;
- ec = boost::system::error_code();
- }
- return ec;
- }
- else
- {
- if (option.level(impl.protocol_) == SOL_SOCKET
- && option.name(impl.protocol_) == SO_LINGER)
- {
- const ::linger* linger_option =
- reinterpret_cast<const ::linger*>(option.data(impl.protocol_));
- if (linger_option->l_onoff != 0 && linger_option->l_linger != 0)
- impl.flags_ |= implementation_type::close_might_block;
- else
- impl.flags_ &= ~implementation_type::close_might_block;
- }
-
- socket_ops::setsockopt(impl.socket_,
- option.level(impl.protocol_), option.name(impl.protocol_),
- option.data(impl.protocol_), option.size(impl.protocol_), ec);
- return ec;
- }
+ socket_ops::setsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), option.size(impl.protocol_), ec);
+ return ec;
   }
 
   // Set a socket option.
@@ -513,65 +193,12 @@
   boost::system::error_code get_option(const implementation_type& impl,
       Option& option, boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- if (option.level(impl.protocol_) == custom_socket_option_level
- && option.name(impl.protocol_) == enable_connection_aborted_option)
- {
- if (option.size(impl.protocol_) != sizeof(int))
- {
- ec = boost::asio::error::invalid_argument;
- }
- else
- {
- int* target = reinterpret_cast<int*>(option.data(impl.protocol_));
- if (impl.flags_ & implementation_type::enable_connection_aborted)
- *target = 1;
- else
- *target = 0;
- option.resize(impl.protocol_, sizeof(int));
- ec = boost::system::error_code();
- }
- return ec;
- }
- else
- {
- size_t size = option.size(impl.protocol_);
- socket_ops::getsockopt(impl.socket_,
- option.level(impl.protocol_), option.name(impl.protocol_),
- option.data(impl.protocol_), &size, ec);
- if (!ec)
- option.resize(impl.protocol_, size);
- return ec;
- }
- }
-
- // Perform an IO control command on the socket.
- template <typename IO_Control_Command>
- boost::system::error_code io_control(implementation_type& impl,
- IO_Control_Command& command, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::ioctl(impl.socket_, command.name(),
- static_cast<ioctl_arg_type*>(command.data()), ec);
-
- if (!ec && command.name() == static_cast<int>(FIONBIO))
- {
- if (*static_cast<ioctl_arg_type*>(command.data()))
- impl.flags_ |= implementation_type::user_set_non_blocking;
- else
- impl.flags_ &= ~implementation_type::user_set_non_blocking;
- }
-
+ std::size_t size = option.size(impl.protocol_);
+ socket_ops::getsockopt(impl.socket_, impl.state_,
+ option.level(impl.protocol_), option.name(impl.protocol_),
+ option.data(impl.protocol_), &size, ec);
+ if (!ec)
+ option.resize(impl.protocol_, size);
     return ec;
   }
 
@@ -579,12 +206,6 @@
   endpoint_type local_endpoint(const implementation_type& impl,
       boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return endpoint_type();
- }
-
     endpoint_type endpoint;
     std::size_t addr_len = endpoint.capacity();
     if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
@@ -597,210 +218,13 @@
   endpoint_type remote_endpoint(const implementation_type& impl,
       boost::system::error_code& ec) const
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
+ endpoint_type endpoint = impl.remote_endpoint_;
+ std::size_t addr_len = endpoint.capacity();
+ if (socket_ops::getpeername(impl.socket_, endpoint.data(),
+ &addr_len, impl.have_remote_endpoint_, ec))
       return endpoint_type();
- }
-
- if (impl.socket_.have_remote_endpoint())
- {
- // Check if socket is still connected.
- DWORD connect_time = 0;
- size_t connect_time_len = sizeof(connect_time);
- if (socket_ops::getsockopt(impl.socket_, SOL_SOCKET, SO_CONNECT_TIME,
- &connect_time, &connect_time_len, ec) == socket_error_retval)
- {
- return endpoint_type();
- }
- if (connect_time == 0xFFFFFFFF)
- {
- ec = boost::asio::error::not_connected;
- return endpoint_type();
- }
-
- ec = boost::system::error_code();
- return impl.socket_.remote_endpoint();
- }
- else
- {
- endpoint_type endpoint;
- std::size_t addr_len = endpoint.capacity();
- if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
- return endpoint_type();
- endpoint.resize(addr_len);
- return endpoint;
- }
- }
-
- /// Disable sends or receives on the socket.
- boost::system::error_code shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- socket_ops::shutdown(impl.socket_, what, ec);
- return ec;
- }
-
- // Send the given data to the peer. Returns the number of bytes sent.
- template <typename ConstBufferSequence>
- size_t send(implementation_type& impl, const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- 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 && bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Send the data.
- DWORD bytes_transferred = 0;
- int result = ::WSASend(impl.socket_, bufs.buffers(),
- bufs.count(), &bytes_transferred, flags, 0, 0);
- if (result != 0)
- {
- DWORD last_error = ::WSAGetLastError();
- if (last_error == ERROR_NETNAME_DELETED)
- last_error = WSAECONNRESET;
- else if (last_error == ERROR_PORT_UNREACHABLE)
- last_error = WSAECONNREFUSED;
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
- }
-
- // Wait until data can be sent without blocking.
- size_t send(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- // Wait for socket to become ready.
- socket_ops::poll_write(impl.socket_, ec);
-
- return 0;
- }
-
- template <typename ConstBufferSequence, typename Handler>
- class send_op : public operation
- {
- public:
- send_op(weak_cancel_token_type cancel_token,
- const ConstBufferSequence& buffers, Handler handler)
- : operation(&send_op::do_complete),
- cancel_token_(cancel_token),
- buffers_(buffers),
- 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 operation 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)
- {
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- // 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.
- 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;
- }
-
- // 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:
- weak_cancel_token_type cancel_token_;
- ConstBufferSequence buffers_;
- 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.cancel_token_, buffers, handler);
-
- buffer_sequence_adapter<boost::asio::const_buffer,
- ConstBufferSequence> bufs(buffers);
-
- start_send_op(impl, bufs.buffers(), bufs.count(), flags,
- impl.protocol_.type() == SOCK_STREAM && bufs.all_empty(), ptr.get());
- 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)
- {
- // 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_reactor_op(impl, reactor::write_op, ptr.get());
- ptr.release();
+ endpoint.resize(addr_len);
+ return endpoint;
   }
 
   // Send a datagram to the specified endpoint. Returns the number of bytes
@@ -810,107 +234,25 @@
       const endpoint_type& destination, socket_base::message_flags flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     buffer_sequence_adapter<boost::asio::const_buffer,
         ConstBufferSequence> bufs(buffers);
 
- // Send the data.
- DWORD bytes_transferred = 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();
- if (last_error == ERROR_PORT_UNREACHABLE)
- last_error = WSAECONNREFUSED;
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
+ return socket_ops::sync_sendto(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags,
+ destination.data(), destination.size(), ec);
   }
 
   // Wait until data can be sent without blocking.
   size_t send_to(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, const endpoint_type&,
+ const endpoint_type&, socket_base::message_flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for socket to become ready.
     socket_ops::poll_write(impl.socket_, ec);
 
     return 0;
   }
 
- template <typename ConstBufferSequence, typename Handler>
- class send_to_op : public operation
- {
- public:
- send_to_op(weak_cancel_token_type cancel_token,
- const ConstBufferSequence& buffers, Handler handler)
- : operation(&send_to_op::do_complete),
- cancel_token_(cancel_token),
- buffers_(buffers),
- 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 operation 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)
- {
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- // 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.
- 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. 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:
- weak_cancel_token_type cancel_token_;
- ConstBufferSequence buffers_;
- 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>
@@ -919,233 +261,35 @@
       socket_base::message_flags flags, Handler handler)
   {
     // 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.cancel_token_, buffers, handler);
+ typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, buffers, handler);
 
     buffer_sequence_adapter<boost::asio::const_buffer,
         ConstBufferSequence> bufs(buffers);
 
- start_send_to_op(impl, bufs.buffers(),
- bufs.count(), destination, flags, ptr.get());
- ptr.release();
+ start_send_to_op(impl, bufs.buffers(), bufs.count(),
+ destination.data(), static_cast<int>(destination.size()),
+ flags, p.p);
+ p.v = p.p = 0;
   }
 
   // Start an asynchronous wait until data can be sent without blocking.
   template <typename Handler>
   void async_send_to(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, const endpoint_type&, Handler handler)
+ const endpoint_type&, socket_base::message_flags, 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);
-
- start_reactor_op(impl, reactor::write_op, ptr.get());
- ptr.release();
- }
-
- // Receive some data from the peer. Returns the number of bytes received.
- template <typename MutableBufferSequence>
- size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
- 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 && bufs.all_empty())
- {
- ec = boost::system::error_code();
- return 0;
- }
-
- // Receive some data.
- DWORD bytes_transferred = 0;
- DWORD recv_flags = flags;
- int result = ::WSARecv(impl.socket_, bufs.buffers(),
- bufs.count(), &bytes_transferred, &recv_flags, 0, 0);
- if (result != 0)
- {
- DWORD last_error = ::WSAGetLastError();
- if (last_error == ERROR_NETNAME_DELETED)
- last_error = WSAECONNRESET;
- else if (last_error == ERROR_PORT_UNREACHABLE)
- last_error = WSAECONNREFUSED;
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
- if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM)
- {
- ec = boost::asio::error::eof;
- return 0;
- }
-
- ec = boost::system::error_code();
- return bytes_transferred;
- }
-
- // Wait until data can be received without blocking.
- size_t receive(implementation_type& impl, const null_buffers&,
- socket_base::message_flags, boost::system::error_code& ec)
- {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
+ typedef win_iocp_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, handler);
 
- // Wait for socket to become ready.
- socket_ops::poll_read(impl.socket_, ec);
-
- return 0;
- }
-
- template <typename MutableBufferSequence, typename Handler>
- class receive_op : public operation
- {
- public:
- receive_op(int protocol_type, weak_cancel_token_type cancel_token,
- const MutableBufferSequence& buffers, Handler handler)
- : operation(&receive_op::do_complete),
- protocol_type_(protocol_type),
- cancel_token_(cancel_token),
- buffers_(buffers),
- 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 operation 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)
- {
-#if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
- // 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.
- 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;
- }
-
- // Check for connection closed.
- else if (!ec && bytes_transferred == 0
- && o->protocol_type_ == SOCK_STREAM
- && !buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence>::all_empty(o->buffers_)
- && !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. 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_;
- weak_cancel_token_type cancel_token_;
- MutableBufferSequence buffers_;
- Handler 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, protocol_type,
- impl.cancel_token_, buffers, handler);
-
- buffer_sequence_adapter<boost::asio::mutable_buffer,
- MutableBufferSequence> bufs(buffers);
-
- 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.
- template <typename Handler>
- void async_receive(implementation_type& impl, const null_buffers& buffers,
- socket_base::message_flags flags, Handler handler)
- {
- 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.
-
- // Allocate and construct an operation to wrap the handler.
- 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,
- impl.cancel_token_, buffers, handler);
-
- ::WSABUF buf = { 0, 0 };
- start_receive_op(impl, &buf, 1, flags, false, ptr.get());
- ptr.release();
- }
- else
- {
- // 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_reactor_op(impl,
- (flags & socket_base::message_out_of_band)
- ? reactor::except_op : reactor::read_op,
- ptr.get());
- ptr.release();
- }
+ start_reactor_op(impl, reactor::write_op, p.p);
+ p.v = p.p = 0;
   }
 
   // Receive a datagram with the endpoint of the sender. Returns the number of
@@ -1156,41 +300,18 @@
       endpoint_type& sender_endpoint, socket_base::message_flags flags,
       boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     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.buffers(),
- bufs.count(), &bytes_transferred, &recv_flags,
- sender_endpoint.data(), &endpoint_size, 0, 0);
- if (result != 0)
- {
- DWORD last_error = ::WSAGetLastError();
- if (last_error == ERROR_PORT_UNREACHABLE)
- last_error = WSAECONNREFUSED;
- ec = boost::system::error_code(last_error,
- boost::asio::error::get_system_category());
- return 0;
- }
- if (bytes_transferred == 0 && impl.protocol_.type() == SOCK_STREAM)
- {
- ec = boost::asio::error::eof;
- return 0;
- }
+ std::size_t addr_len = sender_endpoint.capacity();
+ std::size_t bytes_recvd = socket_ops::sync_recvfrom(
+ impl.socket_, impl.state_, bufs.buffers(), bufs.count(),
+ flags, sender_endpoint.data(), &addr_len, ec);
 
- sender_endpoint.resize(static_cast<std::size_t>(endpoint_size));
+ if (!ec)
+ sender_endpoint.resize(addr_len);
 
- ec = boost::system::error_code();
- return bytes_transferred;
+ return bytes_recvd;
   }
 
   // Wait until data can be received without blocking.
@@ -1198,12 +319,6 @@
       const null_buffers&, endpoint_type& sender_endpoint,
       socket_base::message_flags, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return 0;
- }
-
     // Wait for socket to become ready.
     socket_ops::poll_read(impl.socket_, ec);
 
@@ -1213,75 +328,6 @@
     return 0;
   }
 
- template <typename MutableBufferSequence, typename Handler>
- class receive_from_op : public operation
- {
- public:
- 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())),
- buffers_(buffers),
- handler_(handler)
- {
- }
-
- int& endpoint_size()
- {
- return endpoint_size_;
- }
-
- 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.
- 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.
- 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.
- if (ec.value() == ERROR_PORT_UNREACHABLE)
- {
- ec = boost::asio::error::connection_refused;
- }
-
- // 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. 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_;
- weak_cancel_token_type cancel_token_;
- MutableBufferSequence buffers_;
- 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.
@@ -1291,19 +337,19 @@
       socket_base::message_flags flags, Handler 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,
- protocol_type, sender_endp, buffers, handler);
+ typedef win_iocp_socket_recvfrom_op<
+ MutableBufferSequence, endpoint_type, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler);
 
     buffer_sequence_adapter<boost::asio::mutable_buffer,
         MutableBufferSequence> bufs(buffers);
 
     start_receive_from_op(impl, bufs.buffers(), bufs.count(),
- sender_endp, flags, &ptr.get()->endpoint_size(), ptr.get());
- ptr.release();
+ sender_endp.data(), flags, &p.p->endpoint_size(), p.p);
+ p.v = p.p = 0;
   }
 
   // Wait until data can be received without blocking.
@@ -1313,19 +359,17 @@
       socket_base::message_flags flags, 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);
+ typedef win_iocp_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, handler);
 
     // Reset endpoint since it can be given no sensible value at this time.
     sender_endpoint = endpoint_type();
 
- start_reactor_op(impl,
- (flags & socket_base::message_out_of_band)
- ? reactor::except_op : reactor::read_op,
- ptr.get());
- ptr.release();
+ start_null_buffers_receive_op(impl, flags, p.p);
+ p.v = p.p = 0;
   }
 
   // Accept a new connection.
@@ -1333,12 +377,6 @@
   boost::system::error_code accept(implementation_type& impl, Socket& peer,
       endpoint_type* peer_endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
     // We cannot accept a socket that is already open.
     if (peer.is_open())
     {
@@ -1346,222 +384,22 @@
       return ec;
     }
 
- for (;;)
- {
- socket_holder new_socket;
- std::size_t addr_len = 0;
- if (peer_endpoint)
- {
- addr_len = peer_endpoint->capacity();
- new_socket.reset(socket_ops::accept(impl.socket_,
- peer_endpoint->data(), &addr_len, ec));
- }
- else
- {
- new_socket.reset(socket_ops::accept(impl.socket_, 0, 0, ec));
- }
-
- if (ec)
- {
- if (ec == boost::asio::error::connection_aborted
- && !(impl.flags_ & implementation_type::enable_connection_aborted))
- {
- // Retry accept operation.
- continue;
- }
- else
- {
- return ec;
- }
- }
+ std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0;
+ socket_holder new_socket(socket_ops::sync_accept(impl.socket_,
+ impl.state_, peer_endpoint ? peer_endpoint->data() : 0,
+ peer_endpoint ? &addr_len : 0, ec));
 
+ // On success, assign new connection to peer socket object.
+ if (new_socket.get() >= 0)
+ {
       if (peer_endpoint)
         peer_endpoint->resize(addr_len);
-
- peer.assign(impl.protocol_, new_socket.get(), ec);
- if (!ec)
+ if (!peer.assign(impl.protocol_, new_socket.get(), ec))
         new_socket.release();
- return ec;
     }
- }
 
- template <typename Socket, typename Handler>
- class accept_op : public operation
- {
- public:
- 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),
- peer_(peer),
- protocol_(protocol),
- peer_endpoint_(peer_endpoint),
- enable_connection_aborted_(enable_connection_aborted),
- handler_(handler)
- {
- }
-
- socket_holder& new_socket()
- {
- return new_socket_;
- }
-
- void* output_buffer()
- {
- return output_buffer_;
- }
-
- DWORD address_length()
- {
- return sizeof(sockaddr_storage_type) + 16;
- }
-
- 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)
- {
- // 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 (ec == boost::asio::error::connection_aborted
- && !o->enable_connection_aborted_)
- {
- // Reset OVERLAPPED structure.
- o->reset();
-
- // 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)
- {
- // 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)
- {
- 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
- {
- // 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
- {
- 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 (!ec)
- {
- 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);
- }
-
- // If the socket was successfully accepted, transfer ownership of the
- // socket to the peer object.
- if (!ec)
- {
- o->peer_.assign(o->protocol_,
- native_type(o->new_socket_.get(), peer_endpoint), ec);
- if (!ec)
- o->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);
- }
- }
-
- private:
- win_iocp_io_service& iocp_service_;
- socket_type socket_;
- socket_holder new_socket_;
- Socket& peer_;
- protocol_type protocol_;
- endpoint_type* peer_endpoint_;
- unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
- bool enable_connection_aborted_;
- Handler handler_;
- };
+ return ec;
+ }
 
   // Start an asynchronous accept. The peer and peer_endpoint objects
   // must be valid until the accept's handler is invoked.
@@ -1570,443 +408,55 @@
       endpoint_type* peer_endpoint, Handler handler)
   {
     // 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);
+ typedef win_iocp_socket_accept_op<Socket, protocol_type, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
     bool enable_connection_aborted =
- (impl.flags_ & implementation_type::enable_connection_aborted);
- 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();
+ (impl.state_ & socket_ops::enable_connection_aborted) != 0;
+ p.p = new (p.v) op(*this, impl.socket_, peer, impl.protocol_,
+ peer_endpoint, enable_connection_aborted, handler);
+
+ start_accept_op(impl, peer.is_open(), p.p->new_socket(),
+ impl.protocol_.family(), impl.protocol_.type(),
+ impl.protocol_.protocol(), p.p->output_buffer(),
+ p.p->address_length(), p.p);
+ p.v = p.p = 0;
   }
 
   // Connect the socket to the specified endpoint.
   boost::system::error_code connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, boost::system::error_code& ec)
   {
- if (!is_open(impl))
- {
- ec = boost::asio::error::bad_descriptor;
- return ec;
- }
-
- // Perform the connect operation.
- socket_ops::connect(impl.socket_,
+ socket_ops::sync_connect(impl.socket_,
         peer_endpoint.data(), peer_endpoint.size(), ec);
     return ec;
   }
 
- class connect_op_base : public reactor_op
- {
- public:
- connect_op_base(socket_type socket, func_type complete_func)
- : reactor_op(&connect_op_base::do_perform, complete_func),
- socket_(socket)
- {
- }
-
- static bool do_perform(reactor_op* base)
- {
- 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(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)
- {
- o->ec_ = boost::system::error_code(connect_error,
- boost::asio::error::get_system_category());
- }
-
- return true;
- }
-
- 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)
- {
- }
-
- 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:
- Handler handler_;
- };
-
   // Start an asynchronous connect.
   template <typename Handler>
   void async_connect(implementation_type& impl,
       const endpoint_type& peer_endpoint, Handler handler)
   {
     // 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(impl);
- 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
- {
- 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);
- }
+ typedef reactive_socket_connect_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.socket_, handler);
+
+ start_connect_op(impl, p.p, peer_endpoint.data(),
+ static_cast<int>(peer_endpoint.size()));
+ p.v = p.p = 0;
   }
-
- // 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(impl);
- iocp_service_.work_started();
-
- if (!is_open(impl))
- iocp_service_.on_completion(op, boost::asio::error::bad_descriptor);
- else
- {
- 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(impl);
- 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
- {
- 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(impl);
- iocp_service_.work_started();
-
- 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(impl);
- 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
- {
- 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
- {
- 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(impl);
-
- 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(impl);
-
- 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);
- }
-
- // Helper function to close a socket when the associated object is being
- // destroyed.
- void close_for_destruction(implementation_type& impl)
- {
- if (is_open(impl))
- {
- // 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* r = static_cast<reactor*>(
- interlocked_compare_exchange_pointer(
- reinterpret_cast<void**>(&reactor_), 0, 0));
- 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
- // default so that the closure is performed in the background.
- if (impl.flags_ & implementation_type::close_might_block)
- {
- ::linger opt;
- opt.l_onoff = 0;
- opt.l_linger = 0;
- boost::system::error_code ignored_ec;
- socket_ops::setsockopt(impl.socket_,
- SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
- }
-
- boost::system::error_code ignored_ec;
- socket_ops::close(impl.socket_, ignored_ec);
- impl.socket_ = invalid_socket;
- impl.flags_ = 0;
- impl.cancel_token_.reset();
-#if defined(BOOST_ASIO_ENABLE_CANCELIO)
- impl.safe_cancellation_thread_id_ = 0;
-#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
- }
- }
-
- // Update the ID of the thread from which cancellation is safe.
- void update_cancellation_thread_id(implementation_type& impl)
- {
-#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);
-#else // defined(BOOST_ASIO_ENABLE_CANCELIO)
- (void)impl;
-#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
- // - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
- void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp)
- {
-#if defined(_M_IX86)
- return reinterpret_cast<void*>(InterlockedCompareExchange(
- reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch),
- reinterpret_cast<LONG>(cmp)));
-#else
- return InterlockedCompareExchangePointer(dest, exch, cmp);
-#endif
- }
-
- // Helper function to emulate InterlockedExchangePointer functionality for:
- // - very old Platform SDKs; and
- // - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
- void* interlocked_exchange_pointer(void** dest, void* val)
- {
-#if defined(_M_IX86)
- return reinterpret_cast<void*>(InterlockedExchange(
- reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val)));
-#else
- return InterlockedExchangePointer(dest, val);
-#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* reactor_;
-
- // Mutex to protect access to the linked list of implementations.
- boost::asio::detail::mutex mutex_;
-
- // The head of a linked list of all implementations.
- implementation_type* impl_list_;
 };
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_ASIO_HAS_IOCP)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
 #endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_HPP

Added: trunk/boost/asio/detail/win_iocp_socket_service_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/detail/win_iocp_socket_service_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,387 @@
+//
+// detail/win_iocp_socket_service_base.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_SOCKET_SERVICE_BASE_HPP
+#define BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/addressof.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/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>
+#include <boost/asio/detail/win_iocp_io_service.hpp>
+#include <boost/asio/detail/win_iocp_null_buffers_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_send_op.hpp>
+#include <boost/asio/detail/win_iocp_socket_recv_op.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class win_iocp_socket_service_base
+{
+public:
+ // The implementation type of the socket.
+ struct base_implementation_type
+ {
+ // The native socket representation.
+ socket_type socket_;
+
+ // The current state of the socket.
+ socket_ops::state_type state_;
+
+ // We use a shared pointer as a cancellation token here to work around the
+ // broken Windows support for cancellation. MSDN says that when you call
+ // closesocket any outstanding WSARecv or WSASend operations will complete
+ // with the error ERROR_OPERATION_ABORTED. In practice they complete with
+ // ERROR_NETNAME_DELETED, which means you can't tell the difference between
+ // a local cancellation and the socket being hard-closed by the peer.
+ socket_ops::shared_cancel_token_type cancel_token_;
+
+ // Per-descriptor data used by the reactor.
+ 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
+ // operations. 0 means no asynchronous operations have been started yet.
+ // ~0 means asynchronous operations have been started from more than one
+ // thread, and cancellation is not supported for the socket.
+ DWORD safe_cancellation_thread_id_;
+#endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
+
+ // Pointers to adjacent socket implementations in linked list.
+ base_implementation_type* next_;
+ base_implementation_type* prev_;
+ };
+
+ // Constructor.
+ BOOST_ASIO_DECL win_iocp_socket_service_base(
+ boost::asio::io_service& io_service);
+
+ // Destroy all user-defined handler objects owned by the service.
+ BOOST_ASIO_DECL void shutdown_service();
+
+ // Construct a new socket implementation.
+ BOOST_ASIO_DECL void construct(base_implementation_type& impl);
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL void destroy(base_implementation_type& impl);
+
+ // Determine whether the socket is open.
+ bool is_open(const base_implementation_type& impl) const
+ {
+ return impl.socket_ != invalid_socket;
+ }
+
+ // Destroy a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code close(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Cancel all operations associated with the socket.
+ BOOST_ASIO_DECL boost::system::error_code cancel(
+ base_implementation_type& impl, boost::system::error_code& ec);
+
+ // Determine whether the socket is at the out-of-band data mark.
+ bool at_mark(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::sockatmark(impl.socket_, ec);
+ }
+
+ // Determine the number of bytes available for reading.
+ std::size_t available(const base_implementation_type& impl,
+ boost::system::error_code& ec) const
+ {
+ return socket_ops::available(impl.socket_, ec);
+ }
+
+ // Place the socket into the state where it will listen for new connections.
+ boost::system::error_code listen(base_implementation_type& impl,
+ int backlog, boost::system::error_code& ec)
+ {
+ socket_ops::listen(impl.socket_, backlog, ec);
+ return ec;
+ }
+
+ // Perform an IO control command on the socket.
+ template <typename IO_Control_Command>
+ boost::system::error_code io_control(base_implementation_type& impl,
+ IO_Control_Command& command, boost::system::error_code& ec)
+ {
+ socket_ops::ioctl(impl.socket_, impl.state_, command.name(),
+ static_cast<ioctl_arg_type*>(command.data()), ec);
+ return ec;
+ }
+
+ /// Disable sends or receives on the socket.
+ boost::system::error_code shutdown(base_implementation_type& impl,
+ socket_base::shutdown_type what, boost::system::error_code& ec)
+ {
+ socket_ops::shutdown(impl.socket_, what, ec);
+ return ec;
+ }
+
+ // Send the given data to the peer. Returns the number of bytes sent.
+ template <typename ConstBufferSequence>
+ size_t send(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_send(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be sent without blocking.
+ size_t send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_write(impl.socket_, ec);
+
+ return 0;
+ }
+
+ // 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(base_implementation_type& impl,
+ const ConstBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, buffers, handler);
+
+ buffer_sequence_adapter<boost::asio::const_buffer,
+ ConstBufferSequence> bufs(buffers);
+
+ start_send_op(impl, bufs.buffers(), bufs.count(), flags,
+ (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(),
+ p.p);
+ p.v = p.p = 0;
+ }
+
+ // Start an asynchronous wait until data can be sent without blocking.
+ template <typename Handler>
+ void async_send(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef win_iocp_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, handler);
+
+ start_reactor_op(impl, reactor::write_op, p.p);
+ p.v = p.p = 0;
+ }
+
+ // Receive some data from the peer. Returns the number of bytes received.
+ template <typename MutableBufferSequence>
+ size_t receive(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, boost::system::error_code& ec)
+ {
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ return socket_ops::sync_recv(impl.socket_, impl.state_,
+ bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec);
+ }
+
+ // Wait until data can be received without blocking.
+ size_t receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags, boost::system::error_code& ec)
+ {
+ // Wait for socket to become ready.
+ socket_ops::poll_read(impl.socket_, ec);
+
+ return 0;
+ }
+
+ // 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(base_implementation_type& impl,
+ const MutableBufferSequence& buffers,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef win_iocp_socket_recv_op<MutableBufferSequence, Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.state_, impl.cancel_token_, buffers, handler);
+
+ buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence> bufs(buffers);
+
+ start_receive_op(impl, bufs.buffers(), bufs.count(), flags,
+ (impl.state_ & socket_ops::stream_oriented) != 0 && bufs.all_empty(),
+ p.p);
+ p.v = p.p = 0;
+ }
+
+ // Wait until data can be received without blocking.
+ template <typename Handler>
+ void async_receive(base_implementation_type& impl, const null_buffers&,
+ socket_base::message_flags flags, Handler handler)
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef win_iocp_null_buffers_op<Handler> op;
+ typename op::ptr p = { boost::addressof(handler),
+ boost_asio_handler_alloc_helpers::allocate(
+ sizeof(op), handler), 0 };
+ p.p = new (p.v) op(impl.cancel_token_, handler);
+
+ start_null_buffers_receive_op(impl, flags, p.p);
+ p.v = p.p = 0;
+ }
+
+ // Helper function to restart an asynchronous accept operation.
+ BOOST_ASIO_DECL void restart_accept_op(socket_type s,
+ socket_holder& new_socket, int family, int type, int protocol,
+ void* output_buffer, DWORD address_length, operation* op);
+
+protected:
+ // Open a new socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_open(
+ base_implementation_type& impl, int family, int type,
+ int protocol, boost::system::error_code& ec);
+
+ // Assign a native socket to a socket implementation.
+ BOOST_ASIO_DECL boost::system::error_code do_assign(
+ base_implementation_type& impl, int type,
+ socket_type native_socket, boost::system::error_code& ec);
+
+ // Helper function to start an asynchronous send operation.
+ BOOST_ASIO_DECL void start_send_op(base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ socket_base::message_flags flags, bool noop, operation* op);
+
+ // Helper function to start an asynchronous send_to operation.
+ BOOST_ASIO_DECL void start_send_to_op(base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ const socket_addr_type* addr, int addrlen,
+ socket_base::message_flags flags, operation* op);
+
+ // Helper function to start an asynchronous receive operation.
+ BOOST_ASIO_DECL void start_receive_op(base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count,
+ socket_base::message_flags flags, bool noop, operation* op);
+
+ // Helper function to start an asynchronous null_buffers receive operation.
+ BOOST_ASIO_DECL void start_null_buffers_receive_op(
+ base_implementation_type& impl,
+ socket_base::message_flags flags, reactor_op* op);
+
+ // Helper function to start an asynchronous receive_from operation.
+ BOOST_ASIO_DECL void start_receive_from_op(base_implementation_type& impl,
+ WSABUF* buffers, std::size_t buffer_count, socket_addr_type* addr,
+ socket_base::message_flags flags, int* addrlen, operation* op);
+
+ // Helper function to start an asynchronous accept operation.
+ BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl,
+ bool peer_is_open, socket_holder& new_socket, int family, int type,
+ int protocol, void* output_buffer, DWORD address_length, operation* op);
+
+ // Start an asynchronous read or write operation using the the reactor.
+ BOOST_ASIO_DECL void start_reactor_op(base_implementation_type& impl,
+ int op_type, reactor_op* op);
+
+ // Start the asynchronous connect operation using the reactor.
+ BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl,
+ reactor_op* op, const socket_addr_type* addr, std::size_t addrlen);
+
+ // Helper function to close a socket when the associated object is being
+ // destroyed.
+ BOOST_ASIO_DECL void close_for_destruction(base_implementation_type& impl);
+
+ // Update the ID of the thread from which cancellation is safe.
+ BOOST_ASIO_DECL void update_cancellation_thread_id(
+ base_implementation_type& impl);
+
+ // 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.
+ BOOST_ASIO_DECL reactor& get_reactor();
+
+ // Helper function to emulate InterlockedCompareExchangePointer functionality
+ // for:
+ // - very old Platform SDKs; and
+ // - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
+ BOOST_ASIO_DECL void* interlocked_compare_exchange_pointer(
+ void** dest, void* exch, void* cmp);
+
+ // Helper function to emulate InterlockedExchangePointer functionality for:
+ // - very old Platform SDKs; and
+ // - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
+ BOOST_ASIO_DECL void* interlocked_exchange_pointer(void** dest, void* val);
+
+ // 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* reactor_;
+
+ // Mutex to protect access to the linked list of implementations.
+ boost::asio::detail::mutex mutex_;
+
+ // The head of a linked list of all implementations.
+ base_implementation_type* impl_list_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_iocp_socket_service_base.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
+#endif // BOOST_ASIO_DETAIL_WIN_IOCP_SOCKET_SERVICE_BASE_HPP

Modified: trunk/boost/asio/detail/win_mutex.hpp
==============================================================================
--- trunk/boost/asio/detail/win_mutex.hpp (original)
+++ trunk/boost/asio/detail/win_mutex.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_mutex.hpp
-// ~~~~~~~~~~~~~
+// detail/win_mutex.hpp
+// ~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,23 +15,15 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS)
 
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/socket_types.hpp>
 #include <boost/asio/detail/scoped_lock.hpp>
+#include <boost/asio/detail/socket_types.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -44,18 +36,7 @@
   typedef boost::asio::detail::scoped_lock<win_mutex> scoped_lock;
 
   // Constructor.
- win_mutex()
- {
- int error = do_init();
- if (error != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(error,
- boost::asio::error::get_system_category()),
- "mutex");
- boost::throw_exception(e);
- }
- }
+ BOOST_ASIO_DECL win_mutex();
 
   // Destructor.
   ~win_mutex()
@@ -79,35 +60,7 @@
   // Initialisation must be performed in a separate function to the constructor
   // since the compiler does not support the use of structured exceptions and
   // C++ exceptions in the same function.
- int do_init()
- {
-#if defined(__MINGW32__)
- // Not sure if MinGW supports structured exception handling, so for now
- // we'll just call the Windows API and hope.
-# if defined(UNDER_CE)
- ::InitializeCriticalSection(&crit_section_);
-# else
- ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
-# endif
- return 0;
-#else
- __try
- {
-# if defined(UNDER_CE)
- ::InitializeCriticalSection(&crit_section_);
-# else
- ::InitializeCriticalSectionAndSpinCount(&crit_section_, 0x80000000);
-# endif
- }
- __except(GetExceptionCode() == STATUS_NO_MEMORY
- ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
- {
- return ERROR_OUTOFMEMORY;
- }
-
- return 0;
-#endif
- }
+ BOOST_ASIO_DECL int do_init();
 
   ::CRITICAL_SECTION crit_section_;
 };
@@ -116,8 +69,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_mutex.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS)
+
 #endif // BOOST_ASIO_DETAIL_WIN_MUTEX_HPP

Modified: trunk/boost/asio/detail/win_signal_blocker.hpp
==============================================================================
--- trunk/boost/asio/detail/win_signal_blocker.hpp (original)
+++ trunk/boost/asio/detail/win_signal_blocker.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_signal_blocker.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
+// detail/win_signal_blocker.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,14 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
 #include <boost/asio/detail/noncopyable.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -62,8 +60,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_WIN_SIGNAL_BLOCKER_HPP

Modified: trunk/boost/asio/detail/win_thread.hpp
==============================================================================
--- trunk/boost/asio/detail/win_thread.hpp (original)
+++ trunk/boost/asio/detail/win_thread.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_thread.hpp
-// ~~~~~~~~~~~~~~
+// detail/win_thread.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,35 +15,25 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) && !defined(UNDER_CE)
 
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
-#include <memory>
-#include <process.h>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-unsigned int __stdcall win_thread_function(void* arg);
+BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg);
 
 #if defined(WINVER) && (WINVER < 0x0500)
-void __stdcall apc_function(ULONG data);
+BOOST_ASIO_DECL void __stdcall apc_function(ULONG data);
 #else
-void __stdcall apc_function(ULONG_PTR data);
+BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR data);
 #endif
 
 template <typename T>
@@ -74,92 +64,26 @@
 public:
   // Constructor.
   template <typename Function>
- win_thread(Function f)
- : exit_event_(0)
+ win_thread(Function f, unsigned int stack_size = 0)
+ : thread_(0),
+ exit_event_(0)
   {
- std::auto_ptr<func_base> arg(new func<Function>(f));
-
- ::HANDLE entry_event = 0;
- arg->entry_event_ = entry_event = ::CreateEvent(0, true, false, 0);
- if (!entry_event)
- {
- DWORD last_error = ::GetLastError();
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "thread.entry_event");
- boost::throw_exception(e);
- }
-
- arg->exit_event_ = exit_event_ = ::CreateEvent(0, true, false, 0);
- if (!exit_event_)
- {
- DWORD last_error = ::GetLastError();
- ::CloseHandle(entry_event);
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "thread.exit_event");
- boost::throw_exception(e);
- }
-
- unsigned int thread_id = 0;
- thread_ = reinterpret_cast<HANDLE>(::_beginthreadex(0, 0,
- win_thread_function, arg.get(), 0, &thread_id));
- if (!thread_)
- {
- DWORD last_error = ::GetLastError();
- if (entry_event)
- ::CloseHandle(entry_event);
- if (exit_event_)
- ::CloseHandle(exit_event_);
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "thread");
- boost::throw_exception(e);
- }
- arg.release();
-
- if (entry_event)
- {
- ::WaitForSingleObject(entry_event, INFINITE);
- ::CloseHandle(entry_event);
- }
+ start_thread(new func<Function>(f), stack_size);
   }
 
   // Destructor.
- ~win_thread()
- {
- ::CloseHandle(thread_);
-
- // The exit_event_ handle is deliberately allowed to leak here since it
- // is an error for the owner of an internal thread not to join() it.
- }
+ BOOST_ASIO_DECL ~win_thread();
 
   // Wait for the thread to exit.
- void join()
- {
- ::WaitForSingleObject(exit_event_, INFINITE);
- ::CloseHandle(exit_event_);
- if (terminate_threads())
- {
- ::TerminateThread(thread_, 0);
- }
- else
- {
- ::QueueUserAPC(apc_function, thread_, 0);
- ::WaitForSingleObject(thread_, INFINITE);
- }
- }
+ BOOST_ASIO_DECL void join();
 
 private:
- friend unsigned int __stdcall win_thread_function(void* arg);
+ friend BOOST_ASIO_DECL unsigned int __stdcall win_thread_function(void* arg);
 
 #if defined(WINVER) && (WINVER < 0x0500)
- friend void __stdcall apc_function(ULONG);
+ friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG);
 #else
- friend void __stdcall apc_function(ULONG_PTR);
+ friend BOOST_ASIO_DECL void __stdcall apc_function(ULONG_PTR);
 #endif
 
   class func_base
@@ -171,6 +95,12 @@
     ::HANDLE exit_event_;
   };
 
+ struct auto_func_base_ptr
+ {
+ func_base* ptr;
+ ~auto_func_base_ptr() { delete ptr; }
+ };
+
   template <typename Function>
   class func
     : public func_base
@@ -190,45 +120,22 @@
     Function f_;
   };
 
+ BOOST_ASIO_DECL void start_thread(func_base* arg, unsigned int stack_size);
+
   ::HANDLE thread_;
   ::HANDLE exit_event_;
 };
 
-inline unsigned int __stdcall win_thread_function(void* arg)
-{
- std::auto_ptr<win_thread::func_base> func(
- static_cast<win_thread::func_base*>(arg));
-
- ::SetEvent(func->entry_event_);
-
- func->run();
-
- // Signal that the thread has finished its work, but rather than returning go
- // to sleep to put the thread into a well known state. If the thread is being
- // joined during global object destruction then it may be killed using
- // TerminateThread (to avoid a deadlock in DllMain). Otherwise, the SleepEx
- // call will be interrupted using QueueUserAPC and the thread will shut down
- // cleanly.
- HANDLE exit_event = func->exit_event_;
- func.reset();
- ::SetEvent(exit_event);
- ::SleepEx(INFINITE, TRUE);
-
- return 0;
-}
-
-#if defined(WINVER) && (WINVER < 0x0500)
-inline void __stdcall apc_function(ULONG) {}
-#else
-inline void __stdcall apc_function(ULONG_PTR) {}
-#endif
-
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_thread.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS) && !defined(UNDER_CE)
+
 #endif // BOOST_ASIO_DETAIL_WIN_THREAD_HPP

Modified: trunk/boost/asio/detail/win_tss_ptr.hpp
==============================================================================
--- trunk/boost/asio/detail/win_tss_ptr.hpp (original)
+++ trunk/boost/asio/detail/win_tss_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// win_tss_ptr.hpp
-// ~~~~~~~~~~~~~~~
+// detail/win_tss_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,51 +15,31 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS)
 
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
+// Helper function to create thread-specific storage.
+BOOST_ASIO_DECL DWORD win_tss_ptr_create();
+
 template <typename T>
 class win_tss_ptr
   : private noncopyable
 {
 public:
-#if defined(UNDER_CE)
- enum { out_of_indexes = 0xFFFFFFFF };
-#else
- enum { out_of_indexes = TLS_OUT_OF_INDEXES };
-#endif
-
   // Constructor.
   win_tss_ptr()
+ : tss_key_(win_tss_ptr_create())
   {
- tss_key_ = ::TlsAlloc();
- if (tss_key_ == out_of_indexes)
- {
- DWORD last_error = ::GetLastError();
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "tss");
- boost::throw_exception(e);
- }
   }
 
   // Destructor.
@@ -90,8 +70,12 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/win_tss_ptr.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS)
+
 #endif // BOOST_ASIO_DETAIL_WIN_TSS_PTR_HPP

Modified: trunk/boost/asio/detail/wince_thread.hpp
==============================================================================
--- trunk/boost/asio/detail/wince_thread.hpp (original)
+++ trunk/boost/asio/detail/wince_thread.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// wince_thread.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/wince_thread.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,23 +15,17 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) && defined(UNDER_CE)
 
-#include <boost/asio/error.hpp>
+#include <memory>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/throw_exception.hpp>
-#include <memory>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -54,11 +48,9 @@
     if (!thread_)
     {
       DWORD last_error = ::GetLastError();
- boost::system::system_error e(
- boost::system::error_code(last_error,
- boost::asio::error::get_system_category()),
- "thread");
- boost::throw_exception(e);
+ boost::system::error_code ec(last_error,
+ boost::asio::error::get_system_category());
+ boost::asio::detail::throw_error(ec, "thread");
     }
     arg.release();
   }
@@ -119,8 +111,8 @@
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_WINDOWS) && defined(UNDER_CE)
+
 #endif // BOOST_ASIO_DETAIL_WINCE_THREAD_HPP

Modified: trunk/boost/asio/detail/winsock_init.hpp
==============================================================================
--- trunk/boost/asio/detail/winsock_init.hpp (original)
+++ trunk/boost/asio/detail/winsock_init.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// winsock_init.hpp
-// ~~~~~~~~~~~~~~~~
+// detail/winsock_init.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,108 +15,78 @@
 # 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/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/noncopyable.hpp>
-#include <boost/asio/detail/socket_types.hpp>
 
 namespace boost {
 namespace asio {
 namespace detail {
 
-template <int Major = 2, int Minor = 0>
-class winsock_init
- : private noncopyable
+class winsock_init_base
 {
-private:
- // Structure to perform the actual initialisation.
- struct do_init
+protected:
+ // Structure to track result of initialisation and number of uses. POD is used
+ // to ensure that the values are zero-initialised prior to any code being run.
+ struct data
   {
- do_init()
- {
- WSADATA wsa_data;
- result_ = ::WSAStartup(MAKEWORD(Major, Minor), &wsa_data);
- }
-
- ~do_init()
- {
- ::WSACleanup();
- }
-
- int result() const
- {
- return result_;
- }
-
- // Helper function to manage a do_init singleton. The static instance of the
- // winsock_init object ensures that this function is always called before
- // main, and therefore before any other threads can get started. The do_init
- // instance must be static in this function to ensure that it gets
- // initialised before any other global objects try to use it.
- static boost::shared_ptr<do_init> instance()
- {
- static boost::shared_ptr<do_init> init(new do_init);
- return init;
- }
-
- private:
- int result_;
+ long init_count_;
+ long result_;
   };
 
+ BOOST_ASIO_DECL static void startup(data& d,
+ unsigned char major, unsigned char minor);
+
+ BOOST_ASIO_DECL static void cleanup(data& d);
+
+ BOOST_ASIO_DECL static void throw_on_error(data& d);
+};
+
+template <int Major = 2, int Minor = 0>
+class winsock_init : private winsock_init_base
+{
 public:
- // Constructor.
- winsock_init()
- : ref_(do_init::instance())
+ winsock_init(bool allow_throw = true)
+ {
+ startup(data_, Major, Minor);
+ if (allow_throw)
+ throw_on_error(data_);
+ }
+
+ winsock_init(const winsock_init&)
   {
- // Check whether winsock was successfully initialised. This check is not
- // performed for the global instance since there will be nobody around to
- // catch the exception.
- if (this != &instance_ && ref_->result() != 0)
- {
- boost::system::system_error e(
- boost::system::error_code(ref_->result(),
- boost::asio::error::get_system_category()),
- "winsock");
- boost::throw_exception(e);
- }
+ startup(data_, Major, Minor);
+ throw_on_error(data_);
   }
 
- // Destructor.
   ~winsock_init()
   {
+ cleanup(data_);
   }
 
 private:
- // Instance to force initialisation of winsock at global scope.
- static winsock_init instance_;
-
- // Reference to singleton do_init object to ensure that winsock does not get
- // cleaned up until the last user has finished with it.
- boost::shared_ptr<do_init> ref_;
+ static data data_;
 };
 
 template <int Major, int Minor>
-winsock_init<Major, Minor> winsock_init<Major, Minor>::instance_;
+typename winsock_init<Major, Minor>::data winsock_init<Major, Minor>::data_;
+
+// Static variable to ensure that winsock is initialised before main, and
+// therefore before any other threads can get started.
+static const winsock_init<>& winsock_init_instance = winsock_init<>(false);
 
 } // namespace detail
 } // namespace asio
 } // namespace boost
 
-#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/detail/impl/winsock_init.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+
 #endif // BOOST_ASIO_DETAIL_WINSOCK_INIT_HPP

Modified: trunk/boost/asio/detail/wrapped_handler.hpp
==============================================================================
--- trunk/boost/asio/detail/wrapped_handler.hpp (original)
+++ trunk/boost/asio/detail/wrapped_handler.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// wrapped_handler.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// detail/wrapped_handler.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,12 @@
 # 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/type_traits/add_reference.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/bind_handler.hpp>
 #include <boost/asio/detail/handler_alloc_helpers.hpp>
 #include <boost/asio/detail/handler_invoke_helpers.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace detail {
@@ -35,9 +31,7 @@
 public:
   typedef void result_type;
 
- wrapped_handler(
- typename boost::add_reference<Dispatcher>::type dispatcher,
- Handler handler)
+ wrapped_handler(Dispatcher dispatcher, Handler handler)
     : dispatcher_(dispatcher),
       handler_(handler)
   {

Modified: trunk/boost/asio/error.hpp
==============================================================================
--- trunk/boost/asio/error.hpp (original)
+++ trunk/boost/asio/error.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,15 +15,15 @@
 # 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/config.hpp>
 #include <boost/cerrno.hpp>
 #include <boost/system/error_code.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/detail/socket_types.hpp>
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# include <WinError.h>
+#else
+# include <cerrno>
+# include <netdb.h>
+#endif
 
 #if defined(GENERATING_DOCUMENTATION)
 /// INTERNAL ONLY.
@@ -50,6 +50,8 @@
 # define BOOST_ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace error {
@@ -220,65 +222,11 @@
 
 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
-namespace detail {
-
-class netdb_category : public boost::system::error_category
-{
-public:
- const char* name() const
- {
- return "asio.netdb";
- }
-
- std::string message(int value) const
- {
- if (value == error::host_not_found)
- return "Host not found (authoritative)";
- if (value == error::host_not_found_try_again)
- return "Host not found (non-authoritative), try again later";
- if (value == error::no_data)
- return "The query is valid, but it does not have associated data";
- if (value == error::no_recovery)
- return "A non-recoverable error occurred during database lookup";
- return "asio.netdb error";
- }
-};
-
-} // namespace detail
-
-inline const boost::system::error_category& get_netdb_category()
-{
- static detail::netdb_category instance;
- return instance;
-}
+extern BOOST_ASIO_DECL
+const boost::system::error_category& get_netdb_category();
 
-namespace detail {
-
-class addrinfo_category : public boost::system::error_category
-{
-public:
- const char* name() const
- {
- return "asio.addrinfo";
- }
-
- std::string message(int value) const
- {
- if (value == error::service_not_found)
- return "Service not found";
- if (value == error::socket_type_not_supported)
- return "Socket type not supported";
- return "asio.addrinfo error";
- }
-};
-
-} // namespace detail
-
-inline const boost::system::error_category& get_addrinfo_category()
-{
- static detail::addrinfo_category instance;
- return instance;
-}
+extern BOOST_ASIO_DECL
+const boost::system::error_category& get_addrinfo_category();
 
 #else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
@@ -294,61 +242,11 @@
 
 #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
-namespace detail {
-
-class misc_category : public boost::system::error_category
-{
-public:
- const char* name() const
- {
- return "asio.misc";
- }
-
- std::string message(int value) const
- {
- if (value == error::already_open)
- return "Already open";
- if (value == error::eof)
- return "End of file";
- if (value == error::not_found)
- return "Element not found";
- if (value == error::fd_set_failure)
- return "The descriptor does not fit into the select call's fd_set";
- return "asio.misc error";
- }
-};
+extern BOOST_ASIO_DECL
+const boost::system::error_category& get_misc_category();
 
-} // namespace detail
-
-inline const boost::system::error_category& get_misc_category()
-{
- static detail::misc_category instance;
- return instance;
-}
-
-namespace detail {
-
-class ssl_category : public boost::system::error_category
-{
-public:
- const char* name() const
- {
- return "asio.ssl";
- }
-
- std::string message(int) const
- {
- return "asio.ssl error";
- }
-};
-
-} // namespace detail
-
-inline const boost::system::error_category& get_ssl_category()
-{
- static detail::ssl_category instance;
- return instance;
-}
+extern BOOST_ASIO_DECL
+const boost::system::error_category& get_ssl_category();
 
 static const boost::system::error_category& system_category
   = boost::asio::error::get_system_category();
@@ -430,13 +328,16 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #undef BOOST_ASIO_NATIVE_ERROR
 #undef BOOST_ASIO_SOCKET_ERROR
 #undef BOOST_ASIO_NETDB_ERROR
 #undef BOOST_ASIO_GETADDRINFO_ERROR
 #undef BOOST_ASIO_WIN_OR_POSIX
 
-
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/impl/error.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
 
 #endif // BOOST_ASIO_ERROR_HPP

Modified: trunk/boost/asio/handler_alloc_hook.hpp
==============================================================================
--- trunk/boost/asio/handler_alloc_hook.hpp (original)
+++ trunk/boost/asio/handler_alloc_hook.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,12 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <cstddef>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/handler_invoke_hook.hpp
==============================================================================
--- trunk/boost/asio/handler_invoke_hook.hpp (original)
+++ trunk/boost/asio/handler_invoke_hook.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,6 +15,8 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
+#include <boost/asio/detail/config.hpp>
+
 #include <boost/asio/detail/push_options.hpp>
 
 namespace boost {

Added: trunk/boost/asio/impl/error.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/error.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,155 @@
+//
+// impl/error.ipp
+// ~~~~~~~~~~~~~~
+//
+// 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_IMPL_ERROR_IPP
+#define BOOST_ASIO_IMPL_ERROR_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/cerrno.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace error {
+
+#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+namespace detail {
+
+class netdb_category : public boost::system::error_category
+{
+public:
+ const char* name() const
+ {
+ return "asio.netdb";
+ }
+
+ std::string message(int value) const
+ {
+ if (value == error::host_not_found)
+ return "Host not found (authoritative)";
+ if (value == error::host_not_found_try_again)
+ return "Host not found (non-authoritative), try again later";
+ if (value == error::no_data)
+ return "The query is valid, but it does not have associated data";
+ if (value == error::no_recovery)
+ return "A non-recoverable error occurred during database lookup";
+ return "asio.netdb error";
+ }
+};
+
+} // namespace detail
+
+const boost::system::error_category& get_netdb_category()
+{
+ static detail::netdb_category instance;
+ return instance;
+}
+
+namespace detail {
+
+class addrinfo_category : public boost::system::error_category
+{
+public:
+ const char* name() const
+ {
+ return "asio.addrinfo";
+ }
+
+ std::string message(int value) const
+ {
+ if (value == error::service_not_found)
+ return "Service not found";
+ if (value == error::socket_type_not_supported)
+ return "Socket type not supported";
+ return "asio.addrinfo error";
+ }
+};
+
+} // namespace detail
+
+const boost::system::error_category& get_addrinfo_category()
+{
+ static detail::addrinfo_category instance;
+ return instance;
+}
+
+#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
+
+namespace detail {
+
+class misc_category : public boost::system::error_category
+{
+public:
+ const char* name() const
+ {
+ return "asio.misc";
+ }
+
+ std::string message(int value) const
+ {
+ if (value == error::already_open)
+ return "Already open";
+ if (value == error::eof)
+ return "End of file";
+ if (value == error::not_found)
+ return "Element not found";
+ if (value == error::fd_set_failure)
+ return "The descriptor does not fit into the select call's fd_set";
+ return "asio.misc error";
+ }
+};
+
+} // namespace detail
+
+const boost::system::error_category& get_misc_category()
+{
+ static detail::misc_category instance;
+ return instance;
+}
+
+namespace detail {
+
+class ssl_category : public boost::system::error_category
+{
+public:
+ const char* name() const
+ {
+ return "asio.ssl";
+ }
+
+ std::string message(int) const
+ {
+ return "asio.ssl error";
+ }
+};
+
+} // namespace detail
+
+const boost::system::error_category& get_ssl_category()
+{
+ static detail::ssl_category instance;
+ return instance;
+}
+
+} // namespace error
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_ERROR_IPP

Added: trunk/boost/asio/impl/io_service.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/io_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,126 @@
+//
+// impl/io_service.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_IMPL_IO_SERVICE_HPP
+#define BOOST_ASIO_IMPL_IO_SERVICE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/service_registry.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_service.hpp>
+#else
+# include <boost/asio/detail/task_io_service.hpp>
+#endif
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename Handler>
+inline void io_service::dispatch(Handler handler)
+{
+ impl_.dispatch(handler);
+}
+
+template <typename Handler>
+inline void io_service::post(Handler handler)
+{
+ impl_.post(handler);
+}
+
+template <typename Handler>
+#if defined(GENERATING_DOCUMENTATION)
+unspecified
+#else
+inline detail::wrapped_handler<io_service&, Handler>
+#endif
+io_service::wrap(Handler handler)
+{
+ return detail::wrapped_handler<io_service&, Handler>(*this, handler);
+}
+
+inline io_service::work::work(boost::asio::io_service& io_service)
+ : io_service_(io_service)
+{
+ io_service_.impl_.work_started();
+}
+
+inline io_service::work::work(const work& other)
+ : io_service_(other.io_service_)
+{
+ io_service_.impl_.work_started();
+}
+
+inline io_service::work::~work()
+{
+ io_service_.impl_.work_finished();
+}
+
+inline boost::asio::io_service& io_service::work::io_service()
+{
+ return io_service_;
+}
+
+inline boost::asio::io_service& io_service::work::get_io_service()
+{
+ return io_service_;
+}
+
+inline boost::asio::io_service& io_service::service::io_service()
+{
+ return owner_;
+}
+
+inline boost::asio::io_service& io_service::service::get_io_service()
+{
+ return owner_;
+}
+
+template <typename Service>
+inline Service& use_service(io_service& ios)
+{
+ // Check that Service meets the necessary type requirements.
+ (void)static_cast<io_service::service*>(static_cast<Service*>(0));
+ (void)static_cast<const io_service::id*>(&Service::id);
+
+ return ios.service_registry_->template use_service<Service>();
+}
+
+template <typename Service>
+inline void add_service(io_service& ios, Service* svc)
+{
+ // Check that Service meets the necessary type requirements.
+ (void)static_cast<io_service::service*>(static_cast<Service*>(0));
+ (void)static_cast<const io_service::id*>(&Service::id);
+
+ ios.service_registry_->template add_service<Service>(svc);
+}
+
+template <typename Service>
+inline bool has_service(io_service& ios)
+{
+ // Check that Service meets the necessary type requirements.
+ (void)static_cast<io_service::service*>(static_cast<Service*>(0));
+ (void)static_cast<const io_service::id*>(&Service::id);
+
+ return ios.service_registry_->template has_service<Service>();
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_IO_SERVICE_HPP

Modified: trunk/boost/asio/impl/io_service.ipp
==============================================================================
--- trunk/boost/asio/impl/io_service.ipp (original)
+++ trunk/boost/asio/impl/io_service.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// io_service.ipp
-// ~~~~~~~~~~~~~~
+// impl/io_service.ipp
+// ~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -8,19 +8,16 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
 
-#ifndef BOOST_ASIO_IO_SERVICE_IPP
-#define BOOST_ASIO_IO_SERVICE_IPP
+#ifndef BOOST_ASIO_IMPL_IO_SERVICE_IPP
+#define BOOST_ASIO_IMPL_IO_SERVICE_IPP
 
 #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/asio/detail/config.hpp>
 #include <boost/limits.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/service_registry.hpp>
 #include <boost/asio/detail/throw_error.hpp>
 
@@ -28,32 +25,33 @@
 # include <boost/asio/detail/win_iocp_io_service.hpp>
 #else
 # include <boost/asio/detail/task_io_service.hpp>
-# include <boost/asio/detail/reactor.hpp>
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
-inline io_service::io_service()
+io_service::io_service()
   : service_registry_(new boost::asio::detail::service_registry(*this)),
     impl_(service_registry_->use_service<impl_type>())
 {
   impl_.init((std::numeric_limits<std::size_t>::max)());
 }
 
-inline io_service::io_service(std::size_t concurrency_hint)
+io_service::io_service(std::size_t concurrency_hint)
   : service_registry_(new boost::asio::detail::service_registry(*this)),
     impl_(service_registry_->use_service<impl_type>())
 {
   impl_.init(concurrency_hint);
 }
 
-inline io_service::~io_service()
+io_service::~io_service()
 {
   delete service_registry_;
 }
 
-inline std::size_t io_service::run()
+std::size_t io_service::run()
 {
   boost::system::error_code ec;
   std::size_t s = impl_.run(ec);
@@ -61,12 +59,12 @@
   return s;
 }
 
-inline std::size_t io_service::run(boost::system::error_code& ec)
+std::size_t io_service::run(boost::system::error_code& ec)
 {
   return impl_.run(ec);
 }
 
-inline std::size_t io_service::run_one()
+std::size_t io_service::run_one()
 {
   boost::system::error_code ec;
   std::size_t s = impl_.run_one(ec);
@@ -74,12 +72,12 @@
   return s;
 }
 
-inline std::size_t io_service::run_one(boost::system::error_code& ec)
+std::size_t io_service::run_one(boost::system::error_code& ec)
 {
   return impl_.run_one(ec);
 }
 
-inline std::size_t io_service::poll()
+std::size_t io_service::poll()
 {
   boost::system::error_code ec;
   std::size_t s = impl_.poll(ec);
@@ -87,12 +85,12 @@
   return s;
 }
 
-inline std::size_t io_service::poll(boost::system::error_code& ec)
+std::size_t io_service::poll(boost::system::error_code& ec)
 {
   return impl_.poll(ec);
 }
 
-inline std::size_t io_service::poll_one()
+std::size_t io_service::poll_one()
 {
   boost::system::error_code ec;
   std::size_t s = impl_.poll_one(ec);
@@ -100,122 +98,39 @@
   return s;
 }
 
-inline std::size_t io_service::poll_one(boost::system::error_code& ec)
+std::size_t io_service::poll_one(boost::system::error_code& ec)
 {
   return impl_.poll_one(ec);
 }
 
-inline void io_service::stop()
+void io_service::stop()
 {
   impl_.stop();
 }
 
-inline void io_service::reset()
+void io_service::reset()
 {
   impl_.reset();
 }
 
-template <typename Handler>
-inline void io_service::dispatch(Handler handler)
-{
- impl_.dispatch(handler);
-}
-
-template <typename Handler>
-inline void io_service::post(Handler handler)
-{
- impl_.post(handler);
-}
-
-template <typename Handler>
-#if defined(GENERATING_DOCUMENTATION)
-unspecified
-#else
-inline detail::wrapped_handler<io_service&, Handler>
-#endif
-io_service::wrap(Handler handler)
-{
- return detail::wrapped_handler<io_service&, Handler>(*this, handler);
-}
-
-inline io_service::work::work(boost::asio::io_service& io_service)
- : io_service_(io_service)
-{
- io_service_.impl_.work_started();
-}
-
-inline io_service::work::work(const work& other)
- : io_service_(other.io_service_)
-{
- io_service_.impl_.work_started();
-}
-
-inline io_service::work::~work()
-{
- io_service_.impl_.work_finished();
-}
-
-inline boost::asio::io_service& io_service::work::io_service()
-{
- return io_service_;
-}
-
-inline boost::asio::io_service& io_service::work::get_io_service()
-{
- return io_service_;
-}
-
-inline io_service::service::service(boost::asio::io_service& owner)
+io_service::service::service(boost::asio::io_service& owner)
   : owner_(owner),
     next_(0)
 {
 }
 
-inline io_service::service::~service()
-{
-}
-
-inline boost::asio::io_service& io_service::service::io_service()
-{
- return owner_;
-}
-
-inline boost::asio::io_service& io_service::service::get_io_service()
+io_service::service::~service()
 {
- return owner_;
 }
 
-template <typename Service>
-inline Service& use_service(io_service& ios)
+service_already_exists::service_already_exists()
+ : std::logic_error("Service already exists.")
 {
- // Check that Service meets the necessary type requirements.
- (void)static_cast<io_service::service*>(static_cast<Service*>(0));
- (void)static_cast<const io_service::id*>(&Service::id);
-
- return ios.service_registry_->template use_service<Service>();
 }
 
-template <typename Service>
-void add_service(io_service& ios, Service* svc)
+invalid_service_owner::invalid_service_owner()
+ : std::logic_error("Invalid service owner.")
 {
- // Check that Service meets the necessary type requirements.
- (void)static_cast<io_service::service*>(static_cast<Service*>(0));
- (void)static_cast<const io_service::id*>(&Service::id);
-
- if (&ios != &svc->io_service())
- boost::throw_exception(invalid_service_owner());
- if (!ios.service_registry_->template add_service<Service>(svc))
- boost::throw_exception(service_already_exists());
-}
-
-template <typename Service>
-bool has_service(io_service& ios)
-{
- // Check that Service meets the necessary type requirements.
- (void)static_cast<io_service::service*>(static_cast<Service*>(0));
- (void)static_cast<const io_service::id*>(&Service::id);
-
- return ios.service_registry_->template has_service<Service>();
 }
 
 } // namespace asio
@@ -223,4 +138,4 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
-#endif // BOOST_ASIO_IO_SERVICE_IPP
+#endif // BOOST_ASIO_IMPL_IO_SERVICE_IPP

Added: trunk/boost/asio/impl/read.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/read.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,388 @@
+//
+// impl/read.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_IMPL_READ_HPP
+#define BOOST_ASIO_IMPL_READ_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <algorithm>
+#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>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition>
+std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ boost::asio::detail::consuming_buffers<
+ mutable_buffer, MutableBufferSequence> tmp(buffers);
+ std::size_t total_transferred = 0;
+ 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.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ }
+ return total_transferred;
+}
+
+template <typename SyncReadStream, typename MutableBufferSequence>
+inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition>
+inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+template <typename SyncReadStream, typename Allocator,
+ typename CompletionCondition>
+std::size_t read(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ 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 = read_size_helper(b, max_size);
+ while (bytes_available > 0)
+ {
+ std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
+ b.commit(bytes_transferred);
+ total_transferred += bytes_transferred;
+ max_size = detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred));
+ bytes_available = read_size_helper(b, max_size);
+ }
+ return total_transferred;
+}
+
+template <typename SyncReadStream, typename Allocator>
+inline std::size_t read(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s, b, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename Allocator,
+ typename CompletionCondition>
+inline std::size_t read(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s, b, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition, typename ReadHandler>
+ class read_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, ReadHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ stream_(stream),
+ buffers_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ switch (start)
+ {
+ case 1:
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ for (;;)
+ {
+ stream_.async_read_some(buffers_, *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ buffers_.consume(bytes_transferred);
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ if ((!ec && bytes_transferred == 0)
+ || buffers_.begin() == buffers_.end())
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::detail::consuming_buffers<
+ mutable_buffer, MutableBufferSequence> buffers_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ 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)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(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_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::mutable_buffer buffer_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_op<AsyncReadStream, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_op<AsyncReadStream, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename MutableBufferSequence, typename CompletionCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_op<AsyncReadStream, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename MutableBufferSequence,
+ typename CompletionCondition, typename ReadHandler>
+inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, ReadHandler handler)
+{
+ detail::read_op<AsyncReadStream, MutableBufferSequence,
+ CompletionCondition, ReadHandler>(
+ s, buffers, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncReadStream, typename MutableBufferSequence,
+ typename ReadHandler>
+inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
+ ReadHandler handler)
+{
+ async_read(s, buffers, transfer_all(), handler);
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ class read_streambuf_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ read_streambuf_op(AsyncReadStream& stream,
+ basic_streambuf<Allocator>& streambuf,
+ CompletionCondition completion_condition, ReadHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ stream_(stream),
+ streambuf_(streambuf),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t max_size, bytes_available;
+ switch (start)
+ {
+ case 1:
+ max_size = this->check_for_completion(ec, total_transferred_);
+ bytes_available = read_size_helper(streambuf_, max_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_for_completion(ec, total_transferred_);
+ bytes_available = read_size_helper(streambuf_, max_size);
+ if ((!ec && bytes_transferred == 0) || bytes_available == 0)
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_streambuf_op<AsyncReadStream, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_streambuf_op<AsyncReadStream, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename Allocator, typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_streambuf_op<AsyncReadStream, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+inline void async_read(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, ReadHandler handler)
+{
+ detail::read_streambuf_op<AsyncReadStream,
+ Allocator, CompletionCondition, ReadHandler>(
+ s, b, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+inline void async_read(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, ReadHandler handler)
+{
+ async_read(s, b, transfer_all(), handler);
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_READ_HPP

Deleted: trunk/boost/asio/impl/read.ipp
==============================================================================
--- trunk/boost/asio/impl/read.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,403 +0,0 @@
-//
-// read.ipp
-// ~~~~~~~~
-//
-// 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_READ_IPP
-#define BOOST_ASIO_READ_IPP
-
-#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 <algorithm>
-#include <boost/asio/detail/pop_options.hpp>
-
-#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>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-namespace boost {
-namespace asio {
-
-template <typename SyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition>
-std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- ec = boost::system::error_code();
- boost::asio::detail::consuming_buffers<
- mutable_buffer, MutableBufferSequence> tmp(buffers);
- std::size_t total_transferred = 0;
- 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.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- }
- return total_transferred;
-}
-
-template <typename SyncReadStream, typename MutableBufferSequence>
-inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read(s, buffers, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition>
-inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-template <typename SyncReadStream, typename Allocator,
- typename CompletionCondition>
-std::size_t read(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- ec = boost::system::error_code();
- 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()));
- while (bytes_available > 0)
- {
- std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);
- b.commit(bytes_transferred);
- total_transferred += bytes_transferred;
- max_size = detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred));
- bytes_available = std::min<std::size_t>(512,
- std::min<std::size_t>(max_size, b.max_size() - b.size()));
- }
- return total_transferred;
-}
-
-template <typename SyncReadStream, typename Allocator>
-inline std::size_t read(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read(s, b, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncReadStream, typename Allocator,
- typename CompletionCondition>
-inline std::size_t read(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read(s, b, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition, typename ReadHandler>
- class read_op
- : detail::base_from_completion_cond<CompletionCondition>
- {
- public:
- read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, ReadHandler handler)
- : detail::base_from_completion_cond<
- CompletionCondition>(completion_condition),
- stream_(stream),
- buffers_(buffers),
- total_transferred_(0),
- 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_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_);
- }
- }
-
- //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_)
- {
- 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_;
- boost::asio::mutable_buffer buffer_;
- std::size_t total_transferred_;
- ReadHandler handler_;
- bool start_;
- };
-
- template <typename AsyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_op<AsyncReadStream, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_op<AsyncReadStream, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream,
- typename MutableBufferSequence, typename CompletionCondition,
- typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_op<AsyncReadStream, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename MutableBufferSequence,
- typename CompletionCondition, typename ReadHandler>
-inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, ReadHandler handler)
-{
- detail::read_op<AsyncReadStream, MutableBufferSequence,
- CompletionCondition, ReadHandler>(
- s, buffers, completion_condition, handler)(
- boost::system::error_code(), 0);
-}
-
-template <typename AsyncReadStream, typename MutableBufferSequence,
- typename ReadHandler>
-inline void async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
- ReadHandler handler)
-{
- async_read(s, buffers, transfer_all(), handler);
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncReadStream, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- class read_streambuf_op
- : detail::base_from_completion_cond<CompletionCondition>
- {
- public:
- read_streambuf_op(AsyncReadStream& stream,
- basic_streambuf<Allocator>& streambuf,
- CompletionCondition completion_condition, ReadHandler handler)
- : detail::base_from_completion_cond<
- CompletionCondition>(completion_condition),
- stream_(stream),
- streambuf_(streambuf),
- total_transferred_(0),
- handler_(handler),
- start_(true)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- 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_);
- }
- }
-
- //private:
- AsyncReadStream& stream_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- std::size_t total_transferred_;
- ReadHandler handler_;
- bool start_;
- };
-
- template <typename AsyncReadStream, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_streambuf_op<AsyncReadStream, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_streambuf_op<AsyncReadStream, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream,
- typename Allocator, typename CompletionCondition, typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_streambuf_op<AsyncReadStream, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
-inline void async_read(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, ReadHandler 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>
-inline void async_read(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, ReadHandler handler)
-{
- async_read(s, b, transfer_all(), handler);
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_READ_IPP

Added: trunk/boost/asio/impl/read_at.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/read_at.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,412 @@
+//
+// impl/read_at.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_IMPL_READ_AT_HPP
+#define BOOST_ASIO_IMPL_READ_AT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <algorithm>
+#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>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+ typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ boost::asio::detail::consuming_buffers<
+ mutable_buffer, MutableBufferSequence> tmp(buffers);
+ std::size_t total_transferred = 0;
+ tmp.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ while (tmp.begin() != tmp.end())
+ {
+ std::size_t bytes_transferred = d.read_some_at(
+ offset + total_transferred, tmp, ec);
+ tmp.consume(bytes_transferred);
+ total_transferred += bytes_transferred;
+ tmp.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ }
+ return total_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, const MutableBufferSequence& buffers)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_at(
+ d, offset, buffers, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
+ typename CompletionCondition>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_at(
+ d, offset, buffers, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition>
+std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ 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 = read_size_helper(b, max_size);
+ while (bytes_available > 0)
+ {
+ std::size_t bytes_transferred = d.read_some_at(
+ offset + total_transferred, b.prepare(bytes_available), ec);
+ b.commit(bytes_transferred);
+ total_transferred += bytes_transferred;
+ max_size = detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred));
+ bytes_available = read_size_helper(b, max_size);
+ }
+ return total_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename Allocator>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_at(
+ d, offset, b, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition>
+inline std::size_t read_at(SyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_at(
+ d, offset, b, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncRandomAccessReadDevice,
+ typename MutableBufferSequence, typename CompletionCondition,
+ typename ReadHandler>
+ class read_at_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ read_at_op(AsyncRandomAccessReadDevice& device,
+ boost::uint64_t offset, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, ReadHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ buffers_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ switch (start)
+ {
+ case 1:
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ for (;;)
+ {
+ device_.async_read_some_at(
+ offset_ + total_transferred_, buffers_, *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ buffers_.consume(bytes_transferred);
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ if ((!ec && bytes_transferred == 0)
+ || buffers_.begin() == buffers_.end())
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessReadDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::detail::consuming_buffers<
+ mutable_buffer, MutableBufferSequence> buffers_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessReadDevice,
+ typename CompletionCondition, typename ReadHandler>
+ class read_at_op<AsyncRandomAccessReadDevice,
+ boost::asio::mutable_buffers_1, CompletionCondition, ReadHandler>
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ read_at_op(AsyncRandomAccessReadDevice& device,
+ boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers,
+ CompletionCondition completion_condition, ReadHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ buffer_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(ec, total_transferred_);
+ for (;;)
+ {
+ device_.async_read_some_at(offset_ + total_transferred_,
+ boost::asio::buffer(buffer_ + total_transferred_, n), *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ if ((!ec && bytes_transferred == 0)
+ || (n = this->check_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessReadDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::mutable_buffer buffer_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessReadDevice,
+ typename MutableBufferSequence, typename CompletionCondition,
+ typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncRandomAccessReadDevice,
+ typename MutableBufferSequence, typename CompletionCondition,
+ typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncRandomAccessReadDevice,
+ typename MutableBufferSequence, typename CompletionCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+ typename CompletionCondition, typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, const MutableBufferSequence& buffers,
+ CompletionCondition completion_condition, ReadHandler handler)
+{
+ detail::read_at_op<AsyncRandomAccessReadDevice,
+ MutableBufferSequence, CompletionCondition, ReadHandler>(
+ d, offset, buffers, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
+ typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, const MutableBufferSequence& buffers,
+ ReadHandler handler)
+{
+ async_read_at(d, offset, buffers, transfer_all(), handler);
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ class read_at_streambuf_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
+ boost::uint64_t offset, basic_streambuf<Allocator>& streambuf,
+ CompletionCondition completion_condition, ReadHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ streambuf_(streambuf),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t max_size, bytes_available;
+ switch (start)
+ {
+ case 1:
+ max_size = this->check_for_completion(ec, total_transferred_);
+ bytes_available = read_size_helper(streambuf_, max_size);
+ for (;;)
+ {
+ device_.async_read_some_at(offset_ + total_transferred_,
+ streambuf_.prepare(bytes_available), *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ streambuf_.commit(bytes_transferred);
+ max_size = this->check_for_completion(ec, total_transferred_);
+ bytes_available = read_size_helper(streambuf_, max_size);
+ if ((!ec && bytes_transferred == 0) || bytes_available == 0)
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessReadDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ std::size_t total_transferred_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncRandomAccessReadDevice,
+ typename Allocator, typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+ typename CompletionCondition, typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, ReadHandler handler)
+{
+ detail::read_at_streambuf_op<AsyncRandomAccessReadDevice,
+ Allocator, CompletionCondition, ReadHandler>(
+ d, offset, b, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncRandomAccessReadDevice, typename Allocator,
+ typename ReadHandler>
+inline void async_read_at(AsyncRandomAccessReadDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ ReadHandler handler)
+{
+ async_read_at(d, offset, b, transfer_all(), handler);
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_READ_AT_HPP

Deleted: trunk/boost/asio/impl/read_at.ipp
==============================================================================
--- trunk/boost/asio/impl/read_at.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,375 +0,0 @@
-//
-// read_at.ipp
-// ~~~~~~~~~~~
-//
-// 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_READ_AT_IPP
-#define BOOST_ASIO_READ_AT_IPP
-
-#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 <algorithm>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/completion_condition.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/consuming_buffers.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-namespace boost {
-namespace asio {
-
-template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
- typename CompletionCondition>
-std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- ec = boost::system::error_code();
- boost::asio::detail::consuming_buffers<
- mutable_buffer, MutableBufferSequence> tmp(buffers);
- std::size_t total_transferred = 0;
- tmp.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- while (tmp.begin() != tmp.end())
- {
- std::size_t bytes_transferred = d.read_some_at(
- offset + total_transferred, tmp, ec);
- tmp.consume(bytes_transferred);
- total_transferred += bytes_transferred;
- tmp.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- }
- return total_transferred;
-}
-
-template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
-inline std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, const MutableBufferSequence& buffers)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, buffers, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence,
- typename CompletionCondition>
-inline std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, buffers, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-template <typename SyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition>
-std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- std::size_t total_transferred = 0;
- for (;;)
- {
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- std::size_t bytes_transferred = d.read_some_at(
- offset + total_transferred, b.prepare(bytes_available), ec);
- b.commit(bytes_transferred);
- total_transferred += bytes_transferred;
- if (b.size() == b.max_size()
- || completion_condition(ec, total_transferred))
- return total_transferred;
- }
-}
-
-template <typename SyncRandomAccessReadDevice, typename Allocator>
-inline std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, b, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition>
-inline std::size_t read_at(SyncRandomAccessReadDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, b, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncRandomAccessReadDevice,
- typename MutableBufferSequence, typename CompletionCondition,
- typename ReadHandler>
- class read_at_handler
- {
- public:
- typedef boost::asio::detail::consuming_buffers<
- mutable_buffer, MutableBufferSequence> buffers_type;
-
- read_at_handler(AsyncRandomAccessReadDevice& stream,
- boost::uint64_t offset, const buffers_type& buffers,
- CompletionCondition completion_condition, ReadHandler handler)
- : stream_(stream),
- offset_(offset),
- buffers_(buffers),
- total_transferred_(0),
- completion_condition_(completion_condition),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- total_transferred_ += bytes_transferred;
- buffers_.consume(bytes_transferred);
- buffers_.prepare(detail::adapt_completion_condition_result(
- completion_condition_(ec, total_transferred_)));
- if (buffers_.begin() == buffers_.end())
- {
- handler_(ec, total_transferred_);
- }
- else
- {
- stream_.async_read_some_at(
- offset_ + total_transferred_, buffers_, *this);
- }
- }
-
- //private:
- AsyncRandomAccessReadDevice& stream_;
- boost::uint64_t offset_;
- buffers_type buffers_;
- std::size_t total_transferred_;
- CompletionCondition completion_condition_;
- ReadHandler handler_;
- };
-
- template <typename AsyncRandomAccessReadDevice,
- typename MutableBufferSequence, typename CompletionCondition,
- typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncRandomAccessReadDevice,
- typename MutableBufferSequence, typename CompletionCondition,
- typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncRandomAccessReadDevice,
- typename MutableBufferSequence, typename CompletionCondition,
- typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_at_handler<AsyncRandomAccessReadDevice, MutableBufferSequence,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
- typename CompletionCondition, typename ReadHandler>
-inline void async_read_at(AsyncRandomAccessReadDevice& d,
- boost::uint64_t offset, 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.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- if (tmp.begin() == tmp.end())
- {
- d.get_io_service().post(detail::bind_handler(
- handler, ec, total_transferred));
- return;
- }
-
- d.async_read_some_at(offset, tmp,
- detail::read_at_handler<AsyncRandomAccessReadDevice,
- MutableBufferSequence, CompletionCondition, ReadHandler>(
- d, offset, tmp, completion_condition, handler));
-}
-
-template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
- typename ReadHandler>
-inline void async_read_at(AsyncRandomAccessReadDevice& d,
- boost::uint64_t offset, const MutableBufferSequence& buffers,
- ReadHandler handler)
-{
- async_read_at(d, offset, buffers, transfer_all(), handler);
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- class read_at_streambuf_handler
- {
- public:
- read_at_streambuf_handler(AsyncRandomAccessReadDevice& stream,
- boost::uint64_t offset, basic_streambuf<Allocator>& streambuf,
- CompletionCondition completion_condition, ReadHandler handler)
- : stream_(stream),
- offset_(offset),
- streambuf_(streambuf),
- total_transferred_(0),
- completion_condition_(completion_condition),
- handler_(handler)
- {
- }
-
- 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)
- {
- handler_(ec, total_transferred_);
- }
- else
- {
- stream_.async_read_some_at(offset_ + total_transferred_,
- streambuf_.prepare(bytes_available), *this);
- }
- }
-
- //private:
- AsyncRandomAccessReadDevice& stream_;
- boost::uint64_t offset_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- std::size_t total_transferred_;
- CompletionCondition completion_condition_;
- ReadHandler handler_;
- };
-
- template <typename AsyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncRandomAccessReadDevice,
- typename Allocator, typename CompletionCondition, typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
- CompletionCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncRandomAccessReadDevice, typename Allocator,
- typename CompletionCondition, typename ReadHandler>
-inline void async_read_at(AsyncRandomAccessReadDevice& d,
- boost::uint64_t offset, 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)
- {
- d.get_io_service().post(detail::bind_handler(
- handler, ec, total_transferred));
- return;
- }
-
- d.async_read_some_at(offset, b.prepare(bytes_available),
- detail::read_at_streambuf_handler<AsyncRandomAccessReadDevice, Allocator,
- CompletionCondition, ReadHandler>(
- d, offset, b, completion_condition, handler));
-}
-
-template <typename AsyncRandomAccessReadDevice, typename Allocator,
- typename ReadHandler>
-inline void async_read_at(AsyncRandomAccessReadDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- ReadHandler handler)
-{
- async_read_at(d, offset, b, transfer_all(), handler);
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_READ_AT_IPP

Added: trunk/boost/asio/impl/read_until.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/read_until.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,876 @@
+//
+// impl/read_until.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_IMPL_READ_UNTIL_HPP
+#define BOOST_ASIO_IMPL_READ_UNTIL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <utility>
+#include <boost/limits.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/buffers_iterator.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncReadStream, typename Allocator>
+inline std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, char delim)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s, b, delim, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename Allocator>
+std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, char delim,
+ boost::system::error_code& ec)
+{
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = b.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ iterator iter = std::find(start, end, delim);
+ if (iter != end)
+ {
+ // Found a match. We're done.
+ ec = boost::system::error_code();
+ return iter - begin + 1;
+ }
+ else
+ {
+ // No match. Next search can start with the new data.
+ search_position = end - begin;
+ }
+
+ // Check if buffer is full.
+ if (b.size() == b.max_size())
+ {
+ ec = error::not_found;
+ return 0;
+ }
+
+ // Need more data.
+ std::size_t bytes_to_read = read_size_helper(b, 65536);
+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));
+ if (ec)
+ return 0;
+ }
+}
+
+template <typename SyncReadStream, typename Allocator>
+inline std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const std::string& delim)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s, b, delim, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+namespace detail
+{
+ // Algorithm that finds a subsequence of equal values in a sequence. Returns
+ // (iterator,true) if a full match was found, in which case the iterator
+ // points to the beginning of the match. Returns (iterator,false) if a
+ // partial match was found at the end of the first sequence, in which case
+ // the iterator points to the beginning of the partial match. Returns
+ // (last1,false) if no full or partial match was found.
+ template <typename Iterator1, typename Iterator2>
+ std::pair<Iterator1, bool> partial_search(
+ Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
+ {
+ for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)
+ {
+ Iterator1 test_iter1 = iter1;
+ Iterator2 test_iter2 = first2;
+ for (;; ++test_iter1, ++test_iter2)
+ {
+ if (test_iter2 == last2)
+ return std::make_pair(iter1, true);
+ if (test_iter1 == last1)
+ {
+ if (test_iter2 != first2)
+ return std::make_pair(iter1, false);
+ else
+ break;
+ }
+ if (*test_iter1 != *test_iter2)
+ break;
+ }
+ }
+ return std::make_pair(last1, false);
+ }
+} // namespace detail
+
+template <typename SyncReadStream, typename Allocator>
+std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const std::string& delim,
+ boost::system::error_code& ec)
+{
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = b.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = detail::partial_search(
+ start, end, delim.begin(), delim.end());
+ if (result.first != end)
+ {
+ if (result.second)
+ {
+ // Full match. We're done.
+ ec = boost::system::error_code();
+ return result.first - begin + delim.length();
+ }
+ else
+ {
+ // Partial match. Next search needs to start from beginning of match.
+ search_position = result.first - begin;
+ }
+ }
+ else
+ {
+ // No match. Next search can start with the new data.
+ search_position = end - begin;
+ }
+
+ // Check if buffer is full.
+ if (b.size() == b.max_size())
+ {
+ ec = error::not_found;
+ return 0;
+ }
+
+ // Need more data.
+ std::size_t bytes_to_read = read_size_helper(b, 65536);
+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));
+ if (ec)
+ return 0;
+ }
+}
+
+template <typename SyncReadStream, typename Allocator>
+inline std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s, b, expr, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename Allocator>
+std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
+ boost::system::error_code& ec)
+{
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = b.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ boost::match_results<iterator,
+ typename std::vector<boost::sub_match<iterator> >::allocator_type>
+ match_results;
+ if (regex_search(start, end, match_results, expr,
+ boost::match_default | boost::match_partial))
+ {
+ if (match_results[0].matched)
+ {
+ // Full match. We're done.
+ ec = boost::system::error_code();
+ return match_results[0].second - begin;
+ }
+ else
+ {
+ // Partial match. Next search needs to start from beginning of match.
+ search_position = match_results[0].first - begin;
+ }
+ }
+ else
+ {
+ // No match. Next search can start with the new data.
+ search_position = end - begin;
+ }
+
+ // Check if buffer is full.
+ if (b.size() == b.max_size())
+ {
+ ec = error::not_found;
+ return 0;
+ }
+
+ // Need more data.
+ std::size_t bytes_to_read = read_size_helper(b, 65536);
+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));
+ if (ec)
+ return 0;
+ }
+}
+
+template <typename SyncReadStream, typename Allocator, typename MatchCondition>
+std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ MatchCondition match_condition, boost::system::error_code& ec,
+ typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
+{
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = b.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = match_condition(start, end);
+ if (result.second)
+ {
+ // Full match. We're done.
+ ec = boost::system::error_code();
+ return result.first - begin;
+ }
+ else if (result.first != end)
+ {
+ // Partial match. Next search needs to start from beginning of match.
+ search_position = result.first - begin;
+ }
+ else
+ {
+ // No match. Next search can start with the new data.
+ search_position = end - begin;
+ }
+
+ // Check if buffer is full.
+ if (b.size() == b.max_size())
+ {
+ ec = error::not_found;
+ return 0;
+ }
+
+ // Need more data.
+ std::size_t bytes_to_read = read_size_helper(b, 65536);
+ b.commit(s.read_some(b.prepare(bytes_to_read), ec));
+ if (ec)
+ return 0;
+ }
+}
+
+template <typename SyncReadStream, typename Allocator, typename MatchCondition>
+inline std::size_t read_until(SyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,
+ typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s, b, match_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ class read_until_delim_op
+ {
+ public:
+ read_until_delim_op(AsyncReadStream& stream,
+ boost::asio::basic_streambuf<Allocator>& streambuf,
+ char delim, ReadHandler handler)
+ : stream_(stream),
+ streambuf_(streambuf),
+ delim_(delim),
+ search_position_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();
+ std::size_t bytes_to_read;
+ switch (start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = streambuf_.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position_;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ iterator iter = std::find(start, end, delim_);
+ if (iter != end)
+ {
+ // Found a match. We're done.
+ search_position_ = iter - begin + 1;
+ bytes_to_read = 0;
+ }
+
+ // No match yet. Check if buffer is full.
+ else if (streambuf_.size() == streambuf_.max_size())
+ {
+ search_position_ = not_found;
+ bytes_to_read = 0;
+ }
+
+ // Need to read some more data.
+ else
+ {
+ // Next search can start with the new data.
+ search_position_ = end - begin;
+ bytes_to_read = read_size_helper(streambuf_, 65536);
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read == 0)
+ break;
+
+ // Start a new asynchronous read operation to obtain more data.
+ stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this);
+ return; default:
+ streambuf_.commit(bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ handler_(search_position_ == not_found ? error::not_found : ec,
+ ec || search_position_ == not_found ? 0 : search_position_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ char delim_;
+ std::size_t search_position_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_delim_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_delim_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream, typename Allocator,
+ typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_delim_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+void async_read_until(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler)
+{
+ detail::read_until_delim_op<
+ AsyncReadStream, Allocator, ReadHandler>(
+ s, b, delim, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ class read_until_delim_string_op
+ {
+ public:
+ read_until_delim_string_op(AsyncReadStream& stream,
+ boost::asio::basic_streambuf<Allocator>& streambuf,
+ const std::string& delim, ReadHandler handler)
+ : stream_(stream),
+ streambuf_(streambuf),
+ delim_(delim),
+ search_position_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();
+ std::size_t bytes_to_read;
+ switch (start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = streambuf_.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position_;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = detail::partial_search(
+ start, end, delim_.begin(), delim_.end());
+ if (result.first != end && result.second)
+ {
+ // Full match. We're done.
+ search_position_ = result.first - begin + delim_.length();
+ bytes_to_read = 0;
+ }
+
+ // No match yet. Check if buffer is full.
+ else if (streambuf_.size() == streambuf_.max_size())
+ {
+ search_position_ = not_found;
+ bytes_to_read = 0;
+ }
+
+ // Need to read some more data.
+ else
+ {
+ if (result.first != end)
+ {
+ // Partial match. Next search needs to start from beginning of
+ // match.
+ search_position_ = result.first - begin;
+ }
+ else
+ {
+ // Next search can start with the new data.
+ search_position_ = end - begin;
+ }
+
+ bytes_to_read = read_size_helper(streambuf_, 65536);
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read == 0)
+ break;
+
+ // Start a new asynchronous read operation to obtain more data.
+ stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this);
+ return; default:
+ streambuf_.commit(bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ handler_(search_position_ == not_found ? error::not_found : ec,
+ ec || search_position_ == not_found ? 0 : search_position_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ std::string delim_;
+ std::size_t search_position_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_delim_string_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_delim_string_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename Allocator, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_delim_string_op<AsyncReadStream,
+ Allocator, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+void async_read_until(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const std::string& delim,
+ ReadHandler handler)
+{
+ detail::read_until_delim_string_op<
+ AsyncReadStream, Allocator, ReadHandler>(
+ s, b, delim, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename Allocator,
+ typename RegEx, typename ReadHandler>
+ class read_until_expr_op
+ {
+ public:
+ read_until_expr_op(AsyncReadStream& stream,
+ boost::asio::basic_streambuf<Allocator>& streambuf,
+ const boost::regex& expr, ReadHandler handler)
+ : stream_(stream),
+ streambuf_(streambuf),
+ expr_(expr),
+ search_position_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();
+ std::size_t bytes_to_read;
+ switch (start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = streambuf_.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position_;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ boost::match_results<iterator,
+ typename std::vector<boost::sub_match<iterator> >::allocator_type>
+ match_results;
+ bool match = regex_search(start, end, match_results, expr_,
+ boost::match_default | boost::match_partial);
+ if (match && match_results[0].matched)
+ {
+ // Full match. We're done.
+ search_position_ = match_results[0].second - begin;
+ bytes_to_read = 0;
+ }
+
+ // No match yet. Check if buffer is full.
+ else if (streambuf_.size() == streambuf_.max_size())
+ {
+ search_position_ = not_found;
+ bytes_to_read = 0;
+ }
+
+ // Need to read some more data.
+ else
+ {
+ if (match)
+ {
+ // Partial match. Next search needs to start from beginning of
+ // match.
+ search_position_ = match_results[0].first - begin;
+ }
+ else
+ {
+ // Next search can start with the new data.
+ search_position_ = end - begin;
+ }
+
+ bytes_to_read = read_size_helper(streambuf_, 65536);
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read == 0)
+ break;
+
+ // Start a new asynchronous read operation to obtain more data.
+ stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this);
+ return; default:
+ streambuf_.commit(bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ handler_(search_position_ == not_found ? error::not_found : ec,
+ ec || search_position_ == not_found ? 0 : search_position_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ RegEx expr_;
+ std::size_t search_position_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename RegEx, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_expr_op<AsyncReadStream,
+ Allocator, RegEx, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename RegEx, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_expr_op<AsyncReadStream,
+ Allocator, RegEx, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream, typename Allocator,
+ typename RegEx, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_expr_op<AsyncReadStream,
+ Allocator, RegEx, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
+void async_read_until(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
+ ReadHandler handler)
+{
+ detail::read_until_expr_op<AsyncReadStream,
+ Allocator, boost::regex, ReadHandler>(
+ s, b, expr, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename Allocator,
+ typename MatchCondition, typename ReadHandler>
+ class read_until_match_op
+ {
+ public:
+ read_until_match_op(AsyncReadStream& stream,
+ boost::asio::basic_streambuf<Allocator>& streambuf,
+ MatchCondition match_condition, ReadHandler handler)
+ : stream_(stream),
+ streambuf_(streambuf),
+ match_condition_(match_condition),
+ search_position_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();
+ std::size_t bytes_to_read;
+ switch (start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename boost::asio::basic_streambuf<
+ Allocator>::const_buffers_type const_buffers_type;
+ typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
+ const_buffers_type buffers = streambuf_.data();
+ iterator begin = iterator::begin(buffers);
+ iterator start = begin + search_position_;
+ iterator end = iterator::end(buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = match_condition_(start, end);
+ if (result.second)
+ {
+ // Full match. We're done.
+ search_position_ = result.first - begin;
+ bytes_to_read = 0;
+ }
+
+ // No match yet. Check if buffer is full.
+ else if (streambuf_.size() == streambuf_.max_size())
+ {
+ search_position_ = not_found;
+ bytes_to_read = 0;
+ }
+
+ // Need to read some more data.
+ else
+ {
+ if (result.first != end)
+ {
+ // Partial match. Next search needs to start from beginning of
+ // match.
+ search_position_ = result.first - begin;
+ }
+ else
+ {
+ // Next search can start with the new data.
+ search_position_ = end - begin;
+ }
+
+ bytes_to_read = read_size_helper(streambuf_, 65536);
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read == 0)
+ break;
+
+ // Start a new asynchronous read operation to obtain more data.
+ stream_.async_read_some(streambuf_.prepare(bytes_to_read), *this);
+ return; default:
+ streambuf_.commit(bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ handler_(search_position_ == not_found ? error::not_found : ec,
+ ec || search_position_ == not_found ? 0 : search_position_);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ MatchCondition match_condition_;
+ std::size_t search_position_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename MatchCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_match_op<AsyncReadStream,
+ Allocator, MatchCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename Allocator,
+ typename MatchCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_match_op<AsyncReadStream,
+ Allocator, MatchCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream, typename Allocator,
+ typename MatchCondition, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_match_op<AsyncReadStream,
+ Allocator, MatchCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncReadStream, typename Allocator,
+ typename MatchCondition, typename ReadHandler>
+void async_read_until(AsyncReadStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ MatchCondition match_condition, ReadHandler handler,
+ typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
+{
+ detail::read_until_match_op<
+ AsyncReadStream, Allocator, MatchCondition, ReadHandler>(
+ s, b, match_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_READ_UNTIL_HPP

Deleted: trunk/boost/asio/impl/read_until.ipp
==============================================================================
--- trunk/boost/asio/impl/read_until.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,989 +0,0 @@
-//
-// read_until.ipp
-// ~~~~~~~~~~~~~~
-//
-// 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_READ_UNTIL_IPP
-#define BOOST_ASIO_READ_UNTIL_IPP
-
-#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 <algorithm>
-#include <string>
-#include <utility>
-#include <boost/limits.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/buffer.hpp>
-#include <boost/asio/buffers_iterator.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-namespace boost {
-namespace asio {
-
-template <typename SyncReadStream, typename Allocator>
-inline std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, char delim)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_until(s, b, delim, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncReadStream, typename Allocator>
-std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, char delim,
- boost::system::error_code& ec)
-{
- std::size_t next_search_start = 0;
- for (;;)
- {
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- iterator iter = std::find(start, end, delim);
- if (iter != end)
- {
- // Found a match. We're done.
- ec = boost::system::error_code();
- return iter - begin + 1;
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- ec = error::not_found;
- return 0;
- }
-
- // Need more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- b.commit(s.read_some(b.prepare(bytes_available), ec));
- if (ec)
- return 0;
- }
-}
-
-template <typename SyncReadStream, typename Allocator>
-inline std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const std::string& delim)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_until(s, b, delim, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-namespace detail
-{
- // Algorithm that finds a subsequence of equal values in a sequence. Returns
- // (iterator,true) if a full match was found, in which case the iterator
- // points to the beginning of the match. Returns (iterator,false) if a
- // partial match was found at the end of the first sequence, in which case
- // the iterator points to the beginning of the partial match. Returns
- // (last1,false) if no full or partial match was found.
- template <typename Iterator1, typename Iterator2>
- std::pair<Iterator1, bool> partial_search(
- Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
- {
- for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)
- {
- Iterator1 test_iter1 = iter1;
- Iterator2 test_iter2 = first2;
- for (;; ++test_iter1, ++test_iter2)
- {
- if (test_iter2 == last2)
- return std::make_pair(iter1, true);
- if (test_iter1 == last1)
- {
- if (test_iter2 != first2)
- return std::make_pair(iter1, false);
- else
- break;
- }
- if (*test_iter1 != *test_iter2)
- break;
- }
- }
- return std::make_pair(last1, false);
- }
-} // namespace detail
-
-template <typename SyncReadStream, typename Allocator>
-std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const std::string& delim,
- boost::system::error_code& ec)
-{
- std::size_t next_search_start = 0;
- for (;;)
- {
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::pair<iterator, bool> result = boost::asio::detail::partial_search(
- start, end, delim.begin(), delim.end());
- if (result.first != end)
- {
- if (result.second)
- {
- // Full match. We're done.
- ec = boost::system::error_code();
- return result.first - begin + delim.length();
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = result.first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- ec = error::not_found;
- return 0;
- }
-
- // Need more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- b.commit(s.read_some(b.prepare(bytes_available), ec));
- if (ec)
- return 0;
- }
-}
-
-template <typename SyncReadStream, typename Allocator>
-inline std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_until(s, b, expr, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncReadStream, typename Allocator>
-std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
- boost::system::error_code& ec)
-{
- std::size_t next_search_start = 0;
- for (;;)
- {
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- boost::match_results<iterator> match_results;
- if (boost::regex_search(start, end, match_results, expr,
- boost::match_default | boost::match_partial))
- {
- if (match_results[0].matched)
- {
- // Full match. We're done.
- ec = boost::system::error_code();
- return match_results[0].second - begin;
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = match_results[0].first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- ec = error::not_found;
- return 0;
- }
-
- // Need more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- b.commit(s.read_some(b.prepare(bytes_available), ec));
- if (ec)
- return 0;
- }
-}
-
-template <typename SyncReadStream, typename Allocator, typename MatchCondition>
-std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- MatchCondition match_condition, boost::system::error_code& ec,
- typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
-{
- std::size_t next_search_start = 0;
- for (;;)
- {
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::pair<iterator, bool> result = match_condition(start, end);
- if (result.second)
- {
- // Full match. We're done.
- ec = boost::system::error_code();
- return result.first - begin;
- }
- else if (result.first != end)
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = result.first - begin;
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- ec = error::not_found;
- return 0;
- }
-
- // Need more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- b.commit(s.read_some(b.prepare(bytes_available), ec));
- if (ec)
- return 0;
- }
-}
-
-template <typename SyncReadStream, typename Allocator, typename MatchCondition>
-inline std::size_t read_until(SyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, MatchCondition match_condition,
- typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = read_until(s, b, match_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-namespace detail
-{
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- class read_until_delim_handler
- {
- public:
- read_until_delim_handler(AsyncReadStream& stream,
- boost::asio::basic_streambuf<Allocator>& streambuf, char delim,
- std::size_t next_search_start, ReadHandler handler)
- : stream_(stream),
- streambuf_(streambuf),
- delim_(delim),
- next_search_start_(next_search_start),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- // Check for errors.
- if (ec)
- {
- std::size_t bytes = 0;
- handler_(ec, bytes);
- return;
- }
-
- // Commit received data to streambuf's get area.
- streambuf_.commit(bytes_transferred);
-
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = streambuf_.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start_;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- iterator iter = std::find(start, end, delim_);
- if (iter != end)
- {
- // Found a match. We're done.
- std::size_t bytes = iter - begin + 1;
- handler_(ec, bytes);
- return;
- }
-
- // No match. Check if buffer is full.
- if (streambuf_.size() == streambuf_.max_size())
- {
- std::size_t bytes = 0;
- boost::system::error_code ec(error::not_found);
- handler_(ec, bytes);
- return;
- }
-
- // Next search can start with the new data.
- next_search_start_ = end - begin;
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
- stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
- }
-
- //private:
- AsyncReadStream& stream_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- char delim_;
- std::size_t next_search_start_;
- ReadHandler handler_;
- };
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_until_delim_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_delim_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream, typename Allocator,
- typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_until_delim_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-void async_read_until(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, char delim, ReadHandler handler)
-{
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- iterator iter = std::find(begin, end, delim);
- if (iter != end)
- {
- // Found a match. We're done.
- boost::system::error_code ec;
- std::size_t bytes = iter - begin + 1;
- s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
- return;
- }
-
- // No match. Check if buffer is full.
- if (b.size() == b.max_size())
- {
- boost::system::error_code ec(error::not_found);
- s.get_io_service().post(detail::bind_handler(handler, ec, 0));
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- s.async_read_some(b.prepare(bytes_available),
- detail::read_until_delim_handler<AsyncReadStream, Allocator, ReadHandler>(
- s, b, delim, end - begin, handler));
-}
-
-namespace detail
-{
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- class read_until_delim_string_handler
- {
- public:
- read_until_delim_string_handler(AsyncReadStream& stream,
- boost::asio::basic_streambuf<Allocator>& streambuf,
- const std::string& delim, std::size_t next_search_start,
- ReadHandler handler)
- : stream_(stream),
- streambuf_(streambuf),
- delim_(delim),
- next_search_start_(next_search_start),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- // Check for errors.
- if (ec)
- {
- std::size_t bytes = 0;
- handler_(ec, bytes);
- return;
- }
-
- // Commit received data to streambuf's get area.
- streambuf_.commit(bytes_transferred);
-
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = streambuf_.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start_;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::pair<iterator, bool> result = boost::asio::detail::partial_search(
- start, end, delim_.begin(), delim_.end());
- if (result.first != end)
- {
- if (result.second)
- {
- // Full match. We're done.
- std::size_t bytes = result.first - begin + delim_.length();
- handler_(ec, bytes);
- return;
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start_ = result.first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start_ = end - begin;
- }
-
- // Check if buffer is full.
- if (streambuf_.size() == streambuf_.max_size())
- {
- std::size_t bytes = 0;
- boost::system::error_code ec2(error::not_found);
- handler_(ec2, bytes);
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
- stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
- }
-
- //private:
- AsyncReadStream& stream_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- std::string delim_;
- std::size_t next_search_start_;
- ReadHandler handler_;
- };
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_until_delim_string_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_delim_string_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream,
- typename Allocator, typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_until_delim_string_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-void async_read_until(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const std::string& delim,
- ReadHandler handler)
-{
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::size_t next_search_start;
- std::pair<iterator, bool> result = boost::asio::detail::partial_search(
- begin, end, delim.begin(), delim.end());
- if (result.first != end)
- {
- if (result.second)
- {
- // Full match. We're done.
- boost::system::error_code ec;
- std::size_t bytes = result.first - begin + delim.length();
- s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
- return;
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = result.first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- boost::system::error_code ec(error::not_found);
- s.get_io_service().post(detail::bind_handler(handler, ec, 0));
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- s.async_read_some(b.prepare(bytes_available),
- detail::read_until_delim_string_handler<
- AsyncReadStream, Allocator, ReadHandler>(
- s, b, delim, next_search_start, handler));
-}
-
-namespace detail
-{
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- class read_until_expr_handler
- {
- public:
- read_until_expr_handler(AsyncReadStream& stream,
- boost::asio::basic_streambuf<Allocator>& streambuf,
- const boost::regex& expr, std::size_t next_search_start,
- ReadHandler handler)
- : stream_(stream),
- streambuf_(streambuf),
- expr_(expr),
- next_search_start_(next_search_start),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- // Check for errors.
- if (ec)
- {
- std::size_t bytes = 0;
- handler_(ec, bytes);
- return;
- }
-
- // Commit received data to streambuf's get area.
- streambuf_.commit(bytes_transferred);
-
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = streambuf_.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start_;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- boost::match_results<iterator> match_results;
- if (boost::regex_search(start, end, match_results, expr_,
- boost::match_default | boost::match_partial))
- {
- if (match_results[0].matched)
- {
- // Full match. We're done.
- std::size_t bytes = match_results[0].second - begin;
- handler_(ec, bytes);
- return;
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start_ = match_results[0].first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start_ = end - begin;
- }
-
- // Check if buffer is full.
- if (streambuf_.size() == streambuf_.max_size())
- {
- std::size_t bytes = 0;
- boost::system::error_code ec(error::not_found);
- handler_(ec, bytes);
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
- stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
- }
-
- //private:
- AsyncReadStream& stream_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- boost::regex expr_;
- std::size_t next_search_start_;
- ReadHandler handler_;
- };
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_until_expr_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_expr_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream, typename Allocator,
- typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_until_expr_handler<AsyncReadStream,
- Allocator, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename Allocator, typename ReadHandler>
-void async_read_until(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b, const boost::regex& expr,
- ReadHandler handler)
-{
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::size_t next_search_start;
- boost::match_results<iterator> match_results;
- if (boost::regex_search(begin, end, match_results, expr,
- boost::match_default | boost::match_partial))
- {
- if (match_results[0].matched)
- {
- // Full match. We're done.
- boost::system::error_code ec;
- std::size_t bytes = match_results[0].second - begin;
- s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
- return;
- }
- else
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = match_results[0].first - begin;
- }
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- boost::system::error_code ec(error::not_found);
- s.get_io_service().post(detail::bind_handler(handler, ec, 0));
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- s.async_read_some(b.prepare(bytes_available),
- detail::read_until_expr_handler<AsyncReadStream, Allocator, ReadHandler>(
- s, b, expr, next_search_start, handler));
-}
-
-namespace detail
-{
- template <typename AsyncReadStream, typename Allocator,
- typename MatchCondition, typename ReadHandler>
- class read_until_match_handler
- {
- public:
- read_until_match_handler(AsyncReadStream& stream,
- boost::asio::basic_streambuf<Allocator>& streambuf,
- MatchCondition match_condition, std::size_t next_search_start,
- ReadHandler handler)
- : stream_(stream),
- streambuf_(streambuf),
- match_condition_(match_condition),
- next_search_start_(next_search_start),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- // Check for errors.
- if (ec)
- {
- std::size_t bytes = 0;
- handler_(ec, bytes);
- return;
- }
-
- // Commit received data to streambuf's get area.
- streambuf_.commit(bytes_transferred);
-
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = streambuf_.data();
- iterator begin = iterator::begin(buffers);
- iterator start = begin + next_search_start_;
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::pair<iterator, bool> result = match_condition_(start, end);
- if (result.second)
- {
- // Full match. We're done.
- std::size_t bytes = result.first - begin;
- handler_(ec, bytes);
- return;
- }
- else if (result.first != end)
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start_ = result.first - begin;
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start_ = end - begin;
- }
-
- // Check if buffer is full.
- if (streambuf_.size() == streambuf_.max_size())
- {
- std::size_t bytes = 0;
- boost::system::error_code ec(error::not_found);
- handler_(ec, bytes);
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, streambuf_.max_size() - streambuf_.size());
- stream_.async_read_some(streambuf_.prepare(bytes_available), *this);
- }
-
- //private:
- AsyncReadStream& stream_;
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- MatchCondition match_condition_;
- std::size_t next_search_start_;
- ReadHandler handler_;
- };
-
- template <typename AsyncReadStream, typename Allocator,
- typename MatchCondition, typename ReadHandler>
- inline void* asio_handler_allocate(std::size_t size,
- read_until_match_handler<AsyncReadStream,
- Allocator, MatchCondition, ReadHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncReadStream, typename Allocator,
- typename MatchCondition, typename ReadHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_match_handler<AsyncReadStream,
- Allocator, MatchCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncReadStream, typename Allocator,
- typename MatchCondition, typename ReadHandler>
- inline void asio_handler_invoke(const Function& function,
- read_until_match_handler<AsyncReadStream,
- Allocator, MatchCondition, ReadHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncReadStream, typename Allocator,
- typename MatchCondition, typename ReadHandler>
-void async_read_until(AsyncReadStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- MatchCondition match_condition, ReadHandler handler,
- typename boost::enable_if<is_match_condition<MatchCondition> >::type*)
-{
- // Determine the range of the data to be searched.
- typedef typename boost::asio::basic_streambuf<
- Allocator>::const_buffers_type const_buffers_type;
- typedef boost::asio::buffers_iterator<const_buffers_type> iterator;
- const_buffers_type buffers = b.data();
- iterator begin = iterator::begin(buffers);
- iterator end = iterator::end(buffers);
-
- // Look for a match.
- std::size_t next_search_start;
- std::pair<iterator, bool> result = match_condition(begin, end);
- if (result.second)
- {
- // Full match. We're done.
- boost::system::error_code ec;
- std::size_t bytes = result.first - begin;
- s.get_io_service().post(detail::bind_handler(handler, ec, bytes));
- return;
- }
- else if (result.first != end)
- {
- // Partial match. Next search needs to start from beginning of match.
- next_search_start = result.first - begin;
- }
- else
- {
- // No match. Next search can start with the new data.
- next_search_start = end - begin;
- }
-
- // Check if buffer is full.
- if (b.size() == b.max_size())
- {
- boost::system::error_code ec(error::not_found);
- s.get_io_service().post(detail::bind_handler(handler, ec, 0));
- return;
- }
-
- // Start a new asynchronous read operation to obtain more data.
- std::size_t bytes_available =
- std::min<std::size_t>(512, b.max_size() - b.size());
- s.async_read_some(b.prepare(bytes_available),
- detail::read_until_match_handler<
- AsyncReadStream, Allocator, MatchCondition, ReadHandler>(
- s, b, match_condition, next_search_start, handler));
-}
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_READ_UNTIL_IPP

Added: trunk/boost/asio/impl/serial_port_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/serial_port_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,61 @@
+//
+// impl/serial_port_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
+//
+// 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_IMPL_SERIAL_PORT_BASE_HPP
+#define BOOST_ASIO_IMPL_SERIAL_PORT_BASE_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 {
+
+inline serial_port_base::baud_rate::baud_rate(unsigned int rate)
+ : value_(rate)
+{
+}
+
+inline unsigned int serial_port_base::baud_rate::value() const
+{
+ return value_;
+}
+
+inline serial_port_base::flow_control::type
+serial_port_base::flow_control::value() const
+{
+ return value_;
+}
+
+inline serial_port_base::parity::type serial_port_base::parity::value() const
+{
+ return value_;
+}
+
+inline serial_port_base::stop_bits::type
+serial_port_base::stop_bits::value() const
+{
+ return value_;
+}
+
+inline unsigned int serial_port_base::character_size::value() const
+{
+ return value_;
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_SERIAL_PORT_BASE_HPP

Modified: trunk/boost/asio/impl/serial_port_base.ipp
==============================================================================
--- trunk/boost/asio/impl/serial_port_base.ipp (original)
+++ trunk/boost/asio/impl/serial_port_base.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// serial_port_base.ipp
-// ~~~~~~~~~~~~~~~~~~~~
+// impl/serial_port_base.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Copyright (c) 2008 Rep Invariant Systems, Inc. (info_at_[hidden])
@@ -9,33 +9,36 @@
 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 //
 
-#ifndef BOOST_ASIO_SERIAL_PORT_BASE_IPP
-#define BOOST_ASIO_SERIAL_PORT_BASE_IPP
+#ifndef BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP
+#define BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP
 
 #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/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+#include <stdexcept>
 #include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/serial_port_base.hpp>
 
-namespace boost {
-namespace asio {
+#if defined(GENERATING_DOCUMENTATION)
+# define BOOST_ASIO_OPTION_STORAGE implementation_defined
+#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# define BOOST_ASIO_OPTION_STORAGE DCB
+#else
+# define BOOST_ASIO_OPTION_STORAGE termios
+#endif
 
-inline serial_port_base::baud_rate::baud_rate(unsigned int rate)
- : value_(rate)
-{
-}
+#include <boost/asio/detail/push_options.hpp>
 
-inline unsigned int serial_port_base::baud_rate::value() const
-{
- return value_;
-}
+namespace boost {
+namespace asio {
 
-inline boost::system::error_code serial_port_base::baud_rate::store(
+boost::system::error_code serial_port_base::baud_rate::store(
     BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -123,7 +126,7 @@
   return ec;
 }
 
-inline boost::system::error_code serial_port_base::baud_rate::load(
+boost::system::error_code serial_port_base::baud_rate::load(
     const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -205,7 +208,7 @@
   return ec;
 }
 
-inline serial_port_base::flow_control::flow_control(
+serial_port_base::flow_control::flow_control(
     serial_port_base::flow_control::type t)
   : value_(t)
 {
@@ -216,13 +219,7 @@
   }
 }
 
-inline serial_port_base::flow_control::type
-serial_port_base::flow_control::value() const
-{
- return value_;
-}
-
-inline boost::system::error_code serial_port_base::flow_control::store(
+boost::system::error_code serial_port_base::flow_control::store(
     BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -281,7 +278,7 @@
   return ec;
 }
 
-inline boost::system::error_code serial_port_base::flow_control::load(
+boost::system::error_code serial_port_base::flow_control::load(
     const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -317,7 +314,7 @@
   return ec;
 }
 
-inline serial_port_base::parity::parity(serial_port_base::parity::type t)
+serial_port_base::parity::parity(serial_port_base::parity::type t)
   : value_(t)
 {
   if (t != none && t != odd && t != even)
@@ -327,12 +324,7 @@
   }
 }
 
-inline serial_port_base::parity::type serial_port_base::parity::value() const
-{
- return value_;
-}
-
-inline boost::system::error_code serial_port_base::parity::store(
+boost::system::error_code serial_port_base::parity::store(
     BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -379,7 +371,7 @@
   return ec;
 }
 
-inline boost::system::error_code serial_port_base::parity::load(
+boost::system::error_code serial_port_base::parity::load(
     const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -416,7 +408,7 @@
   return ec;
 }
 
-inline serial_port_base::stop_bits::stop_bits(
+serial_port_base::stop_bits::stop_bits(
     serial_port_base::stop_bits::type t)
   : value_(t)
 {
@@ -427,13 +419,7 @@
   }
 }
 
-inline serial_port_base::stop_bits::type
-serial_port_base::stop_bits::value() const
-{
- return value_;
-}
-
-inline boost::system::error_code serial_port_base::stop_bits::store(
+boost::system::error_code serial_port_base::stop_bits::store(
     BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -469,7 +455,7 @@
   return ec;
 }
 
-inline boost::system::error_code serial_port_base::stop_bits::load(
+boost::system::error_code serial_port_base::stop_bits::load(
     const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -496,7 +482,7 @@
   return ec;
 }
 
-inline serial_port_base::character_size::character_size(unsigned int t)
+serial_port_base::character_size::character_size(unsigned int t)
   : value_(t)
 {
   if (t < 5 || t > 8)
@@ -506,12 +492,7 @@
   }
 }
 
-inline unsigned int serial_port_base::character_size::value() const
-{
- return value_;
-}
-
-inline boost::system::error_code serial_port_base::character_size::store(
+boost::system::error_code serial_port_base::character_size::store(
     BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec) const
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -531,7 +512,7 @@
   return ec;
 }
 
-inline boost::system::error_code serial_port_base::character_size::load(
+boost::system::error_code serial_port_base::character_size::load(
     const BOOST_ASIO_OPTION_STORAGE& storage, boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
@@ -556,4 +537,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
-#endif // BOOST_ASIO_SERIAL_PORT_BASE_IPP
+#undef BOOST_ASIO_OPTION_STORAGE
+
+#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
+
+#endif // BOOST_ASIO_IMPL_SERIAL_PORT_BASE_IPP

Added: trunk/boost/asio/impl/src.cpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/src.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,59 @@
+//
+// impl/src.cpp
+// ~~~~~~~~~~~~
+//
+// 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)
+//
+
+#define BOOST_ASIO_SOURCE
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# error Do not compile Asio library source with BOOST_ASIO_HEADER_ONLY defined
+#endif
+
+#include <boost/asio/impl/error.ipp>
+#include <boost/asio/impl/io_service.ipp>
+#include <boost/asio/impl/serial_port_base.ipp>
+#include <boost/asio/detail/impl/descriptor_ops.ipp>
+#include <boost/asio/detail/impl/dev_poll_reactor.ipp>
+#include <boost/asio/detail/impl/epoll_reactor.ipp>
+#include <boost/asio/detail/impl/eventfd_select_interrupter.ipp>
+#include <boost/asio/detail/impl/kqueue_reactor.ipp>
+#include <boost/asio/detail/impl/pipe_select_interrupter.ipp>
+#include <boost/asio/detail/impl/posix_event.ipp>
+#include <boost/asio/detail/impl/posix_mutex.ipp>
+#include <boost/asio/detail/impl/posix_thread.ipp>
+#include <boost/asio/detail/impl/posix_tss_ptr.ipp>
+#include <boost/asio/detail/impl/reactive_descriptor_service.ipp>
+#include <boost/asio/detail/impl/reactive_serial_port_service.ipp>
+#include <boost/asio/detail/impl/reactive_socket_service_base.ipp>
+#include <boost/asio/detail/impl/resolver_service_base.ipp>
+#include <boost/asio/detail/impl/select_reactor.ipp>
+#include <boost/asio/detail/impl/service_registry.ipp>
+#include <boost/asio/detail/impl/socket_ops.ipp>
+#include <boost/asio/detail/impl/socket_select_interrupter.ipp>
+#include <boost/asio/detail/impl/strand_service.ipp>
+#include <boost/asio/detail/impl/task_io_service.ipp>
+#include <boost/asio/detail/impl/throw_error.ipp>
+#include <boost/asio/detail/impl/timer_queue.ipp>
+#include <boost/asio/detail/impl/timer_queue_set.ipp>
+#include <boost/asio/detail/impl/win_iocp_handle_service.ipp>
+#include <boost/asio/detail/impl/win_iocp_io_service.ipp>
+#include <boost/asio/detail/impl/win_iocp_serial_port_service.ipp>
+#include <boost/asio/detail/impl/win_iocp_socket_service_base.ipp>
+#include <boost/asio/detail/impl/win_event.ipp>
+#include <boost/asio/detail/impl/win_mutex.ipp>
+#include <boost/asio/detail/impl/win_thread.ipp>
+#include <boost/asio/detail/impl/win_tss_ptr.ipp>
+#include <boost/asio/detail/impl/winsock_init.ipp>
+#include <boost/asio/ip/impl/address.ipp>
+#include <boost/asio/ip/impl/address_v4.ipp>
+#include <boost/asio/ip/impl/address_v6.ipp>
+#include <boost/asio/ip/impl/host_name.ipp>
+#include <boost/asio/ip/detail/impl/endpoint.ipp>
+#include <boost/asio/local/detail/impl/endpoint.ipp>

Added: trunk/boost/asio/impl/write.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/write.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,398 @@
+//
+// impl/write.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_IMPL_WRITE_HPP
+#define BOOST_ASIO_IMPL_WRITE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#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>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition>
+std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ boost::asio::detail::consuming_buffers<
+ const_buffer, ConstBufferSequence> tmp(buffers);
+ std::size_t total_transferred = 0;
+ 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.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ }
+ return total_transferred;
+}
+
+template <typename SyncWriteStream, typename ConstBufferSequence>
+inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition>
+inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+template <typename SyncWriteStream, typename Allocator,
+ typename CompletionCondition>
+std::size_t write(SyncWriteStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
+ b.consume(bytes_transferred);
+ return bytes_transferred;
+}
+
+template <typename SyncWriteStream, typename Allocator>
+inline std::size_t write(SyncWriteStream& s,
+ boost::asio::basic_streambuf<Allocator>& b)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s, b, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncWriteStream, typename Allocator,
+ typename CompletionCondition>
+inline std::size_t write(SyncWriteStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s, b, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ class write_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, WriteHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ stream_(stream),
+ buffers_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ switch (start)
+ {
+ case 1:
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ for (;;)
+ {
+ stream_.async_write_some(buffers_, *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ buffers_.consume(bytes_transferred);
+ buffers_.prepare(this->check_for_completion(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_;
+ };
+
+ 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)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(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_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncWriteStream& stream_;
+ boost::asio::mutable_buffer buffer_;
+ std::size_t total_transferred_;
+ WriteHandler handler_;
+ };
+
+ 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)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(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_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncWriteStream& stream_;
+ boost::asio::const_buffer buffer_;
+ std::size_t total_transferred_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ write_op<AsyncWriteStream, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ write_op<AsyncWriteStream, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncWriteStream,
+ typename ConstBufferSequence, typename CompletionCondition,
+ typename WriteHandler>
+ inline void asio_handler_invoke(const Function& function,
+ write_op<AsyncWriteStream, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncWriteStream, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, WriteHandler handler)
+{
+ detail::write_op<AsyncWriteStream, ConstBufferSequence,
+ CompletionCondition, WriteHandler>(
+ s, buffers, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncWriteStream, typename ConstBufferSequence,
+ typename WriteHandler>
+inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
+ WriteHandler handler)
+{
+ async_write(s, buffers, transfer_all(), handler);
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncWriteStream, typename Allocator,
+ typename WriteHandler>
+ class write_streambuf_handler
+ {
+ public:
+ write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf,
+ WriteHandler handler)
+ : streambuf_(streambuf),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ streambuf_.consume(bytes_transferred);
+ handler_(ec, bytes_transferred);
+ }
+
+ //private:
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncWriteStream, typename Allocator,
+ typename WriteHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ write_streambuf_handler<AsyncWriteStream,
+ Allocator, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncWriteStream, typename Allocator,
+ typename WriteHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ write_streambuf_handler<AsyncWriteStream,
+ Allocator, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncWriteStream, typename Allocator,
+ typename WriteHandler>
+ inline void asio_handler_invoke(const Function& function,
+ write_streambuf_handler<AsyncWriteStream,
+ Allocator, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncWriteStream, typename Allocator,
+ typename CompletionCondition, typename WriteHandler>
+inline void async_write(AsyncWriteStream& s,
+ boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, WriteHandler handler)
+{
+ async_write(s, b.data(), completion_condition,
+ detail::write_streambuf_handler<
+ AsyncWriteStream, Allocator, WriteHandler>(b, handler));
+}
+
+template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
+inline void async_write(AsyncWriteStream& s,
+ boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
+{
+ async_write(s, b, transfer_all(), handler);
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_WRITE_HPP

Deleted: trunk/boost/asio/impl/write.ipp
==============================================================================
--- trunk/boost/asio/impl/write.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,404 +0,0 @@
-//
-// write.ipp
-// ~~~~~~~~~
-//
-// 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_WRITE_IPP
-#define BOOST_ASIO_WRITE_IPP
-
-#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>
-#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>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-namespace boost {
-namespace asio {
-
-template <typename SyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition>
-std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- ec = boost::system::error_code();
- boost::asio::detail::consuming_buffers<
- const_buffer, ConstBufferSequence> tmp(buffers);
- std::size_t total_transferred = 0;
- 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.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- }
- return total_transferred;
-}
-
-template <typename SyncWriteStream, typename ConstBufferSequence>
-inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write(s, buffers, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition>
-inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-template <typename SyncWriteStream, typename Allocator,
- typename CompletionCondition>
-std::size_t write(SyncWriteStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
- b.consume(bytes_transferred);
- return bytes_transferred;
-}
-
-template <typename SyncWriteStream, typename Allocator>
-inline std::size_t write(SyncWriteStream& s,
- boost::asio::basic_streambuf<Allocator>& b)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write(s, b, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncWriteStream, typename Allocator,
- typename CompletionCondition>
-inline std::size_t write(SyncWriteStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write(s, b, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- class write_op
- : detail::base_from_completion_cond<CompletionCondition>
- {
- public:
- write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, WriteHandler handler)
- : detail::base_from_completion_cond<
- CompletionCondition>(completion_condition),
- stream_(stream),
- buffers_(buffers),
- total_transferred_(0),
- 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)
- {
- 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_);
- }
- }
-
- //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_)
- {
- 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_;
- boost::asio::const_buffer buffer_;
- std::size_t total_transferred_;
- WriteHandler handler_;
- bool start_;
- };
-
- template <typename AsyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- inline void* asio_handler_allocate(std::size_t size,
- write_op<AsyncWriteStream, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- write_op<AsyncWriteStream, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncWriteStream,
- typename ConstBufferSequence, typename CompletionCondition,
- typename WriteHandler>
- inline void asio_handler_invoke(const Function& function,
- write_op<AsyncWriteStream, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncWriteStream, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
-inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, WriteHandler handler)
-{
- detail::write_op<AsyncWriteStream, ConstBufferSequence,
- CompletionCondition, WriteHandler>(
- s, buffers, completion_condition, handler)(
- boost::system::error_code(), 0);
-}
-
-template <typename AsyncWriteStream, typename ConstBufferSequence,
- typename WriteHandler>
-inline void async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
- WriteHandler handler)
-{
- async_write(s, buffers, transfer_all(), handler);
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncWriteStream, typename Allocator,
- typename WriteHandler>
- class write_streambuf_handler
- {
- public:
- write_streambuf_handler(boost::asio::basic_streambuf<Allocator>& streambuf,
- WriteHandler handler)
- : streambuf_(streambuf),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- streambuf_.consume(bytes_transferred);
- handler_(ec, bytes_transferred);
- }
-
- //private:
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- WriteHandler handler_;
- };
-
- template <typename AsyncWriteStream, typename Allocator,
- typename WriteHandler>
- inline void* asio_handler_allocate(std::size_t size,
- write_streambuf_handler<AsyncWriteStream,
- Allocator, WriteHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncWriteStream, typename Allocator,
- typename WriteHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- write_streambuf_handler<AsyncWriteStream,
- Allocator, WriteHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncWriteStream, typename Allocator,
- typename WriteHandler>
- inline void asio_handler_invoke(const Function& function,
- write_streambuf_handler<AsyncWriteStream,
- Allocator, WriteHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncWriteStream, typename Allocator,
- typename CompletionCondition, typename WriteHandler>
-inline void async_write(AsyncWriteStream& s,
- boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, WriteHandler handler)
-{
- async_write(s, b.data(), completion_condition,
- detail::write_streambuf_handler<
- AsyncWriteStream, Allocator, WriteHandler>(b, handler));
-}
-
-template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
-inline void async_write(AsyncWriteStream& s,
- boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
-{
- async_write(s, b, transfer_all(), handler);
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_WRITE_IPP

Added: trunk/boost/asio/impl/write_at.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/impl/write_at.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,419 @@
+//
+// impl/write_at.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_IMPL_WRITE_AT_HPP
+#define BOOST_ASIO_IMPL_WRITE_AT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#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>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ ec = boost::system::error_code();
+ boost::asio::detail::consuming_buffers<
+ const_buffer, ConstBufferSequence> tmp(buffers);
+ std::size_t total_transferred = 0;
+ tmp.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ while (tmp.begin() != tmp.end())
+ {
+ std::size_t bytes_transferred = d.write_some_at(
+ offset + total_transferred, tmp, ec);
+ tmp.consume(bytes_transferred);
+ total_transferred += bytes_transferred;
+ tmp.prepare(detail::adapt_completion_condition_result(
+ completion_condition(ec, total_transferred)));
+ }
+ return total_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, const ConstBufferSequence& buffers)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write_at(
+ d, offset, buffers, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write_at(
+ d, offset, buffers, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+ typename CompletionCondition>
+std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, boost::system::error_code& ec)
+{
+ std::size_t bytes_transferred = write_at(
+ d, offset, b.data(), completion_condition, ec);
+ b.consume(bytes_transferred);
+ return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+template <typename SyncRandomAccessWriteDevice, typename Allocator,
+ typename CompletionCondition>
+inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write_at(
+ d, offset, b, completion_condition, ec);
+ boost::asio::detail::throw_error(ec);
+ return bytes_transferred;
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ class write_at_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ write_at_op(AsyncRandomAccessWriteDevice& device,
+ boost::uint64_t offset, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, WriteHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ buffers_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ switch (start)
+ {
+ case 1:
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ for (;;)
+ {
+ device_.async_write_some_at(
+ offset_ + total_transferred_, buffers_, *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ buffers_.consume(bytes_transferred);
+ buffers_.prepare(this->check_for_completion(ec, total_transferred_));
+ if ((!ec && bytes_transferred == 0)
+ || buffers_.begin() == buffers_.end())
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessWriteDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::detail::consuming_buffers<
+ const_buffer, ConstBufferSequence> buffers_;
+ std::size_t total_transferred_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessWriteDevice,
+ typename CompletionCondition, typename WriteHandler>
+ class write_at_op<AsyncRandomAccessWriteDevice,
+ boost::asio::mutable_buffers_1, CompletionCondition, WriteHandler>
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ write_at_op(AsyncRandomAccessWriteDevice& device,
+ boost::uint64_t offset, const boost::asio::mutable_buffers_1& buffers,
+ CompletionCondition completion_condition,
+ WriteHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ buffer_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(ec, total_transferred_);
+ for (;;)
+ {
+ device_.async_write_some_at(offset_ + total_transferred_,
+ boost::asio::buffer(buffer_ + total_transferred_, n), *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ if ((!ec && bytes_transferred == 0)
+ || (n = this->check_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessWriteDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::mutable_buffer buffer_;
+ std::size_t total_transferred_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessWriteDevice,
+ typename CompletionCondition, typename WriteHandler>
+ class write_at_op<AsyncRandomAccessWriteDevice, boost::asio::const_buffers_1,
+ CompletionCondition, WriteHandler>
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ write_at_op(AsyncRandomAccessWriteDevice& device,
+ boost::uint64_t offset, const boost::asio::const_buffers_1& buffers,
+ CompletionCondition completion_condition,
+ WriteHandler handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ device_(device),
+ offset_(offset),
+ buffer_(buffers),
+ total_transferred_(0),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t n = 0;
+ switch (start)
+ {
+ case 1:
+ n = this->check_for_completion(ec, total_transferred_);
+ for (;;)
+ {
+ device_.async_write_some_at(offset_ + total_transferred_,
+ boost::asio::buffer(buffer_ + total_transferred_, n), *this);
+ return; default:
+ total_transferred_ += bytes_transferred;
+ if ((!ec && bytes_transferred == 0)
+ || (n = this->check_for_completion(ec, total_transferred_)) == 0
+ || total_transferred_ == boost::asio::buffer_size(buffer_))
+ break;
+ }
+
+ handler_(ec, total_transferred_);
+ }
+ }
+
+ //private:
+ AsyncRandomAccessWriteDevice& device_;
+ boost::uint64_t offset_;
+ boost::asio::const_buffer buffer_;
+ std::size_t total_transferred_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncRandomAccessWriteDevice,
+ typename ConstBufferSequence, typename CompletionCondition,
+ typename WriteHandler>
+ inline void asio_handler_invoke(const Function& function,
+ write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename CompletionCondition, typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, const ConstBufferSequence& buffers,
+ CompletionCondition completion_condition, WriteHandler handler)
+{
+ detail::write_at_op<AsyncRandomAccessWriteDevice,
+ ConstBufferSequence, CompletionCondition, WriteHandler>(
+ d, offset, buffers, completion_condition, handler)(
+ boost::system::error_code(), 0, 1);
+}
+
+template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
+ typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, const ConstBufferSequence& buffers,
+ WriteHandler handler)
+{
+ async_write_at(d, offset, buffers, transfer_all(), handler);
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+namespace detail
+{
+ template <typename AsyncRandomAccessWriteDevice,
+ typename Allocator, typename WriteHandler>
+ class write_at_streambuf_op
+ {
+ public:
+ write_at_streambuf_op(
+ boost::asio::basic_streambuf<Allocator>& streambuf,
+ WriteHandler handler)
+ : streambuf_(streambuf),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ streambuf_.consume(bytes_transferred);
+ handler_(ec, bytes_transferred);
+ }
+
+ //private:
+ boost::asio::basic_streambuf<Allocator>& streambuf_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+ typename WriteHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ write_at_streambuf_op<AsyncRandomAccessWriteDevice,
+ Allocator, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+ typename WriteHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ write_at_streambuf_op<AsyncRandomAccessWriteDevice,
+ Allocator, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncRandomAccessWriteDevice,
+ typename Allocator, typename WriteHandler>
+ inline void asio_handler_invoke(const Function& function,
+ write_at_streambuf_op<AsyncRandomAccessWriteDevice,
+ Allocator, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+} // namespace detail
+
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+ typename CompletionCondition, typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ CompletionCondition completion_condition, WriteHandler handler)
+{
+ async_write_at(d, offset, b.data(), completion_condition,
+ detail::write_at_streambuf_op<
+ AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));
+}
+
+template <typename AsyncRandomAccessWriteDevice, typename Allocator,
+ typename WriteHandler>
+inline void async_write_at(AsyncRandomAccessWriteDevice& d,
+ boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
+ WriteHandler handler)
+{
+ async_write_at(d, offset, b, transfer_all(), handler);
+}
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_WRITE_AT_HPP

Deleted: trunk/boost/asio/impl/write_at.ipp
==============================================================================
--- trunk/boost/asio/impl/write_at.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
+++ (empty file)
@@ -1,321 +0,0 @@
-//
-// write_at.ipp
-// ~~~~~~~~~~~~
-//
-// 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_WRITE_AT_IPP
-#define BOOST_ASIO_WRITE_AT_IPP
-
-#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>
-#include <boost/asio/completion_condition.hpp>
-#include <boost/asio/detail/bind_handler.hpp>
-#include <boost/asio/detail/consuming_buffers.hpp>
-#include <boost/asio/detail/handler_alloc_helpers.hpp>
-#include <boost/asio/detail/handler_invoke_helpers.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-namespace boost {
-namespace asio {
-
-template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition>
-std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- ec = boost::system::error_code();
- boost::asio::detail::consuming_buffers<
- const_buffer, ConstBufferSequence> tmp(buffers);
- std::size_t total_transferred = 0;
- tmp.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- while (tmp.begin() != tmp.end())
- {
- std::size_t bytes_transferred = d.write_some_at(
- offset + total_transferred, tmp, ec);
- tmp.consume(bytes_transferred);
- total_transferred += bytes_transferred;
- tmp.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- }
- return total_transferred;
-}
-
-template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
-inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, const ConstBufferSequence& buffers)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(
- d, offset, buffers, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition>
-inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(
- d, offset, buffers, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-template <typename SyncRandomAccessWriteDevice, typename Allocator,
- typename CompletionCondition>
-std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, boost::system::error_code& ec)
-{
- std::size_t bytes_transferred = write_at(
- d, offset, b.data(), completion_condition, ec);
- b.consume(bytes_transferred);
- return bytes_transferred;
-}
-
-template <typename SyncRandomAccessWriteDevice, typename Allocator>
-inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(d, offset, b, transfer_all(), ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-template <typename SyncRandomAccessWriteDevice, typename Allocator,
- typename CompletionCondition>
-inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition)
-{
- boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(
- d, offset, b, completion_condition, ec);
- boost::asio::detail::throw_error(ec);
- return bytes_transferred;
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- class write_at_handler
- {
- public:
- typedef boost::asio::detail::consuming_buffers<
- const_buffer, ConstBufferSequence> buffers_type;
-
- write_at_handler(AsyncRandomAccessWriteDevice& stream,
- boost::uint64_t offset, const buffers_type& buffers,
- CompletionCondition completion_condition, WriteHandler handler)
- : stream_(stream),
- buffers_(buffers),
- offset_(offset),
- total_transferred_(0),
- completion_condition_(completion_condition),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- total_transferred_ += bytes_transferred;
- buffers_.consume(bytes_transferred);
- buffers_.prepare(detail::adapt_completion_condition_result(
- completion_condition_(ec, total_transferred_)));
- if (buffers_.begin() == buffers_.end())
- {
- handler_(ec, total_transferred_);
- }
- else
- {
- stream_.async_write_some_at(
- offset_ + total_transferred_, buffers_, *this);
- }
- }
-
- //private:
- AsyncRandomAccessWriteDevice& stream_;
- buffers_type buffers_;
- boost::uint64_t offset_;
- std::size_t total_transferred_;
- CompletionCondition completion_condition_;
- WriteHandler handler_;
- };
-
- template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- inline void* asio_handler_allocate(std::size_t size,
- write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncRandomAccessWriteDevice,
- typename ConstBufferSequence, typename CompletionCondition,
- typename WriteHandler>
- inline void asio_handler_invoke(const Function& function,
- write_at_handler<AsyncRandomAccessWriteDevice, ConstBufferSequence,
- CompletionCondition, WriteHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename CompletionCondition, typename WriteHandler>
-inline void async_write_at(AsyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, 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.prepare(detail::adapt_completion_condition_result(
- completion_condition(ec, total_transferred)));
- if (tmp.begin() == tmp.end())
- {
- d.get_io_service().post(detail::bind_handler(
- handler, ec, total_transferred));
- return;
- }
-
- d.async_write_some_at(offset, tmp,
- detail::write_at_handler<AsyncRandomAccessWriteDevice,
- ConstBufferSequence, CompletionCondition, WriteHandler>(
- d, offset, tmp, completion_condition, handler));
-}
-
-template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
- typename WriteHandler>
-inline void async_write_at(AsyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, const ConstBufferSequence& buffers,
- WriteHandler handler)
-{
- async_write_at(d, offset, buffers, transfer_all(), handler);
-}
-
-#if !defined(BOOST_NO_IOSTREAM)
-
-namespace detail
-{
- template <typename AsyncRandomAccessWriteDevice, typename Allocator,
- typename WriteHandler>
- class write_at_streambuf_handler
- {
- public:
- write_at_streambuf_handler(
- boost::asio::basic_streambuf<Allocator>& streambuf,
- WriteHandler handler)
- : streambuf_(streambuf),
- handler_(handler)
- {
- }
-
- void operator()(const boost::system::error_code& ec,
- std::size_t bytes_transferred)
- {
- streambuf_.consume(bytes_transferred);
- handler_(ec, bytes_transferred);
- }
-
- //private:
- boost::asio::basic_streambuf<Allocator>& streambuf_;
- WriteHandler handler_;
- };
-
- template <typename AsyncRandomAccessWriteDevice, typename Allocator,
- typename WriteHandler>
- inline void* asio_handler_allocate(std::size_t size,
- write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
- Allocator, WriteHandler>* this_handler)
- {
- return boost_asio_handler_alloc_helpers::allocate(
- size, this_handler->handler_);
- }
-
- template <typename AsyncRandomAccessWriteDevice, typename Allocator,
- typename WriteHandler>
- inline void asio_handler_deallocate(void* pointer, std::size_t size,
- write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
- Allocator, WriteHandler>* this_handler)
- {
- boost_asio_handler_alloc_helpers::deallocate(
- pointer, size, this_handler->handler_);
- }
-
- template <typename Function, typename AsyncRandomAccessWriteDevice,
- typename Allocator, typename WriteHandler>
- inline void asio_handler_invoke(const Function& function,
- write_at_streambuf_handler<AsyncRandomAccessWriteDevice,
- Allocator, WriteHandler>* this_handler)
- {
- boost_asio_handler_invoke_helpers::invoke(
- function, this_handler->handler_);
- }
-} // namespace detail
-
-template <typename AsyncRandomAccessWriteDevice, typename Allocator,
- typename CompletionCondition, typename WriteHandler>
-inline void async_write_at(AsyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- CompletionCondition completion_condition, WriteHandler handler)
-{
- async_write_at(d, offset, b.data(), completion_condition,
- detail::write_at_streambuf_handler<
- AsyncRandomAccessWriteDevice, Allocator, WriteHandler>(b, handler));
-}
-
-template <typename AsyncRandomAccessWriteDevice, typename Allocator,
- typename WriteHandler>
-inline void async_write_at(AsyncRandomAccessWriteDevice& d,
- boost::uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
- WriteHandler handler)
-{
- async_write_at(d, offset, b, transfer_all(), handler);
-}
-
-#endif // !defined(BOOST_NO_IOSTREAM)
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_WRITE_AT_IPP

Modified: trunk/boost/asio/io_service.hpp
==============================================================================
--- trunk/boost/asio/io_service.hpp (original)
+++ trunk/boost/asio/io_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,25 +15,29 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <stdexcept>
 #include <typeinfo>
-#include <boost/config.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/noncopyable.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>
-#include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
-#include <boost/asio/detail/winsock_init.hpp>
 #include <boost/asio/detail/wrapped_handler.hpp>
+#include <boost/system/error_code.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_service_fwd.hpp>
+#else
+# include <boost/asio/detail/task_io_service_fwd.hpp>
+#endif
+
+#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+# include <boost/asio/detail/winsock_init.hpp>
+#elif defined(__sun) || defined(__QNX__) || defined(__hpux) || defined(_AIX) \
+ || defined(__osf__)
+# include <boost/asio/detail/signal_init.hpp>
+#endif
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -46,7 +50,7 @@
 #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; }
+namespace detail { typedef task_io_service io_service_impl; }
 #endif
 
 /// Provides core I/O functionality.
@@ -197,7 +201,7 @@
   class strand;
 
   /// Constructor.
- io_service();
+ BOOST_ASIO_DECL io_service();
 
   /// Constructor.
   /**
@@ -206,7 +210,7 @@
    * @param concurrency_hint A suggestion to the implementation on how many
    * threads it should allow to run simultaneously.
    */
- explicit io_service(std::size_t concurrency_hint);
+ BOOST_ASIO_DECL explicit io_service(std::size_t concurrency_hint);
 
   /// Destructor.
   /**
@@ -240,7 +244,7 @@
    * destructor defined above destroys all handlers, causing all @c shared_ptr
    * references to all connection objects to be destroyed.
    */
- ~io_service();
+ BOOST_ASIO_DECL ~io_service();
 
   /// Run the io_service object's event processing loop.
   /**
@@ -266,7 +270,7 @@
    * The poll() function may also be used to dispatch ready handlers, but
    * without blocking.
    */
- std::size_t run();
+ BOOST_ASIO_DECL std::size_t run();
 
   /// Run the io_service object's event processing loop.
   /**
@@ -292,7 +296,7 @@
    * The poll() function may also be used to dispatch ready handlers, but
    * without blocking.
    */
- std::size_t run(boost::system::error_code& ec);
+ BOOST_ASIO_DECL std::size_t run(boost::system::error_code& ec);
 
   /// Run the io_service object's event processing loop to execute at most one
   /// handler.
@@ -304,7 +308,7 @@
    *
    * @throws boost::system::system_error Thrown on failure.
    */
- std::size_t run_one();
+ BOOST_ASIO_DECL std::size_t run_one();
 
   /// Run the io_service object's event processing loop to execute at most one
   /// handler.
@@ -316,7 +320,7 @@
    *
    * @return The number of handlers that were executed.
    */
- std::size_t run_one(boost::system::error_code& ec);
+ BOOST_ASIO_DECL std::size_t run_one(boost::system::error_code& ec);
 
   /// Run the io_service object's event processing loop to execute ready
   /// handlers.
@@ -328,7 +332,7 @@
    *
    * @throws boost::system::system_error Thrown on failure.
    */
- std::size_t poll();
+ BOOST_ASIO_DECL std::size_t poll();
 
   /// Run the io_service object's event processing loop to execute ready
   /// handlers.
@@ -340,7 +344,7 @@
    *
    * @return The number of handlers that were executed.
    */
- std::size_t poll(boost::system::error_code& ec);
+ BOOST_ASIO_DECL std::size_t poll(boost::system::error_code& ec);
 
   /// Run the io_service object's event processing loop to execute one ready
   /// handler.
@@ -352,7 +356,7 @@
    *
    * @throws boost::system::system_error Thrown on failure.
    */
- std::size_t poll_one();
+ BOOST_ASIO_DECL std::size_t poll_one();
 
   /// Run the io_service object's event processing loop to execute one ready
   /// handler.
@@ -364,7 +368,7 @@
    *
    * @return The number of handlers that were executed.
    */
- std::size_t poll_one(boost::system::error_code& ec);
+ BOOST_ASIO_DECL std::size_t poll_one(boost::system::error_code& ec);
 
   /// Stop the io_service object's event processing loop.
   /**
@@ -373,7 +377,7 @@
    * return as soon as possible. Subsequent calls to run(), run_one(), poll()
    * or poll_one() will return immediately until reset() is called.
    */
- void stop();
+ BOOST_ASIO_DECL void stop();
 
   /// Reset the io_service in preparation for a subsequent run() invocation.
   /**
@@ -386,7 +390,7 @@
    * This function must not be called while there are any unfinished calls to
    * the run(), run_one(), poll() or poll_one() functions.
    */
- void reset();
+ BOOST_ASIO_DECL void reset();
 
   /// Request the io_service to invoke the given handler.
   /**
@@ -606,10 +610,10 @@
   /**
    * @param owner The io_service object that owns the service.
    */
- service(boost::asio::io_service& owner);
+ BOOST_ASIO_DECL service(boost::asio::io_service& owner);
 
   /// Destructor.
- virtual ~service();
+ BOOST_ASIO_DECL virtual ~service();
 
 private:
   /// Destroy all user-defined handler objects owned by the service.
@@ -632,10 +636,7 @@
   : public std::logic_error
 {
 public:
- service_already_exists()
- : std::logic_error("Service already exists.")
- {
- }
+ BOOST_ASIO_DECL service_already_exists();
 };
 
 /// Exception thrown when trying to add a service object to an io_service where
@@ -644,17 +645,45 @@
   : public std::logic_error
 {
 public:
- invalid_service_owner()
- : std::logic_error("Invalid service owner.")
+ BOOST_ASIO_DECL invalid_service_owner();
+};
+
+namespace detail {
+
+// Special derived service id type to keep classes header-file only.
+template <typename Type>
+class service_id
+ : public boost::asio::io_service::id
+{
+};
+
+// Special service base class to keep classes header-file only.
+template <typename Type>
+class service_base
+ : public boost::asio::io_service::service
+{
+public:
+ static boost::asio::detail::service_id<Type> id;
+
+ // Constructor.
+ service_base(boost::asio::io_service& io_service)
+ : boost::asio::io_service::service(io_service)
   {
   }
 };
 
+template <typename Type>
+boost::asio::detail::service_id<Type> service_base<Type>::id;
+
+} // namespace detail
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/io_service.ipp>
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/impl/io_service.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/impl/io_service.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_IO_SERVICE_HPP

Modified: trunk/boost/asio/ip/address.hpp
==============================================================================
--- trunk/boost/asio/ip/address.hpp (original)
+++ trunk/boost/asio/ip/address.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// address.hpp
-// ~~~~~~~~~~~
+// ip/address.hpp
+// ~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,21 +15,17 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio/ip/address_v6.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
 #if !defined(BOOST_NO_IOSTREAM)
 # include <iosfwd>
 #endif // !defined(BOOST_NO_IOSTREAM)
-#include <string>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/ip/address_v4.hpp>
-#include <boost/asio/ip/address_v6.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -48,63 +44,27 @@
 {
 public:
   /// Default constructor.
- address()
- : type_(ipv4),
- ipv4_address_(),
- ipv6_address_()
- {
- }
+ BOOST_ASIO_DECL address();
 
   /// Construct an address from an IPv4 address.
- address(const boost::asio::ip::address_v4& ipv4_address)
- : type_(ipv4),
- ipv4_address_(ipv4_address),
- ipv6_address_()
- {
- }
+ BOOST_ASIO_DECL address(const boost::asio::ip::address_v4& ipv4_address);
 
   /// Construct an address from an IPv6 address.
- address(const boost::asio::ip::address_v6& ipv6_address)
- : type_(ipv6),
- ipv4_address_(),
- ipv6_address_(ipv6_address)
- {
- }
+ BOOST_ASIO_DECL address(const boost::asio::ip::address_v6& ipv6_address);
 
   /// Copy constructor.
- address(const address& other)
- : type_(other.type_),
- ipv4_address_(other.ipv4_address_),
- ipv6_address_(other.ipv6_address_)
- {
- }
+ BOOST_ASIO_DECL address(const address& other);
 
   /// Assign from another address.
- address& operator=(const address& other)
- {
- type_ = other.type_;
- ipv4_address_ = other.ipv4_address_;
- ipv6_address_ = other.ipv6_address_;
- return *this;
- }
+ BOOST_ASIO_DECL address& operator=(const address& other);
 
   /// Assign from an IPv4 address.
- address& operator=(const boost::asio::ip::address_v4& ipv4_address)
- {
- type_ = ipv4;
- ipv4_address_ = ipv4_address;
- ipv6_address_ = boost::asio::ip::address_v6();
- return *this;
- }
+ BOOST_ASIO_DECL address& operator=(
+ const boost::asio::ip::address_v4& ipv4_address);
 
   /// Assign from an IPv6 address.
- address& operator=(const boost::asio::ip::address_v6& ipv6_address)
- {
- type_ = ipv6;
- ipv4_address_ = boost::asio::ip::address_v4();
- ipv6_address_ = ipv6_address;
- return *this;
- }
+ BOOST_ASIO_DECL address& operator=(
+ const boost::asio::ip::address_v6& ipv6_address);
 
   /// Get whether the address is an IP version 4 address.
   bool is_v4() const
@@ -119,127 +79,63 @@
   }
 
   /// Get the address as an IP version 4 address.
- boost::asio::ip::address_v4 to_v4() const
- {
- if (type_ != ipv4)
- {
- boost::system::system_error e(
- boost::asio::error::address_family_not_supported);
- boost::throw_exception(e);
- }
- return ipv4_address_;
- }
+ BOOST_ASIO_DECL boost::asio::ip::address_v4 to_v4() const;
 
   /// Get the address as an IP version 6 address.
- boost::asio::ip::address_v6 to_v6() const
- {
- if (type_ != ipv6)
- {
- boost::system::system_error e(
- boost::asio::error::address_family_not_supported);
- boost::throw_exception(e);
- }
- return ipv6_address_;
- }
+ BOOST_ASIO_DECL boost::asio::ip::address_v6 to_v6() const;
 
   /// Get the address as a string in dotted decimal format.
- std::string to_string() const
- {
- if (type_ == ipv6)
- return ipv6_address_.to_string();
- return ipv4_address_.to_string();
- }
+ BOOST_ASIO_DECL std::string to_string() const;
 
   /// Get the address as a string in dotted decimal format.
- std::string to_string(boost::system::error_code& ec) const
- {
- if (type_ == ipv6)
- return ipv6_address_.to_string(ec);
- return ipv4_address_.to_string(ec);
- }
+ BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const;
 
   /// Create an address from an IPv4 address string in dotted decimal form,
   /// or from an IPv6 address in hexadecimal notation.
- static address from_string(const char* str)
- {
- boost::system::error_code ec;
- address addr = from_string(str, ec);
- boost::asio::detail::throw_error(ec);
- return addr;
- }
+ BOOST_ASIO_DECL static address from_string(const char* str);
 
   /// Create an address from an IPv4 address string in dotted decimal form,
   /// or from an IPv6 address in hexadecimal notation.
- static address from_string(const char* str, boost::system::error_code& ec)
- {
- boost::asio::ip::address_v6 ipv6_address =
- boost::asio::ip::address_v6::from_string(str, ec);
- if (!ec)
- {
- address tmp;
- tmp.type_ = ipv6;
- tmp.ipv6_address_ = ipv6_address;
- return tmp;
- }
-
- boost::asio::ip::address_v4 ipv4_address =
- boost::asio::ip::address_v4::from_string(str, ec);
- if (!ec)
- {
- address tmp;
- tmp.type_ = ipv4;
- tmp.ipv4_address_ = ipv4_address;
- return tmp;
- }
-
- return address();
- }
+ BOOST_ASIO_DECL static address from_string(
+ const char* str, boost::system::error_code& ec);
 
   /// Create an address from an IPv4 address string in dotted decimal form,
   /// or from an IPv6 address in hexadecimal notation.
- static address from_string(const std::string& str)
- {
- return from_string(str.c_str());
- }
+ BOOST_ASIO_DECL static address from_string(const std::string& str);
 
   /// Create an address from an IPv4 address string in dotted decimal form,
   /// or from an IPv6 address in hexadecimal notation.
- static address from_string(const std::string& str,
- boost::system::error_code& ec)
+ BOOST_ASIO_DECL static address from_string(
+ const std::string& str, boost::system::error_code& ec);
+
+ /// Compare two addresses for equality.
+ BOOST_ASIO_DECL friend bool operator==(const address& a1, const address& a2);
+
+ /// Compare two addresses for inequality.
+ friend bool operator!=(const address& a1, const address& a2)
   {
- return from_string(str.c_str(), ec);
+ return !(a1 == a2);
   }
 
- /// Compare two addresses for equality.
- friend bool operator==(const address& a1, const address& a2)
+ /// Compare addresses for ordering.
+ BOOST_ASIO_DECL friend bool operator<(const address& a1, const address& a2);
+
+ /// Compare addresses for ordering.
+ friend bool operator>(const address& a1, const address& a2)
   {
- if (a1.type_ != a2.type_)
- return false;
- if (a1.type_ == ipv6)
- return a1.ipv6_address_ == a2.ipv6_address_;
- return a1.ipv4_address_ == a2.ipv4_address_;
+ return a2 < a1;
   }
 
- /// Compare two addresses for inequality.
- friend bool operator!=(const address& a1, const address& a2)
+ /// Compare addresses for ordering.
+ friend bool operator<=(const address& a1, const address& a2)
   {
- if (a1.type_ != a2.type_)
- return true;
- if (a1.type_ == ipv6)
- return a1.ipv6_address_ != a2.ipv6_address_;
- return a1.ipv4_address_ != a2.ipv4_address_;
+ return !(a2 < a1);
   }
 
   /// Compare addresses for ordering.
- friend bool operator<(const address& a1, const address& a2)
+ friend bool operator>=(const address& a1, const address& a2)
   {
- if (a1.type_ < a2.type_)
- return true;
- if (a1.type_ > a2.type_)
- return false;
- if (a1.type_ == ipv6)
- return a1.ipv6_address_ < a2.ipv6_address_;
- return a1.ipv4_address_ < a2.ipv4_address_;
+ return !(a1 < a2);
   }
 
 private:
@@ -269,11 +165,7 @@
  */
 template <typename Elem, typename Traits>
 std::basic_ostream<Elem, Traits>& operator<<(
- std::basic_ostream<Elem, Traits>& os, const address& addr)
-{
- os << addr.to_string();
- return os;
-}
+ std::basic_ostream<Elem, Traits>& os, const address& addr);
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
@@ -283,4 +175,9 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/ip/impl/address.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ip/impl/address.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_IP_ADDRESS_HPP

Modified: trunk/boost/asio/ip/address_v4.hpp
==============================================================================
--- trunk/boost/asio/ip/address_v4.hpp (original)
+++ trunk/boost/asio/ip/address_v4.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// address_v4.hpp
-// ~~~~~~~~~~~~~~
+// ip/address_v4.hpp
+// ~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,24 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/array.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/winsock_init.hpp>
+#include <boost/system/error_code.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
 #if !defined(BOOST_NO_IOSTREAM)
 # include <iosfwd>
 #endif // !defined(BOOST_NO_IOSTREAM)
-#include <climits>
-#include <string>
-#include <stdexcept>
-#include <boost/array.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -60,34 +54,10 @@
   }
 
   /// Construct an address from raw bytes.
- explicit address_v4(const bytes_type& bytes)
- {
-#if UCHAR_MAX > 0xFF
- if (bytes[0] > 0xFF || bytes[1] > 0xFF
- || bytes[2] > 0xFF || bytes[3] > 0xFF)
- {
- std::out_of_range ex("address_v4 from bytes_type");
- boost::throw_exception(ex);
- }
-#endif // UCHAR_MAX > 0xFF
-
- using namespace std; // For memcpy.
- memcpy(&addr_.s_addr, bytes.elems, 4);
- }
+ BOOST_ASIO_DECL explicit address_v4(const bytes_type& bytes);
 
   /// Construct an address from a unsigned long in host byte order.
- explicit address_v4(unsigned long addr)
- {
-#if ULONG_MAX > 0xFFFFFFFF
- if (addr > 0xFFFFFFFF)
- {
- std::out_of_range ex("address_v4 from unsigned long");
- boost::throw_exception(ex);
- }
-#endif // ULONG_MAX > 0xFFFFFFFF
-
- addr_.s_addr = boost::asio::detail::socket_ops::host_to_network_long(addr);
- }
+ BOOST_ASIO_DECL explicit address_v4(unsigned long addr);
 
   /// Copy constructor.
   address_v4(const address_v4& other)
@@ -103,96 +73,42 @@
   }
 
   /// Get the address in bytes, in network byte order.
- bytes_type to_bytes() const
- {
- using namespace std; // For memcpy.
- bytes_type bytes;
- memcpy(bytes.elems, &addr_.s_addr, 4);
- return bytes;
- }
+ BOOST_ASIO_DECL bytes_type to_bytes() const;
 
   /// Get the address as an unsigned long in host byte order
- unsigned long to_ulong() const
- {
- return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr);
- }
+ BOOST_ASIO_DECL unsigned long to_ulong() const;
 
   /// Get the address as a string in dotted decimal format.
- std::string to_string() const
- {
- boost::system::error_code ec;
- std::string addr = to_string(ec);
- boost::asio::detail::throw_error(ec);
- return addr;
- }
+ BOOST_ASIO_DECL std::string to_string() const;
 
   /// Get the address as a string in dotted decimal format.
- std::string to_string(boost::system::error_code& ec) const
- {
- char addr_str[boost::asio::detail::max_addr_v4_str_len];
- const char* addr =
- boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str,
- boost::asio::detail::max_addr_v4_str_len, 0, ec);
- if (addr == 0)
- return std::string();
- return addr;
- }
+ BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const;
 
   /// Create an address from an IP address string in dotted decimal form.
- static address_v4 from_string(const char* str)
- {
- boost::system::error_code ec;
- address_v4 addr = from_string(str, ec);
- boost::asio::detail::throw_error(ec);
- return addr;
- }
+ BOOST_ASIO_DECL static address_v4 from_string(const char* str);
 
   /// Create an address from an IP address string in dotted decimal form.
- static address_v4 from_string(const char* str, boost::system::error_code& ec)
- {
- address_v4 tmp;
- if (boost::asio::detail::socket_ops::inet_pton(
- AF_INET, str, &tmp.addr_, 0, ec) <= 0)
- return address_v4();
- return tmp;
- }
+ BOOST_ASIO_DECL static address_v4 from_string(
+ const char* str, boost::system::error_code& ec);
 
   /// Create an address from an IP address string in dotted decimal form.
- static address_v4 from_string(const std::string& str)
- {
- return from_string(str.c_str());
- }
+ BOOST_ASIO_DECL static address_v4 from_string(const std::string& str);
 
   /// Create an address from an IP address string in dotted decimal form.
- static address_v4 from_string(const std::string& str,
- boost::system::error_code& ec)
- {
- return from_string(str.c_str(), ec);
- }
+ BOOST_ASIO_DECL static address_v4 from_string(
+ const std::string& str, boost::system::error_code& ec);
 
   /// Determine whether the address is a class A address.
- bool is_class_a() const
- {
- return IN_CLASSA(to_ulong());
- }
+ BOOST_ASIO_DECL bool is_class_a() const;
 
   /// Determine whether the address is a class B address.
- bool is_class_b() const
- {
- return IN_CLASSB(to_ulong());
- }
+ BOOST_ASIO_DECL bool is_class_b() const;
 
   /// Determine whether the address is a class C address.
- bool is_class_c() const
- {
- return IN_CLASSC(to_ulong());
- }
+ BOOST_ASIO_DECL bool is_class_c() const;
 
   /// Determine whether the address is a multicast address.
- bool is_multicast() const
- {
- return IN_MULTICAST(to_ulong());
- }
+ BOOST_ASIO_DECL bool is_multicast() const;
 
   /// Compare two addresses for equality.
   friend bool operator==(const address_v4& a1, const address_v4& a2)
@@ -250,23 +166,12 @@
 
   /// Obtain an address object that represents the broadcast address that
   /// corresponds to the specified address and netmask.
- static address_v4 broadcast(const address_v4& addr, const address_v4& mask)
- {
- return address_v4(addr.to_ulong() | ~mask.to_ulong());
- }
+ BOOST_ASIO_DECL static address_v4 broadcast(
+ const address_v4& addr, const address_v4& mask);
 
   /// Obtain the netmask that corresponds to the address, based on its address
   /// class.
- static address_v4 netmask(const address_v4& addr)
- {
- if (addr.is_class_a())
- return address_v4(0xFF000000);
- if (addr.is_class_b())
- return address_v4(0xFFFF0000);
- if (addr.is_class_c())
- return address_v4(0xFFFFFF00);
- return address_v4(0xFFFFFFFF);
- }
+ BOOST_ASIO_DECL static address_v4 netmask(const address_v4& addr);
 
 private:
   // The underlying IPv4 address.
@@ -289,22 +194,7 @@
  */
 template <typename Elem, typename Traits>
 std::basic_ostream<Elem, Traits>& operator<<(
- std::basic_ostream<Elem, Traits>& os, const address_v4& addr)
-{
- boost::system::error_code ec;
- std::string s = addr.to_string(ec);
- if (ec)
- {
- if (os.exceptions() & std::ios::failbit)
- boost::asio::detail::throw_error(ec);
- else
- os.setstate(std::ios_base::failbit);
- }
- else
- for (std::string::iterator i = s.begin(); i != s.end(); ++i)
- os << os.widen(*i);
- return os;
-}
+ std::basic_ostream<Elem, Traits>& os, const address_v4& addr);
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
@@ -314,4 +204,9 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/ip/impl/address_v4.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ip/impl/address_v4.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_IP_ADDRESS_V4_HPP

Modified: trunk/boost/asio/ip/address_v6.hpp
==============================================================================
--- trunk/boost/asio/ip/address_v6.hpp (original)
+++ trunk/boost/asio/ip/address_v6.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// address_v6.hpp
-// ~~~~~~~~~~~~~~
+// ip/address_v6.hpp
+// ~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,26 +15,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/array.hpp>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/winsock_init.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/ip/address_v4.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
 #if !defined(BOOST_NO_IOSTREAM)
 # include <iosfwd>
 #endif // !defined(BOOST_NO_IOSTREAM)
-#include <cstring>
-#include <string>
-#include <stdexcept>
-#include <typeinfo>
-#include <boost/array.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/ip/address_v4.hpp>
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -56,46 +49,17 @@
   typedef boost::array<unsigned char, 16> bytes_type;
 
   /// Default constructor.
- address_v6()
- : scope_id_(0)
- {
- boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
- addr_ = tmp_addr;
- }
+ BOOST_ASIO_DECL address_v6();
 
   /// Construct an address from raw bytes and scope ID.
- explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0)
- : scope_id_(scope_id)
- {
-#if UCHAR_MAX > 0xFF
- for (std::size_t i = 0; i < bytes.size(); ++i)
- {
- if (bytes[i] > 0xFF)
- {
- std::out_of_range ex("address_v6 from bytes_type");
- boost::throw_exception(ex);
- }
- }
-#endif // UCHAR_MAX > 0xFF
-
- using namespace std; // For memcpy.
- memcpy(addr_.s6_addr, bytes.elems, 16);
- }
+ BOOST_ASIO_DECL explicit address_v6(const bytes_type& bytes,
+ unsigned long scope_id = 0);
 
   /// Copy constructor.
- address_v6(const address_v6& other)
- : addr_(other.addr_),
- scope_id_(other.scope_id_)
- {
- }
+ BOOST_ASIO_DECL address_v6(const address_v6& other);
 
   /// Assign from another address.
- address_v6& operator=(const address_v6& other)
- {
- addr_ = other.addr_;
- scope_id_ = other.scope_id_;
- return *this;
- }
+ BOOST_ASIO_DECL address_v6& operator=(const address_v6& other);
 
   /// The scope ID of the address.
   /**
@@ -116,217 +80,80 @@
   }
 
   /// Get the address in bytes, in network byte order.
- bytes_type to_bytes() const
- {
- using namespace std; // For memcpy.
- bytes_type bytes;
- memcpy(bytes.elems, addr_.s6_addr, 16);
- return bytes;
- }
+ BOOST_ASIO_DECL bytes_type to_bytes() const;
 
   /// Get the address as a string.
- std::string to_string() const
- {
- boost::system::error_code ec;
- std::string addr = to_string(ec);
- boost::asio::detail::throw_error(ec);
- return addr;
- }
+ BOOST_ASIO_DECL std::string to_string() const;
 
   /// Get the address as a string.
- std::string to_string(boost::system::error_code& ec) const
- {
- char addr_str[boost::asio::detail::max_addr_v6_str_len];
- const char* addr =
- boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str,
- boost::asio::detail::max_addr_v6_str_len, scope_id_, ec);
- if (addr == 0)
- return std::string();
- return addr;
- }
+ BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const;
 
   /// Create an address from an IP address string.
- static address_v6 from_string(const char* str)
- {
- boost::system::error_code ec;
- address_v6 addr = from_string(str, ec);
- boost::asio::detail::throw_error(ec);
- return addr;
- }
+ BOOST_ASIO_DECL static address_v6 from_string(const char* str);
 
   /// Create an address from an IP address string.
- static address_v6 from_string(const char* str, boost::system::error_code& ec)
- {
- address_v6 tmp;
- if (boost::asio::detail::socket_ops::inet_pton(
- AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0)
- return address_v6();
- return tmp;
- }
+ BOOST_ASIO_DECL static address_v6 from_string(
+ const char* str, boost::system::error_code& ec);
 
   /// Create an address from an IP address string.
- static address_v6 from_string(const std::string& str)
- {
- return from_string(str.c_str());
- }
+ BOOST_ASIO_DECL static address_v6 from_string(const std::string& str);
 
   /// Create an address from an IP address string.
- static address_v6 from_string(const std::string& str,
- boost::system::error_code& ec)
- {
- return from_string(str.c_str(), ec);
- }
+ BOOST_ASIO_DECL static address_v6 from_string(
+ const std::string& str, boost::system::error_code& ec);
 
   /// Converts an IPv4-mapped or IPv4-compatible address to an IPv4 address.
- address_v4 to_v4() const
- {
- if (!is_v4_mapped() && !is_v4_compatible())
- {
- std::bad_cast ex;
- boost::throw_exception(ex);
- }
-
- address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],
- addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };
- return address_v4(v4_bytes);
- }
+ BOOST_ASIO_DECL address_v4 to_v4() const;
 
   /// Determine whether the address is a loopback address.
- bool is_loopback() const
- {
-#if defined(__BORLANDC__)
- return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
- && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
- && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
- && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
- && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
- && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
- && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
- && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
-#else
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_LOOPBACK(&addr_) != 0;
-#endif
- }
+ BOOST_ASIO_DECL bool is_loopback() const;
 
   /// Determine whether the address is unspecified.
- bool is_unspecified() const
- {
-#if defined(__BORLANDC__)
- return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
- && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
- && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
- && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
- && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
- && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
- && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
- && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
-#else
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0;
-#endif
- }
+ BOOST_ASIO_DECL bool is_unspecified() const;
 
   /// Determine whether the address is link local.
- bool is_link_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_link_local() const;
 
   /// Determine whether the address is site local.
- bool is_site_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_SITELOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_site_local() const;
 
   /// Determine whether the address is a mapped IPv4 address.
- bool is_v4_mapped() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_V4MAPPED(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_v4_mapped() const;
 
   /// Determine whether the address is an IPv4-compatible address.
- bool is_v4_compatible() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_V4COMPAT(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_v4_compatible() const;
 
   /// Determine whether the address is a multicast address.
- bool is_multicast() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MULTICAST(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast() const;
 
   /// Determine whether the address is a global multicast address.
- bool is_multicast_global() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast_global() const;
 
   /// Determine whether the address is a link-local multicast address.
- bool is_multicast_link_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast_link_local() const;
 
   /// Determine whether the address is a node-local multicast address.
- bool is_multicast_node_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast_node_local() const;
 
   /// Determine whether the address is a org-local multicast address.
- bool is_multicast_org_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast_org_local() const;
 
   /// Determine whether the address is a site-local multicast address.
- bool is_multicast_site_local() const
- {
- using namespace boost::asio::detail;
- return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0;
- }
+ BOOST_ASIO_DECL bool is_multicast_site_local() const;
 
   /// Compare two addresses for equality.
- friend bool operator==(const address_v6& a1, const address_v6& a2)
- {
- using namespace std; // For memcmp.
- return memcmp(&a1.addr_, &a2.addr_,
- sizeof(boost::asio::detail::in6_addr_type)) == 0
- && a1.scope_id_ == a2.scope_id_;
- }
+ BOOST_ASIO_DECL friend bool operator==(
+ const address_v6& a1, const address_v6& a2);
 
   /// Compare two addresses for inequality.
   friend bool operator!=(const address_v6& a1, const address_v6& a2)
   {
- using namespace std; // For memcmp.
- return memcmp(&a1.addr_, &a2.addr_,
- sizeof(boost::asio::detail::in6_addr_type)) != 0
- || a1.scope_id_ != a2.scope_id_;
+ return !(a1 == a2);
   }
 
   /// Compare addresses for ordering.
- friend bool operator<(const address_v6& a1, const address_v6& a2)
- {
- using namespace std; // For memcmp.
- int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
- sizeof(boost::asio::detail::in6_addr_type));
- if (memcmp_result < 0)
- return true;
- if (memcmp_result > 0)
- return false;
- return a1.scope_id_ < a2.scope_id_;
- }
+ BOOST_ASIO_DECL friend bool operator<(
+ const address_v6& a1, const address_v6& a2);
 
   /// Compare addresses for ordering.
   friend bool operator>(const address_v6& a1, const address_v6& a2)
@@ -353,31 +180,13 @@
   }
 
   /// Obtain an address object that represents the loopback address.
- static address_v6 loopback()
- {
- address_v6 tmp;
- boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT;
- tmp.addr_ = tmp_addr;
- return tmp;
- }
+ BOOST_ASIO_DECL static address_v6 loopback();
 
   /// Create an IPv4-mapped IPv6 address.
- static address_v6 v4_mapped(const address_v4& addr)
- {
- address_v4::bytes_type v4_bytes = addr.to_bytes();
- bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,
- v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
- return address_v6(v6_bytes);
- }
+ BOOST_ASIO_DECL static address_v6 v4_mapped(const address_v4& addr);
 
   /// Create an IPv4-compatible IPv6 address.
- static address_v6 v4_compatible(const address_v4& addr)
- {
- address_v4::bytes_type v4_bytes = addr.to_bytes();
- bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
- return address_v6(v6_bytes);
- }
+ BOOST_ASIO_DECL static address_v6 v4_compatible(const address_v4& addr);
 
 private:
   // The underlying IPv6 address.
@@ -403,22 +212,7 @@
  */
 template <typename Elem, typename Traits>
 std::basic_ostream<Elem, Traits>& operator<<(
- std::basic_ostream<Elem, Traits>& os, const address_v6& addr)
-{
- boost::system::error_code ec;
- std::string s = addr.to_string(ec);
- if (ec)
- {
- if (os.exceptions() & std::ios::failbit)
- boost::asio::detail::throw_error(ec);
- else
- os.setstate(std::ios_base::failbit);
- }
- else
- for (std::string::iterator i = s.begin(); i != s.end(); ++i)
- os << os.widen(*i);
- return os;
-}
+ std::basic_ostream<Elem, Traits>& os, const address_v6& addr);
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
@@ -428,4 +222,9 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/ip/impl/address_v6.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ip/impl/address_v6.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_IP_ADDRESS_V6_HPP

Modified: trunk/boost/asio/ip/basic_endpoint.hpp
==============================================================================
--- trunk/boost/asio/ip/basic_endpoint.hpp (original)
+++ trunk/boost/asio/ip/basic_endpoint.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_endpoint.hpp
-// ~~~~~~~~~~~~~~~~~~
+// ip/basic_endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,25 +15,15 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/detail/endpoint.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/throw_exception.hpp>
-#include <boost/detail/workaround.hpp>
-#include <cstring>
 #if !defined(BOOST_NO_IOSTREAM)
-# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-# include <ostream>
-# endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-# include <sstream>
+# include <iosfwd>
 #endif // !defined(BOOST_NO_IOSTREAM)
-#include <boost/asio/detail/pop_options.hpp>
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/ip/address.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -68,11 +58,8 @@
 
   /// Default constructor.
   basic_endpoint()
- : data_()
+ : impl_()
   {
- data_.v4.sin_family = AF_INET;
- data_.v4.sin_port = 0;
- data_.v4.sin_addr.s_addr = INADDR_ANY;
   }
 
   /// Construct an endpoint using a port number, specified in the host's byte
@@ -92,74 +79,35 @@
    * @endcode
    */
   basic_endpoint(const InternetProtocol& protocol, unsigned short port_num)
- : data_()
+ : impl_(protocol.family(), port_num)
   {
- using namespace std; // For memcpy.
- if (protocol.family() == PF_INET)
- {
- data_.v4.sin_family = AF_INET;
- data_.v4.sin_port =
- boost::asio::detail::socket_ops::host_to_network_short(port_num);
- data_.v4.sin_addr.s_addr = INADDR_ANY;
- }
- else
- {
- data_.v6.sin6_family = AF_INET6;
- data_.v6.sin6_port =
- boost::asio::detail::socket_ops::host_to_network_short(port_num);
- data_.v6.sin6_flowinfo = 0;
- boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
- data_.v6.sin6_addr = tmp_addr;
- data_.v6.sin6_scope_id = 0;
- }
   }
 
   /// Construct an endpoint using a port number and an IP address. This
   /// constructor may be used for accepting connections on a specific interface
   /// or for making a connection to a remote endpoint.
   basic_endpoint(const boost::asio::ip::address& addr, unsigned short port_num)
- : data_()
+ : impl_(addr, port_num)
   {
- using namespace std; // For memcpy.
- if (addr.is_v4())
- {
- data_.v4.sin_family = AF_INET;
- data_.v4.sin_port =
- boost::asio::detail::socket_ops::host_to_network_short(port_num);
- data_.v4.sin_addr.s_addr =
- boost::asio::detail::socket_ops::host_to_network_long(
- addr.to_v4().to_ulong());
- }
- else
- {
- data_.v6.sin6_family = AF_INET6;
- data_.v6.sin6_port =
- boost::asio::detail::socket_ops::host_to_network_short(port_num);
- data_.v6.sin6_flowinfo = 0;
- boost::asio::ip::address_v6 v6_addr = addr.to_v6();
- boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes();
- memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16);
- data_.v6.sin6_scope_id = v6_addr.scope_id();
- }
   }
 
   /// Copy constructor.
   basic_endpoint(const basic_endpoint& other)
- : data_(other.data_)
+ : impl_(other.impl_)
   {
   }
 
   /// Assign from another endpoint.
   basic_endpoint& operator=(const basic_endpoint& other)
   {
- data_ = other.data_;
+ impl_ = other.impl_;
     return *this;
   }
 
   /// The protocol associated with the endpoint.
   protocol_type protocol() const
   {
- if (is_v4())
+ if (impl_.is_v4())
       return InternetProtocol::v4();
     return InternetProtocol::v6();
   }
@@ -167,137 +115,104 @@
   /// Get the underlying endpoint in the native type.
   data_type* data()
   {
- return &data_.base;
+ return impl_.data();
   }
 
   /// Get the underlying endpoint in the native type.
   const data_type* data() const
   {
- return &data_.base;
+ return impl_.data();
   }
 
   /// Get the underlying size of the endpoint in the native type.
   std::size_t size() const
   {
- if (is_v4())
- return sizeof(boost::asio::detail::sockaddr_in4_type);
- else
- return sizeof(boost::asio::detail::sockaddr_in6_type);
+ return impl_.size();
   }
 
   /// Set the underlying size of the endpoint in the native type.
   void resize(std::size_t size)
   {
- if (size > sizeof(boost::asio::detail::sockaddr_storage_type))
- {
- boost::system::system_error e(boost::asio::error::invalid_argument);
- boost::throw_exception(e);
- }
+ impl_.resize(size);
   }
 
   /// Get the capacity of the endpoint in the native type.
   std::size_t capacity() const
   {
- return sizeof(boost::asio::detail::sockaddr_storage_type);
+ return impl_.capacity();
   }
 
   /// Get the port associated with the endpoint. The port number is always in
   /// the host's byte order.
   unsigned short port() const
   {
- if (is_v4())
- {
- return boost::asio::detail::socket_ops::network_to_host_short(
- data_.v4.sin_port);
- }
- else
- {
- return boost::asio::detail::socket_ops::network_to_host_short(
- data_.v6.sin6_port);
- }
+ return impl_.port();
   }
 
   /// Set the port associated with the endpoint. The port number is always in
   /// the host's byte order.
   void port(unsigned short port_num)
   {
- if (is_v4())
- {
- data_.v4.sin_port
- = boost::asio::detail::socket_ops::host_to_network_short(port_num);
- }
- else
- {
- data_.v6.sin6_port
- = boost::asio::detail::socket_ops::host_to_network_short(port_num);
- }
+ impl_.port(port_num);
   }
 
   /// Get the IP address associated with the endpoint.
   boost::asio::ip::address address() const
   {
- using namespace std; // For memcpy.
- if (is_v4())
- {
- return boost::asio::ip::address_v4(
- boost::asio::detail::socket_ops::network_to_host_long(
- data_.v4.sin_addr.s_addr));
- }
- else
- {
- boost::asio::ip::address_v6::bytes_type bytes;
- memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);
- return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
- }
+ return impl_.address();
   }
 
   /// Set the IP address associated with the endpoint.
   void address(const boost::asio::ip::address& addr)
   {
- basic_endpoint<InternetProtocol> tmp_endpoint(addr, port());
- data_ = tmp_endpoint.data_;
+ impl_.address(addr);
   }
 
   /// Compare two endpoints for equality.
   friend bool operator==(const basic_endpoint<InternetProtocol>& e1,
       const basic_endpoint<InternetProtocol>& e2)
   {
- return e1.address() == e2.address() && e1.port() == e2.port();
+ return e1.impl_ == e2.impl_;
   }
 
   /// Compare two endpoints for inequality.
   friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,
       const basic_endpoint<InternetProtocol>& e2)
   {
- return e1.address() != e2.address() || e1.port() != e2.port();
+ return !(e1 == e2);
   }
 
   /// Compare endpoints for ordering.
   friend bool operator<(const basic_endpoint<InternetProtocol>& e1,
       const basic_endpoint<InternetProtocol>& e2)
   {
- if (e1.address() < e2.address())
- return true;
- if (e1.address() != e2.address())
- return false;
- return e1.port() < e2.port();
+ return e1.impl_ < e2.impl_;
   }
 
-private:
- // Helper function to determine whether the endpoint is IPv4.
- bool is_v4() const
+ /// Compare endpoints for ordering.
+ friend bool operator>(const basic_endpoint<InternetProtocol>& e1,
+ const basic_endpoint<InternetProtocol>& e2)
   {
- return data_.base.sa_family == AF_INET;
+ return e2.impl_ < e1.impl_;
   }
 
- // The underlying IP socket address.
- union data_union
+ /// Compare endpoints for ordering.
+ friend bool operator<=(const basic_endpoint<InternetProtocol>& e1,
+ const basic_endpoint<InternetProtocol>& e2)
   {
- boost::asio::detail::socket_addr_type base;
- boost::asio::detail::sockaddr_storage_type storage;
- boost::asio::detail::sockaddr_in4_type v4;
- boost::asio::detail::sockaddr_in6_type v6;
- } data_;
+ return !(e2 < e1);
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator>=(const basic_endpoint<InternetProtocol>& e1,
+ const basic_endpoint<InternetProtocol>& e2)
+ {
+ return !(e1 < e2);
+ }
+
+private:
+ // The underlying IP endpoint.
+ boost::asio::ip::detail::endpoint impl_;
 };
 
 #if !defined(BOOST_NO_IOSTREAM)
@@ -314,64 +229,10 @@
  *
  * @relates boost::asio::ip::basic_endpoint
  */
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-template <typename InternetProtocol>
-std::ostream& operator<<(std::ostream& os,
- const basic_endpoint<InternetProtocol>& endpoint)
-{
- const address& addr = endpoint.address();
- boost::system::error_code ec;
- std::string a = addr.to_string(ec);
- if (ec)
- {
- if (os.exceptions() & std::ios::failbit)
- boost::asio::detail::throw_error(ec);
- else
- os.setstate(std::ios_base::failbit);
- }
- else
- {
- std::ostringstream tmp_os;
- tmp_os.imbue(std::locale::classic());
- if (addr.is_v4())
- tmp_os << a;
- else
- tmp_os << '[' << a << ']';
- tmp_os << ':' << endpoint.port();
- os << tmp_os.str();
- }
- return os;
-}
-#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
 template <typename Elem, typename Traits, typename InternetProtocol>
 std::basic_ostream<Elem, Traits>& operator<<(
     std::basic_ostream<Elem, Traits>& os,
- const basic_endpoint<InternetProtocol>& endpoint)
-{
- const address& addr = endpoint.address();
- boost::system::error_code ec;
- std::string a = addr.to_string(ec);
- if (ec)
- {
- if (os.exceptions() & std::ios::failbit)
- boost::asio::detail::throw_error(ec);
- else
- os.setstate(std::ios_base::failbit);
- }
- else
- {
- std::ostringstream tmp_os;
- tmp_os.imbue(std::locale::classic());
- if (addr.is_v4())
- tmp_os << a;
- else
- tmp_os << '[' << a << ']';
- tmp_os << ':' << endpoint.port();
- os << tmp_os.str();
- }
- return os;
-}
-#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+ const basic_endpoint<InternetProtocol>& endpoint);
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
@@ -381,4 +242,6 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/ip/impl/basic_endpoint.hpp>
+
 #endif // BOOST_ASIO_IP_BASIC_ENDPOINT_HPP

Modified: trunk/boost/asio/ip/basic_resolver.hpp
==============================================================================
--- trunk/boost/asio/ip/basic_resolver.hpp (original)
+++ trunk/boost/asio/ip/basic_resolver.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_resolver.hpp
-// ~~~~~~~~~~~~~~~~~~
+// ip/basic_resolver.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,15 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
 #include <boost/asio/ip/resolver_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ip/basic_resolver_entry.hpp
==============================================================================
--- trunk/boost/asio/ip/basic_resolver_entry.hpp (original)
+++ trunk/boost/asio/ip/basic_resolver_entry.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_resolver_entry.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// ip/basic_resolver_entry.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <string>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <string>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_resolver_iterator.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ip/basic_resolver_iterator.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,18 @@
 # 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/asio/detail/config.hpp>
 #include <boost/iterator.hpp>
-#include <boost/shared_ptr.hpp>
 #include <cstring>
 #include <string>
 #include <vector>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/shared_ptr.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 #include <boost/asio/ip/basic_resolver_entry.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {
@@ -177,7 +175,7 @@
   }
 
   typedef std::vector<basic_resolver_entry<InternetProtocol> > values_type;
- boost::shared_ptr<values_type> values_;
+ boost::asio::detail::shared_ptr<values_type> values_;
   std::size_t index_;
 };
 

Modified: trunk/boost/asio/ip/basic_resolver_query.hpp
==============================================================================
--- trunk/boost/asio/ip/basic_resolver_query.hpp (original)
+++ trunk/boost/asio/ip/basic_resolver_query.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_resolver_query.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// ip/basic_resolver_query.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,13 @@
 # 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/config.hpp>
 #include <string>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/ip/resolver_query_base.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {

Added: trunk/boost/asio/ip/detail/endpoint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/detail/endpoint.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,142 @@
+//
+// ip/detail/endpoint.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_IP_DETAIL_ENDPOINT_HPP
+#define BOOST_ASIO_IP_DETAIL_ENDPOINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <string>
+#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/winsock_init.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/ip/address.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+namespace detail {
+
+// Helper class for implementating an IP endpoint.
+class endpoint
+{
+public:
+ // Default constructor.
+ BOOST_ASIO_DECL endpoint();
+
+ // Construct an endpoint using a family and port number.
+ BOOST_ASIO_DECL endpoint(int family, unsigned short port_num);
+
+ // Construct an endpoint using an address and port number.
+ BOOST_ASIO_DECL endpoint(const boost::asio::ip::address& addr,
+ unsigned short port_num);
+
+ // Copy constructor.
+ endpoint(const endpoint& other)
+ : data_(other.data_)
+ {
+ }
+
+ // Assign from another endpoint.
+ endpoint& operator=(const endpoint& other)
+ {
+ data_ = other.data_;
+ return *this;
+ }
+
+ // Get the underlying endpoint in the native type.
+ boost::asio::detail::socket_addr_type* data()
+ {
+ return &data_.base;
+ }
+
+ // Get the underlying endpoint in the native type.
+ const boost::asio::detail::socket_addr_type* data() const
+ {
+ return &data_.base;
+ }
+
+ // Get the underlying size of the endpoint in the native type.
+ std::size_t size() const
+ {
+ if (is_v4())
+ return sizeof(boost::asio::detail::sockaddr_in4_type);
+ else
+ return sizeof(boost::asio::detail::sockaddr_in6_type);
+ }
+
+ // Set the underlying size of the endpoint in the native type.
+ BOOST_ASIO_DECL void resize(std::size_t size);
+
+ // Get the capacity of the endpoint in the native type.
+ std::size_t capacity() const
+ {
+ return sizeof(boost::asio::detail::sockaddr_storage_type);
+ }
+
+ // Get the port associated with the endpoint.
+ BOOST_ASIO_DECL unsigned short port() const;
+
+ // Set the port associated with the endpoint.
+ BOOST_ASIO_DECL void port(unsigned short port_num);
+
+ // Get the IP address associated with the endpoint.
+ BOOST_ASIO_DECL boost::asio::ip::address address() const;
+
+ // Set the IP address associated with the endpoint.
+ BOOST_ASIO_DECL void address(const boost::asio::ip::address& addr);
+
+ // Compare two endpoints for equality.
+ BOOST_ASIO_DECL friend bool operator==(
+ const endpoint& e1, const endpoint& e2);
+
+ // Compare endpoints for ordering.
+ BOOST_ASIO_DECL friend bool operator<(
+ const endpoint& e1, const endpoint& e2);
+
+ // Determine whether the endpoint is IPv4.
+ bool is_v4() const
+ {
+ return data_.base.sa_family == AF_INET;
+ }
+
+#if !defined(BOOST_NO_IOSTREAM)
+ // Convert to a string.
+ BOOST_ASIO_DECL std::string to_string(boost::system::error_code& ec) const;
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+private:
+ // The underlying IP socket address.
+ union data_union
+ {
+ boost::asio::detail::socket_addr_type base;
+ boost::asio::detail::sockaddr_storage_type storage;
+ boost::asio::detail::sockaddr_in4_type v4;
+ boost::asio::detail::sockaddr_in6_type v6;
+ } data_;
+};
+
+} // namespace detail
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ip/detail/impl/endpoint.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // BOOST_ASIO_IP_DETAIL_ENDPOINT_HPP

Added: trunk/boost/asio/ip/detail/impl/endpoint.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/detail/impl/endpoint.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,193 @@
+//
+// ip/detail/impl/endpoint.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IP_DETAIL_IMPL_ENDPOINT_IPP
+#define BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstring>
+#if !defined(BOOST_NO_IOSTREAM)
+# include <sstream>
+#endif // !defined(BOOST_NO_IOSTREAM)
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ip/detail/endpoint.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+namespace detail {
+
+endpoint::endpoint()
+ : data_()
+{
+ data_.v4.sin_family = AF_INET;
+ data_.v4.sin_port = 0;
+ data_.v4.sin_addr.s_addr = INADDR_ANY;
+}
+
+endpoint::endpoint(int family, unsigned short port_num)
+ : data_()
+{
+ using namespace std; // For memcpy.
+ if (family == PF_INET)
+ {
+ data_.v4.sin_family = AF_INET;
+ data_.v4.sin_port =
+ boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ data_.v4.sin_addr.s_addr = INADDR_ANY;
+ }
+ else
+ {
+ data_.v6.sin6_family = AF_INET6;
+ data_.v6.sin6_port =
+ boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ data_.v6.sin6_flowinfo = 0;
+ boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
+ data_.v6.sin6_addr = tmp_addr;
+ data_.v6.sin6_scope_id = 0;
+ }
+}
+
+endpoint::endpoint(const boost::asio::ip::address& addr,
+ unsigned short port_num)
+ : data_()
+{
+ using namespace std; // For memcpy.
+ if (addr.is_v4())
+ {
+ data_.v4.sin_family = AF_INET;
+ data_.v4.sin_port =
+ boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ data_.v4.sin_addr.s_addr =
+ boost::asio::detail::socket_ops::host_to_network_long(
+ addr.to_v4().to_ulong());
+ }
+ else
+ {
+ data_.v6.sin6_family = AF_INET6;
+ data_.v6.sin6_port =
+ boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ data_.v6.sin6_flowinfo = 0;
+ boost::asio::ip::address_v6 v6_addr = addr.to_v6();
+ boost::asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes();
+ memcpy(data_.v6.sin6_addr.s6_addr, bytes.elems, 16);
+ data_.v6.sin6_scope_id = v6_addr.scope_id();
+ }
+}
+
+void endpoint::resize(std::size_t size)
+{
+ if (size > sizeof(boost::asio::detail::sockaddr_storage_type))
+ {
+ boost::system::error_code ec(boost::asio::error::invalid_argument);
+ boost::asio::detail::throw_error(ec);
+ }
+}
+
+unsigned short endpoint::port() const
+{
+ if (is_v4())
+ {
+ return boost::asio::detail::socket_ops::network_to_host_short(
+ data_.v4.sin_port);
+ }
+ else
+ {
+ return boost::asio::detail::socket_ops::network_to_host_short(
+ data_.v6.sin6_port);
+ }
+}
+
+void endpoint::port(unsigned short port_num)
+{
+ if (is_v4())
+ {
+ data_.v4.sin_port
+ = boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ }
+ else
+ {
+ data_.v6.sin6_port
+ = boost::asio::detail::socket_ops::host_to_network_short(port_num);
+ }
+}
+
+boost::asio::ip::address endpoint::address() const
+{
+ using namespace std; // For memcpy.
+ if (is_v4())
+ {
+ return boost::asio::ip::address_v4(
+ boost::asio::detail::socket_ops::network_to_host_long(
+ data_.v4.sin_addr.s_addr));
+ }
+ else
+ {
+ boost::asio::ip::address_v6::bytes_type bytes;
+ memcpy(bytes.elems, data_.v6.sin6_addr.s6_addr, 16);
+ return boost::asio::ip::address_v6(bytes, data_.v6.sin6_scope_id);
+ }
+}
+
+void endpoint::address(const boost::asio::ip::address& addr)
+{
+ endpoint tmp_endpoint(addr, port());
+ data_ = tmp_endpoint.data_;
+}
+
+bool operator==(const endpoint& e1, const endpoint& e2)
+{
+ return e1.address() == e2.address() && e1.port() == e2.port();
+}
+
+bool operator<(const endpoint& e1, const endpoint& e2)
+{
+ if (e1.address() < e2.address())
+ return true;
+ if (e1.address() != e2.address())
+ return false;
+ return e1.port() < e2.port();
+}
+
+#if !defined(BOOST_NO_IOSTREAM)
+std::string endpoint::to_string(boost::system::error_code& ec) const
+{
+ std::string a = address().to_string(ec);
+ if (ec)
+ return std::string();
+
+ std::ostringstream tmp_os;
+ tmp_os.imbue(std::locale::classic());
+ if (is_v4())
+ tmp_os << a;
+ else
+ tmp_os << '[' << a << ']';
+ tmp_os << ':' << port();
+
+ return tmp_os.str();
+}
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+} // namespace detail
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP

Modified: trunk/boost/asio/ip/detail/socket_option.hpp
==============================================================================
--- trunk/boost/asio/ip/detail/socket_option.hpp (original)
+++ trunk/boost/asio/ip/detail/socket_option.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// socket_option.hpp
-// ~~~~~~~~~~~~~~~~~
+// detail/socket_option.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,18 +15,15 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <cstring>
-#include <boost/config.hpp>
 #include <boost/throw_exception.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/ip/address.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/ip/address.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ip/host_name.hpp
==============================================================================
--- trunk/boost/asio/ip/host_name.hpp (original)
+++ trunk/boost/asio/ip/host_name.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// host_name.hpp
-// ~~~~~~~~~~~~~
+// ip/host_name.hpp
+// ~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,45 +15,21 @@
 # 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/asio/detail/config.hpp>
 #include <string>
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/system/error_code.hpp>
 
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
 namespace ip {
 
 /// Get the current host name.
-std::string host_name();
+BOOST_ASIO_DECL std::string host_name();
 
 /// Get the current host name.
-std::string host_name(boost::system::error_code& ec);
-
-inline std::string host_name()
-{
- char name[1024];
- boost::system::error_code ec;
- if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0)
- {
- boost::asio::detail::throw_error(ec);
- return std::string();
- }
- return std::string(name);
-}
-
-inline std::string host_name(boost::system::error_code& ec)
-{
- char name[1024];
- if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0)
- return std::string();
- return std::string(name);
-}
+BOOST_ASIO_DECL std::string host_name(boost::system::error_code& ec);
 
 } // namespace ip
 } // namespace asio
@@ -61,4 +37,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/ip/impl/host_name.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // BOOST_ASIO_IP_HOST_NAME_HPP

Modified: trunk/boost/asio/ip/icmp.hpp
==============================================================================
--- trunk/boost/asio/ip/icmp.hpp (original)
+++ trunk/boost/asio/ip/icmp.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// icmp.hpp
-// ~~~~~~~~
+// ip/icmp.hpp
+// ~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,15 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/socket_types.hpp>
 #include <boost/asio/basic_raw_socket.hpp>
 #include <boost/asio/ip/basic_endpoint.hpp>
 #include <boost/asio/ip/basic_resolver.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Added: trunk/boost/asio/ip/impl/address.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,55 @@
+//
+// ip/impl/address.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_IP_IMPL_ADDRESS_HPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+template <typename Elem, typename Traits>
+std::basic_ostream<Elem, Traits>& operator<<(
+ std::basic_ostream<Elem, Traits>& os, const address& addr)
+{
+ boost::system::error_code ec;
+ std::string s = addr.to_string(ec);
+ if (ec)
+ {
+ if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit)
+ boost::asio::detail::throw_error(ec);
+ else
+ os.setstate(std::basic_ostream<Elem, Traits>::failbit);
+ }
+ else
+ for (std::string::iterator i = s.begin(); i != s.end(); ++i)
+ os << os.widen(*i);
+ return os;
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_HPP

Added: trunk/boost/asio/ip/impl/address.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,188 @@
+//
+// ip/impl/address.ipp
+// ~~~~~~~~~~~~~~~~~~~
+//
+// 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_IP_IMPL_ADDRESS_IPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <typeinfo>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+address::address()
+ : type_(ipv4),
+ ipv4_address_(),
+ ipv6_address_()
+{
+}
+
+address::address(const boost::asio::ip::address_v4& ipv4_address)
+ : type_(ipv4),
+ ipv4_address_(ipv4_address),
+ ipv6_address_()
+{
+}
+
+address::address(const boost::asio::ip::address_v6& ipv6_address)
+ : type_(ipv6),
+ ipv4_address_(),
+ ipv6_address_(ipv6_address)
+{
+}
+
+address::address(const address& other)
+ : type_(other.type_),
+ ipv4_address_(other.ipv4_address_),
+ ipv6_address_(other.ipv6_address_)
+{
+}
+
+address& address::operator=(const address& other)
+{
+ type_ = other.type_;
+ ipv4_address_ = other.ipv4_address_;
+ ipv6_address_ = other.ipv6_address_;
+ return *this;
+}
+
+address& address::operator=(const boost::asio::ip::address_v4& ipv4_address)
+{
+ type_ = ipv4;
+ ipv4_address_ = ipv4_address;
+ ipv6_address_ = boost::asio::ip::address_v6();
+ return *this;
+}
+
+address& address::operator=(const boost::asio::ip::address_v6& ipv6_address)
+{
+ type_ = ipv6;
+ ipv4_address_ = boost::asio::ip::address_v4();
+ ipv6_address_ = ipv6_address;
+ return *this;
+}
+
+boost::asio::ip::address_v4 address::to_v4() const
+{
+ if (type_ != ipv4)
+ {
+ std::bad_cast ex;
+ boost::throw_exception(ex);
+ }
+ return ipv4_address_;
+}
+
+boost::asio::ip::address_v6 address::to_v6() const
+{
+ if (type_ != ipv6)
+ {
+ std::bad_cast ex;
+ boost::throw_exception(ex);
+ }
+ return ipv6_address_;
+}
+
+std::string address::to_string() const
+{
+ if (type_ == ipv6)
+ return ipv6_address_.to_string();
+ return ipv4_address_.to_string();
+}
+
+std::string address::to_string(boost::system::error_code& ec) const
+{
+ if (type_ == ipv6)
+ return ipv6_address_.to_string(ec);
+ return ipv4_address_.to_string(ec);
+}
+
+address address::from_string(const char* str)
+{
+ boost::system::error_code ec;
+ address addr = from_string(str, ec);
+ boost::asio::detail::throw_error(ec);
+ return addr;
+}
+
+address address::from_string(const char* str, boost::system::error_code& ec)
+{
+ boost::asio::ip::address_v6 ipv6_address =
+ boost::asio::ip::address_v6::from_string(str, ec);
+ if (!ec)
+ {
+ address tmp;
+ tmp.type_ = ipv6;
+ tmp.ipv6_address_ = ipv6_address;
+ return tmp;
+ }
+
+ boost::asio::ip::address_v4 ipv4_address =
+ boost::asio::ip::address_v4::from_string(str, ec);
+ if (!ec)
+ {
+ address tmp;
+ tmp.type_ = ipv4;
+ tmp.ipv4_address_ = ipv4_address;
+ return tmp;
+ }
+
+ return address();
+}
+
+address address::from_string(const std::string& str)
+{
+ return from_string(str.c_str());
+}
+
+address address::from_string(const std::string& str,
+ boost::system::error_code& ec)
+{
+ return from_string(str.c_str(), ec);
+}
+
+bool operator==(const address& a1, const address& a2)
+{
+ if (a1.type_ != a2.type_)
+ return false;
+ if (a1.type_ == address::ipv6)
+ return a1.ipv6_address_ == a2.ipv6_address_;
+ return a1.ipv4_address_ == a2.ipv4_address_;
+}
+
+bool operator<(const address& a1, const address& a2)
+{
+ if (a1.type_ < a2.type_)
+ return true;
+ if (a1.type_ > a2.type_)
+ return false;
+ if (a1.type_ == address::ipv6)
+ return a1.ipv6_address_ < a2.ipv6_address_;
+ return a1.ipv4_address_ < a2.ipv4_address_;
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_IPP

Added: trunk/boost/asio/ip/impl/address_v4.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address_v4.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,55 @@
+//
+// ip/impl/address_v4.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_IP_IMPL_ADDRESS_V4_HPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_V4_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+template <typename Elem, typename Traits>
+std::basic_ostream<Elem, Traits>& operator<<(
+ std::basic_ostream<Elem, Traits>& os, const address_v4& addr)
+{
+ boost::system::error_code ec;
+ std::string s = addr.to_string(ec);
+ if (ec)
+ {
+ if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit)
+ boost::asio::detail::throw_error(ec);
+ else
+ os.setstate(std::basic_ostream<Elem, Traits>::failbit);
+ }
+ else
+ for (std::string::iterator i = s.begin(); i != s.end(); ++i)
+ os << os.widen(*i);
+ return os;
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V4_HPP

Added: trunk/boost/asio/ip/impl/address_v4.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address_v4.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,164 @@
+//
+// ip/impl/address_v4.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IP_IMPL_ADDRESS_V4_IPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_V4_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <climits>
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/ip/address_v4.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+address_v4::address_v4(const address_v4::bytes_type& bytes)
+{
+#if UCHAR_MAX > 0xFF
+ if (bytes[0] > 0xFF || bytes[1] > 0xFF
+ || bytes[2] > 0xFF || bytes[3] > 0xFF)
+ {
+ std::out_of_range ex("address_v4 from bytes_type");
+ boost::throw_exception(ex);
+ }
+#endif // UCHAR_MAX > 0xFF
+
+ using namespace std; // For memcpy.
+ memcpy(&addr_.s_addr, bytes.elems, 4);
+}
+
+address_v4::address_v4(unsigned long addr)
+{
+#if ULONG_MAX > 0xFFFFFFFF
+ if (addr > 0xFFFFFFFF)
+ {
+ std::out_of_range ex("address_v4 from unsigned long");
+ boost::throw_exception(ex);
+ }
+#endif // ULONG_MAX > 0xFFFFFFFF
+
+ addr_.s_addr = boost::asio::detail::socket_ops::host_to_network_long(addr);
+}
+
+address_v4::bytes_type address_v4::to_bytes() const
+{
+ using namespace std; // For memcpy.
+ bytes_type bytes;
+ memcpy(bytes.elems, &addr_.s_addr, 4);
+ return bytes;
+}
+
+unsigned long address_v4::to_ulong() const
+{
+ return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr);
+}
+
+std::string address_v4::to_string() const
+{
+ boost::system::error_code ec;
+ std::string addr = to_string(ec);
+ boost::asio::detail::throw_error(ec);
+ return addr;
+}
+
+std::string address_v4::to_string(boost::system::error_code& ec) const
+{
+ char addr_str[boost::asio::detail::max_addr_v4_str_len];
+ const char* addr =
+ boost::asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str,
+ boost::asio::detail::max_addr_v4_str_len, 0, ec);
+ if (addr == 0)
+ return std::string();
+ return addr;
+}
+
+address_v4 address_v4::from_string(const char* str)
+{
+ boost::system::error_code ec;
+ address_v4 addr = from_string(str, ec);
+ boost::asio::detail::throw_error(ec);
+ return addr;
+}
+
+address_v4 address_v4::from_string(
+ const char* str, boost::system::error_code& ec)
+{
+ address_v4 tmp;
+ if (boost::asio::detail::socket_ops::inet_pton(
+ AF_INET, str, &tmp.addr_, 0, ec) <= 0)
+ return address_v4();
+ return tmp;
+}
+
+address_v4 address_v4::from_string(const std::string& str)
+{
+ return from_string(str.c_str());
+}
+
+address_v4 address_v4::from_string(
+ const std::string& str, boost::system::error_code& ec)
+{
+ return from_string(str.c_str(), ec);
+}
+
+bool address_v4::is_class_a() const
+{
+ return IN_CLASSA(to_ulong());
+}
+
+bool address_v4::is_class_b() const
+{
+ return IN_CLASSB(to_ulong());
+}
+
+bool address_v4::is_class_c() const
+{
+ return IN_CLASSC(to_ulong());
+}
+
+bool address_v4::is_multicast() const
+{
+ return IN_MULTICAST(to_ulong());
+}
+
+address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask)
+{
+ return address_v4(addr.to_ulong() | ~mask.to_ulong());
+}
+
+address_v4 address_v4::netmask(const address_v4& addr)
+{
+ if (addr.is_class_a())
+ return address_v4(0xFF000000);
+ if (addr.is_class_b())
+ return address_v4(0xFFFF0000);
+ if (addr.is_class_c())
+ return address_v4(0xFFFFFF00);
+ return address_v4(0xFFFFFFFF);
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V4_IPP

Added: trunk/boost/asio/ip/impl/address_v6.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address_v6.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,55 @@
+//
+// ip/impl/address_v6.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_IP_IMPL_ADDRESS_V6_HPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_V6_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+template <typename Elem, typename Traits>
+std::basic_ostream<Elem, Traits>& operator<<(
+ std::basic_ostream<Elem, Traits>& os, const address_v6& addr)
+{
+ boost::system::error_code ec;
+ std::string s = addr.to_string(ec);
+ if (ec)
+ {
+ if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit)
+ boost::asio::detail::throw_error(ec);
+ else
+ os.setstate(std::basic_ostream<Elem, Traits>::failbit);
+ }
+ else
+ for (std::string::iterator i = s.begin(); i != s.end(); ++i)
+ os << os.widen(*i);
+ return os;
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_HPP

Added: trunk/boost/asio/ip/impl/address_v6.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/address_v6.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,286 @@
+//
+// ip/impl/address_v6.ipp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IP_IMPL_ADDRESS_V6_IPP
+#define BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <cstring>
+#include <stdexcept>
+#include <typeinfo>
+#include <boost/throw_exception.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ip/address_v6.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+address_v6::address_v6()
+ : scope_id_(0)
+{
+ boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_ANY_INIT;
+ addr_ = tmp_addr;
+}
+
+address_v6::address_v6(const address_v6::bytes_type& bytes,
+ unsigned long scope_id)
+ : scope_id_(scope_id)
+{
+#if UCHAR_MAX > 0xFF
+ for (std::size_t i = 0; i < bytes.size(); ++i)
+ {
+ if (bytes[i] > 0xFF)
+ {
+ std::out_of_range ex("address_v6 from bytes_type");
+ boost::throw_exception(ex);
+ }
+ }
+#endif // UCHAR_MAX > 0xFF
+
+ using namespace std; // For memcpy.
+ memcpy(addr_.s6_addr, bytes.elems, 16);
+}
+
+address_v6::address_v6(const address_v6& other)
+ : addr_(other.addr_),
+ scope_id_(other.scope_id_)
+{
+}
+
+address_v6& address_v6::operator=(const address_v6& other)
+{
+ addr_ = other.addr_;
+ scope_id_ = other.scope_id_;
+ return *this;
+}
+
+address_v6::bytes_type address_v6::to_bytes() const
+{
+ using namespace std; // For memcpy.
+ bytes_type bytes;
+ memcpy(bytes.elems, addr_.s6_addr, 16);
+ return bytes;
+}
+
+std::string address_v6::to_string() const
+{
+ boost::system::error_code ec;
+ std::string addr = to_string(ec);
+ boost::asio::detail::throw_error(ec);
+ return addr;
+}
+
+std::string address_v6::to_string(boost::system::error_code& ec) const
+{
+ char addr_str[boost::asio::detail::max_addr_v6_str_len];
+ const char* addr =
+ boost::asio::detail::socket_ops::inet_ntop(AF_INET6, &addr_, addr_str,
+ boost::asio::detail::max_addr_v6_str_len, scope_id_, ec);
+ if (addr == 0)
+ return std::string();
+ return addr;
+}
+
+address_v6 address_v6::from_string(const char* str)
+{
+ boost::system::error_code ec;
+ address_v6 addr = from_string(str, ec);
+ boost::asio::detail::throw_error(ec);
+ return addr;
+}
+
+address_v6 address_v6::from_string(
+ const char* str, boost::system::error_code& ec)
+{
+ address_v6 tmp;
+ if (boost::asio::detail::socket_ops::inet_pton(
+ AF_INET6, str, &tmp.addr_, &tmp.scope_id_, ec) <= 0)
+ return address_v6();
+ return tmp;
+}
+
+address_v6 address_v6::from_string(const std::string& str)
+{
+ return from_string(str.c_str());
+}
+
+address_v6 address_v6::from_string(
+ const std::string& str, boost::system::error_code& ec)
+{
+ return from_string(str.c_str(), ec);
+}
+
+address_v4 address_v6::to_v4() const
+{
+ if (!is_v4_mapped() && !is_v4_compatible())
+ {
+ std::bad_cast ex;
+ boost::throw_exception(ex);
+ }
+
+ address_v4::bytes_type v4_bytes = { { addr_.s6_addr[12],
+ addr_.s6_addr[13], addr_.s6_addr[14], addr_.s6_addr[15] } };
+ return address_v4(v4_bytes);
+}
+
+bool address_v6::is_loopback() const
+{
+#if defined(__BORLANDC__)
+ return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
+ && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
+ && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
+ && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
+ && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
+ && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
+ && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
+ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
+#else
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_LOOPBACK(&addr_) != 0;
+#endif
+}
+
+bool address_v6::is_unspecified() const
+{
+#if defined(__BORLANDC__)
+ return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
+ && (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
+ && (addr_.s6_addr[4] == 0) && (addr_.s6_addr[5] == 0)
+ && (addr_.s6_addr[6] == 0) && (addr_.s6_addr[7] == 0)
+ && (addr_.s6_addr[8] == 0) && (addr_.s6_addr[9] == 0)
+ && (addr_.s6_addr[10] == 0) && (addr_.s6_addr[11] == 0)
+ && (addr_.s6_addr[12] == 0) && (addr_.s6_addr[13] == 0)
+ && (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
+#else
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_UNSPECIFIED(&addr_) != 0;
+#endif
+}
+
+bool address_v6::is_link_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_LINKLOCAL(&addr_) != 0;
+}
+
+bool address_v6::is_site_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_SITELOCAL(&addr_) != 0;
+}
+
+bool address_v6::is_v4_mapped() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_V4MAPPED(&addr_) != 0;
+}
+
+bool address_v6::is_v4_compatible() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_V4COMPAT(&addr_) != 0;
+}
+
+bool address_v6::is_multicast() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MULTICAST(&addr_) != 0;
+}
+
+bool address_v6::is_multicast_global() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MC_GLOBAL(&addr_) != 0;
+}
+
+bool address_v6::is_multicast_link_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MC_LINKLOCAL(&addr_) != 0;
+}
+
+bool address_v6::is_multicast_node_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MC_NODELOCAL(&addr_) != 0;
+}
+
+bool address_v6::is_multicast_org_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MC_ORGLOCAL(&addr_) != 0;
+}
+
+bool address_v6::is_multicast_site_local() const
+{
+ using namespace boost::asio::detail;
+ return IN6_IS_ADDR_MC_SITELOCAL(&addr_) != 0;
+}
+
+bool operator==(const address_v6& a1, const address_v6& a2)
+{
+ using namespace std; // For memcmp.
+ return memcmp(&a1.addr_, &a2.addr_,
+ sizeof(boost::asio::detail::in6_addr_type)) == 0
+ && a1.scope_id_ == a2.scope_id_;
+}
+
+bool operator<(const address_v6& a1, const address_v6& a2)
+{
+ using namespace std; // For memcmp.
+ int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
+ sizeof(boost::asio::detail::in6_addr_type));
+ if (memcmp_result < 0)
+ return true;
+ if (memcmp_result > 0)
+ return false;
+ return a1.scope_id_ < a2.scope_id_;
+}
+
+address_v6 address_v6::loopback()
+{
+ address_v6 tmp;
+ boost::asio::detail::in6_addr_type tmp_addr = IN6ADDR_LOOPBACK_INIT;
+ tmp.addr_ = tmp_addr;
+ return tmp;
+}
+
+address_v6 address_v6::v4_mapped(const address_v4& addr)
+{
+ address_v4::bytes_type v4_bytes = addr.to_bytes();
+ bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF,
+ v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
+ return address_v6(v6_bytes);
+}
+
+address_v6 address_v6::v4_compatible(const address_v4& addr)
+{
+ address_v4::bytes_type v4_bytes = addr.to_bytes();
+ bytes_type v6_bytes = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ v4_bytes[0], v4_bytes[1], v4_bytes[2], v4_bytes[3] } };
+ return address_v6(v6_bytes);
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_IMPL_ADDRESS_V6_IPP

Added: trunk/boost/asio/ip/impl/basic_endpoint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/basic_endpoint.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,57 @@
+//
+// ip/impl/basic_endpoint.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_IP_IMPL_BASIC_ENDPOINT_HPP
+#define BOOST_ASIO_IP_IMPL_BASIC_ENDPOINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#if !defined(BOOST_NO_IOSTREAM)
+
+#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+template <typename Elem, typename Traits, typename InternetProtocol>
+std::basic_ostream<Elem, Traits>& operator<<(
+ std::basic_ostream<Elem, Traits>& os,
+ const basic_endpoint<InternetProtocol>& endpoint)
+{
+ boost::asio::ip::detail::endpoint tmp_ep(endpoint.address(), endpoint.port());
+ boost::system::error_code ec;
+ std::string s = tmp_ep.to_string(ec);
+ if (ec)
+ {
+ if (os.exceptions() & std::basic_ostream<Elem, Traits>::failbit)
+ boost::asio::detail::throw_error(ec);
+ else
+ os.setstate(std::basic_ostream<Elem, Traits>::failbit);
+ }
+ else
+ for (std::string::iterator i = s.begin(); i != s.end(); ++i)
+ os << os.widen(*i);
+ return os;
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#endif // BOOST_ASIO_IP_IMPL_BASIC_ENDPOINT_HPP

Added: trunk/boost/asio/ip/impl/host_name.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/ip/impl/host_name.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,56 @@
+//
+// ip/impl/host_name.ipp
+// ~~~~~~~~~~~~~~~~~~~~~
+//
+// 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_IP_IMPL_HOST_NAME_IPP
+#define BOOST_ASIO_IP_IMPL_HOST_NAME_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/winsock_init.hpp>
+#include <boost/asio/ip/host_name.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace ip {
+
+std::string host_name()
+{
+ char name[1024];
+ boost::system::error_code ec;
+ if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0)
+ {
+ boost::asio::detail::throw_error(ec);
+ return std::string();
+ }
+ return std::string(name);
+}
+
+std::string host_name(boost::system::error_code& ec)
+{
+ char name[1024];
+ if (boost::asio::detail::socket_ops::gethostname(name, sizeof(name), ec) != 0)
+ return std::string();
+ return std::string(name);
+}
+
+} // namespace ip
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IP_IMPL_HOST_NAME_IPP

Modified: trunk/boost/asio/ip/multicast.hpp
==============================================================================
--- trunk/boost/asio/ip/multicast.hpp (original)
+++ trunk/boost/asio/ip/multicast.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// multicast.hpp
-// ~~~~~~~~~~~~~
+// ip/multicast.hpp
+// ~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,12 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/ip/detail/socket_option.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {

Modified: trunk/boost/asio/ip/resolver_query_base.hpp
==============================================================================
--- trunk/boost/asio/ip/resolver_query_base.hpp (original)
+++ trunk/boost/asio/ip/resolver_query_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// resolver_query_base.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// ip/resolver_query_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,12 @@
 # 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/config.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {

Modified: trunk/boost/asio/ip/resolver_service.hpp
==============================================================================
--- trunk/boost/asio/ip/resolver_service.hpp (original)
+++ trunk/boost/asio/ip/resolver_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// resolver_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// ip/resolver_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/error.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/asio/detail/resolver_service.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/detail/resolver_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -73,13 +73,14 @@
   explicit resolver_service(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
         resolver_service<InternetProtocol> >(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 resolver implementation.
@@ -131,8 +132,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 ip

Modified: trunk/boost/asio/ip/tcp.hpp
==============================================================================
--- trunk/boost/asio/ip/tcp.hpp (original)
+++ trunk/boost/asio/ip/tcp.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// tcp.hpp
-// ~~~~~~~
+// ip/tcp.hpp
+// ~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_socket_acceptor.hpp>
 #include <boost/asio/basic_socket_iostream.hpp>
 #include <boost/asio/basic_stream_socket.hpp>
+#include <boost/asio/detail/socket_option.hpp>
+#include <boost/asio/detail/socket_types.hpp>
 #include <boost/asio/ip/basic_endpoint.hpp>
 #include <boost/asio/ip/basic_resolver.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/detail/socket_option.hpp>
-#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ip/udp.hpp
==============================================================================
--- trunk/boost/asio/ip/udp.hpp (original)
+++ trunk/boost/asio/ip/udp.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// udp.hpp
-// ~~~~~~~
+// ip/udp.hpp
+// ~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,15 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_datagram_socket.hpp>
+#include <boost/asio/detail/socket_types.hpp>
 #include <boost/asio/ip/basic_endpoint.hpp>
 #include <boost/asio/ip/basic_resolver.hpp>
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ip/unicast.hpp
==============================================================================
--- trunk/boost/asio/ip/unicast.hpp (original)
+++ trunk/boost/asio/ip/unicast.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// unicast.hpp
-// ~~~~~~~~~~~
+// ip/unicast.hpp
+// ~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,12 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/ip/detail/socket_option.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {

Modified: trunk/boost/asio/ip/v6_only.hpp
==============================================================================
--- trunk/boost/asio/ip/v6_only.hpp (original)
+++ trunk/boost/asio/ip/v6_only.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// v6_only.hpp
-// ~~~~~~~~~~~
+// ip/v6_only.hpp
+// ~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,10 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/detail/socket_option.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ip {

Modified: trunk/boost/asio/is_read_buffered.hpp
==============================================================================
--- trunk/boost/asio/is_read_buffered.hpp (original)
+++ trunk/boost/asio/is_read_buffered.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,15 +15,12 @@
 # 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>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/buffered_read_stream_fwd.hpp>
 #include <boost/asio/buffered_stream_fwd.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/is_write_buffered.hpp
==============================================================================
--- trunk/boost/asio/is_write_buffered.hpp (original)
+++ trunk/boost/asio/is_write_buffered.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,15 +15,12 @@
 # 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>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/buffered_stream_fwd.hpp>
 #include <boost/asio/buffered_write_stream_fwd.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/local/basic_endpoint.hpp
==============================================================================
--- trunk/boost/asio/local/basic_endpoint.hpp (original)
+++ trunk/boost/asio/local/basic_endpoint.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_endpoint.hpp
-// ~~~~~~~~~~~~~~~~~~
+// local/basic_endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 // Derived from a public domain implementation written by Daniel Casimiro.
@@ -16,30 +16,18 @@
 # 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/throw_exception.hpp>
-#include <cstddef>
-#include <cstring>
-#include <ostream>
-#include <boost/system/system_error.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/detail/socket_ops.hpp>
-#include <boost/asio/detail/socket_types.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-
-#if !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
-# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-# define BOOST_ASIO_HAS_LOCAL_SOCKETS 1
-# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-#endif // !defined(BOOST_ASIO_DISABLE_LOCAL_SOCKETS)
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <boost/asio/local/detail/endpoint.hpp>
+
+#if !defined(BOOST_NO_IOSTREAM)
+# include <iosfwd>
+#endif // !defined(BOOST_NO_IOSTREAM)
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -75,34 +63,30 @@
   /// Default constructor.
   basic_endpoint()
   {
- init("", 0);
   }
 
   /// Construct an endpoint using the specified path name.
   basic_endpoint(const char* path)
+ : impl_(path)
   {
- using namespace std; // For strlen.
- init(path, strlen(path));
   }
 
   /// Construct an endpoint using the specified path name.
   basic_endpoint(const std::string& path)
+ : impl_(path)
   {
- init(path.data(), path.length());
   }
 
   /// Copy constructor.
   basic_endpoint(const basic_endpoint& other)
- : data_(other.data_),
- path_length_(other.path_length_)
+ : impl_(other.impl_)
   {
   }
 
   /// Assign from another endpoint.
   basic_endpoint& operator=(const basic_endpoint& other)
   {
- data_ = other.data_;
- path_length_ = other.path_length_;
+ impl_ = other.impl_;
     return *this;
   }
 
@@ -115,123 +99,96 @@
   /// Get the underlying endpoint in the native type.
   data_type* data()
   {
- return &data_.base;
+ return impl_.data();
   }
 
   /// Get the underlying endpoint in the native type.
   const data_type* data() const
   {
- return &data_.base;
+ return impl_.data();
   }
 
   /// Get the underlying size of the endpoint in the native type.
   std::size_t size() const
   {
- return path_length_
- + offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
+ return impl_.size();
   }
 
   /// Set the underlying size of the endpoint in the native type.
   void resize(std::size_t size)
   {
- if (size > sizeof(boost::asio::detail::sockaddr_un_type))
- {
- boost::system::system_error e(boost::asio::error::invalid_argument);
- boost::throw_exception(e);
- }
- else if (size == 0)
- {
- path_length_ = 0;
- }
- else
- {
- path_length_ = size
- - offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
-
- // The path returned by the operating system may be NUL-terminated.
- if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0)
- --path_length_;
- }
+ impl_.resize(size);
   }
 
   /// Get the capacity of the endpoint in the native type.
   std::size_t capacity() const
   {
- return sizeof(boost::asio::detail::sockaddr_un_type);
+ return impl_.capacity();
   }
 
   /// Get the path associated with the endpoint.
   std::string path() const
   {
- return std::string(data_.local.sun_path, path_length_);
+ return impl_.path();
   }
 
   /// Set the path associated with the endpoint.
   void path(const char* p)
   {
- using namespace std; // For strlen.
- init(p, strlen(p));
+ impl_.path(p);
   }
 
   /// Set the path associated with the endpoint.
   void path(const std::string& p)
   {
- init(p.data(), p.length());
+ impl_.path(p);
   }
 
   /// Compare two endpoints for equality.
   friend bool operator==(const basic_endpoint<Protocol>& e1,
       const basic_endpoint<Protocol>& e2)
   {
- return e1.path() == e2.path();
+ return e1.impl_ == e2.impl_;
   }
 
   /// Compare two endpoints for inequality.
   friend bool operator!=(const basic_endpoint<Protocol>& e1,
       const basic_endpoint<Protocol>& e2)
   {
- return e1.path() != e2.path();
+ return !(e1.impl_ == e2.impl_);
   }
 
   /// Compare endpoints for ordering.
   friend bool operator<(const basic_endpoint<Protocol>& e1,
       const basic_endpoint<Protocol>& e2)
   {
- return e1.path() < e2.path();
+ return e1.impl_ < e2.impl_;
   }
 
-private:
- // The underlying UNIX socket address.
- union data_union
+ /// Compare endpoints for ordering.
+ friend bool operator>(const basic_endpoint<Protocol>& e1,
+ const basic_endpoint<Protocol>& e2)
   {
- boost::asio::detail::socket_addr_type base;
- boost::asio::detail::sockaddr_un_type local;
- } data_;
-
- // The length of the path associated with the endpoint.
- std::size_t path_length_;
-
- // Initialise with a specified path.
- void init(const char* path, std::size_t path_length)
- {
- if (path_length > sizeof(data_.local.sun_path) - 1)
- {
- // The buffer is not large enough to store this address.
- boost::system::error_code ec(boost::asio::error::name_too_long);
- boost::asio::detail::throw_error(ec);
- }
-
- using namespace std; // For memcpy.
- data_.local = boost::asio::detail::sockaddr_un_type();
- data_.local.sun_family = AF_UNIX;
- memcpy(data_.local.sun_path, path, path_length);
- path_length_ = path_length;
-
- // NUL-terminate normal path names. Names that start with a NUL are in the
- // UNIX domain protocol's "abstract namespace" and are not NUL-terminated.
- if (path_length > 0 && data_.local.sun_path[0] == 0)
- data_.local.sun_path[path_length] = 0;
+ return e2.impl_ < e1.impl_;
   }
+
+ /// Compare endpoints for ordering.
+ friend bool operator<=(const basic_endpoint<Protocol>& e1,
+ const basic_endpoint<Protocol>& e2)
+ {
+ return !(e2 < e1);
+ }
+
+ /// Compare endpoints for ordering.
+ friend bool operator>=(const basic_endpoint<Protocol>& e1,
+ const basic_endpoint<Protocol>& e2)
+ {
+ return !(e1 < e2);
+ }
+
+private:
+ // The underlying UNIX domain endpoint.
+ boost::asio::local::detail::endpoint impl_;
 };
 
 /// Output an endpoint as a string.
@@ -259,9 +216,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_LOCAL_BASIC_ENDPOINT_HPP

Modified: trunk/boost/asio/local/connect_pair.hpp
==============================================================================
--- trunk/boost/asio/local/connect_pair.hpp (original)
+++ trunk/boost/asio/local/connect_pair.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// connect_pair.hpp
-// ~~~~~~~~~~~~~~~~
+// local/connect_pair.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/basic_socket.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
 #include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/local/basic_endpoint.hpp>
 
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -74,8 +76,9 @@
   if (socket1.assign(protocol, sv[0], ec))
   {
     boost::system::error_code temp_ec;
- boost::asio::detail::socket_ops::close(sv[0], temp_ec);
- boost::asio::detail::socket_ops::close(sv[1], temp_ec);
+ boost::asio::detail::socket_ops::state_type state[2] = { 0, 0 };
+ boost::asio::detail::socket_ops::close(sv[0], state[0], true, temp_ec);
+ boost::asio::detail::socket_ops::close(sv[1], state[1], true, temp_ec);
     return ec;
   }
 
@@ -83,7 +86,8 @@
   {
     boost::system::error_code temp_ec;
     socket1.close(temp_ec);
- boost::asio::detail::socket_ops::close(sv[1], temp_ec);
+ boost::asio::detail::socket_ops::state_type state = 0;
+ boost::asio::detail::socket_ops::close(sv[1], state, true, temp_ec);
     return ec;
   }
 
@@ -94,9 +98,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_LOCAL_CONNECT_PAIR_HPP

Modified: trunk/boost/asio/local/datagram_protocol.hpp
==============================================================================
--- trunk/boost/asio/local/datagram_protocol.hpp (original)
+++ trunk/boost/asio/local/datagram_protocol.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// datagram_protocol.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// local/datagram_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,14 +15,16 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/basic_datagram_socket.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/local/basic_endpoint.hpp>
 
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -72,9 +74,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_LOCAL_DATAGRAM_PROTOCOL_HPP

Added: trunk/boost/asio/local/detail/endpoint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/local/detail/endpoint.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,135 @@
+//
+// local/detail/endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Derived from a public domain implementation written by Daniel Casimiro.
+//
+// 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_LOCAL_DETAIL_ENDPOINT_HPP
+#define BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+#include <cstddef>
+#include <string>
+#include <boost/asio/detail/socket_types.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace local {
+namespace detail {
+
+// Helper class for implementing a UNIX domain endpoint.
+class endpoint
+{
+public:
+ // Default constructor.
+ BOOST_ASIO_DECL endpoint();
+
+ // Construct an endpoint using the specified path name.
+ BOOST_ASIO_DECL endpoint(const char* path);
+
+ // Construct an endpoint using the specified path name.
+ BOOST_ASIO_DECL endpoint(const std::string& path);
+
+ // Copy constructor.
+ endpoint(const endpoint& other)
+ : data_(other.data_),
+ path_length_(other.path_length_)
+ {
+ }
+
+ // Assign from another endpoint.
+ endpoint& operator=(const endpoint& other)
+ {
+ data_ = other.data_;
+ path_length_ = other.path_length_;
+ return *this;
+ }
+
+ // Get the underlying endpoint in the native type.
+ boost::asio::detail::socket_addr_type* data()
+ {
+ return &data_.base;
+ }
+
+ // Get the underlying endpoint in the native type.
+ const boost::asio::detail::socket_addr_type* data() const
+ {
+ return &data_.base;
+ }
+
+ // Get the underlying size of the endpoint in the native type.
+ std::size_t size() const
+ {
+ return path_length_
+ + offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
+ }
+
+ // Set the underlying size of the endpoint in the native type.
+ BOOST_ASIO_DECL void resize(std::size_t size);
+
+ // Get the capacity of the endpoint in the native type.
+ std::size_t capacity() const
+ {
+ return sizeof(boost::asio::detail::sockaddr_un_type);
+ }
+
+ // Get the path associated with the endpoint.
+ BOOST_ASIO_DECL std::string path() const;
+
+ // Set the path associated with the endpoint.
+ BOOST_ASIO_DECL void path(const char* p);
+
+ // Set the path associated with the endpoint.
+ BOOST_ASIO_DECL void path(const std::string& p);
+
+ // Compare two endpoints for equality.
+ BOOST_ASIO_DECL friend bool operator==(
+ const endpoint& e1, const endpoint& e2);
+
+ // Compare endpoints for ordering.
+ BOOST_ASIO_DECL friend bool operator<(
+ const endpoint& e1, const endpoint& e2);
+
+private:
+ // The underlying UNIX socket address.
+ union data_union
+ {
+ boost::asio::detail::socket_addr_type base;
+ boost::asio::detail::sockaddr_un_type local;
+ } data_;
+
+ // The length of the path associated with the endpoint.
+ std::size_t path_length_;
+
+ // Initialise with a specified path.
+ BOOST_ASIO_DECL void init(const char* path, std::size_t path_length);
+};
+
+} // namespace detail
+} // namespace local
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/local/detail/impl/endpoint.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+#endif // BOOST_ASIO_LOCAL_DETAIL_ENDPOINT_HPP

Added: trunk/boost/asio/local/detail/impl/endpoint.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/asio/local/detail/impl/endpoint.ipp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -0,0 +1,130 @@
+//
+// local/detail/impl/endpoint.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Derived from a public domain implementation written by Daniel Casimiro.
+//
+// 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_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
+#define BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+#include <cstring>
+#include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/local/detail/endpoint.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace local {
+namespace detail {
+
+endpoint::endpoint()
+{
+ init("", 0);
+}
+
+endpoint::endpoint(const char* path)
+{
+ using namespace std; // For strlen.
+ init(path, strlen(path));
+}
+
+endpoint::endpoint(const std::string& path)
+{
+ init(path.data(), path.length());
+}
+
+void endpoint::resize(std::size_t size)
+{
+ if (size > sizeof(boost::asio::detail::sockaddr_un_type))
+ {
+ boost::system::error_code ec(boost::asio::error::invalid_argument);
+ boost::asio::detail::throw_error(ec);
+ }
+ else if (size == 0)
+ {
+ path_length_ = 0;
+ }
+ else
+ {
+ path_length_ = size
+ - offsetof(boost::asio::detail::sockaddr_un_type, sun_path);
+
+ // The path returned by the operating system may be NUL-terminated.
+ if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0)
+ --path_length_;
+ }
+}
+
+std::string endpoint::path() const
+{
+ return std::string(data_.local.sun_path, path_length_);
+}
+
+void endpoint::path(const char* p)
+{
+ using namespace std; // For strlen.
+ init(p, strlen(p));
+}
+
+void endpoint::path(const std::string& p)
+{
+ init(p.data(), p.length());
+}
+
+bool operator==(const endpoint& e1, const endpoint& e2)
+{
+ return e1.path() == e2.path();
+}
+
+bool operator<(const endpoint& e1, const endpoint& e2)
+{
+ return e1.path() < e2.path();
+}
+
+void endpoint::init(const char* path, std::size_t path_length)
+{
+ if (path_length > sizeof(data_.local.sun_path) - 1)
+ {
+ // The buffer is not large enough to store this address.
+ boost::system::error_code ec(boost::asio::error::name_too_long);
+ boost::asio::detail::throw_error(ec);
+ }
+
+ using namespace std; // For memcpy.
+ data_.local = boost::asio::detail::sockaddr_un_type();
+ data_.local.sun_family = AF_UNIX;
+ memcpy(data_.local.sun_path, path, path_length);
+ path_length_ = path_length;
+
+ // NUL-terminate normal path names. Names that start with a NUL are in the
+ // UNIX domain protocol's "abstract namespace" and are not NUL-terminated.
+ if (path_length > 0 && data_.local.sun_path[0] == 0)
+ data_.local.sun_path[path_length] = 0;
+}
+
+} // namespace detail
+} // namespace local
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
+
+#endif // BOOST_ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP

Modified: trunk/boost/asio/local/stream_protocol.hpp
==============================================================================
--- trunk/boost/asio/local/stream_protocol.hpp (original)
+++ trunk/boost/asio/local/stream_protocol.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_protocol.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// local/stream_protocol.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/basic_socket_acceptor.hpp>
 #include <boost/asio/basic_socket_iostream.hpp>
 #include <boost/asio/basic_stream_socket.hpp>
-#include <boost/asio/local/basic_endpoint.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/local/basic_endpoint.hpp>
 
-#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -82,9 +84,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_HPP

Modified: trunk/boost/asio/placeholders.hpp
==============================================================================
--- trunk/boost/asio/placeholders.hpp (original)
+++ trunk/boost/asio/placeholders.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,12 +15,11 @@
 # 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/asio/detail/config.hpp>
 #include <boost/bind/arg.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/posix/basic_descriptor.hpp
==============================================================================
--- trunk/boost/asio/posix/basic_descriptor.hpp (original)
+++ trunk/boost/asio/posix/basic_descriptor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_descriptor.hpp
-// ~~~~~~~~~~~~~~~~~~~~
+// posix/basic_descriptor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,17 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/posix/descriptor_base.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -293,4 +294,7 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+ // || defined(GENERATING_DOCUMENTATION)
+
 #endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP

Modified: trunk/boost/asio/posix/basic_stream_descriptor.hpp
==============================================================================
--- trunk/boost/asio/posix/basic_stream_descriptor.hpp (original)
+++ trunk/boost/asio/posix/basic_stream_descriptor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_stream_descriptor.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// posix/basic_stream_descriptor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
+ || defined(GENERATING_DOCUMENTATION)
 
+#include <cstddef>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/posix/basic_descriptor.hpp>
 #include <boost/asio/posix/stream_descriptor_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
 
-#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -298,9 +296,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP

Modified: trunk/boost/asio/posix/descriptor_base.hpp
==============================================================================
--- trunk/boost/asio/posix/descriptor_base.hpp (original)
+++ trunk/boost/asio/posix/descriptor_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// descriptor_base.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// posix/descriptor_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,16 +15,16 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/detail/io_control.hpp>
 #include <boost/asio/detail/socket_option.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace posix {
@@ -92,4 +92,7 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
+ // || defined(GENERATING_DOCUMENTATION)
+
 #endif // BOOST_ASIO_POSIX_DESCRIPTOR_BASE_HPP

Modified: trunk/boost/asio/posix/stream_descriptor.hpp
==============================================================================
--- trunk/boost/asio/posix/stream_descriptor.hpp (original)
+++ trunk/boost/asio/posix/stream_descriptor.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_descriptor.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// posix/stream_descriptor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/posix/basic_stream_descriptor.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <boost/asio/posix/basic_stream_descriptor.hpp>
+
 namespace boost {
 namespace asio {
 namespace posix {
@@ -36,6 +36,4 @@
 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_descriptor_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// posix/stream_descriptor_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,28 +15,18 @@
 # 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/asio/detail/pop_options.hpp>
-
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
-
-#if !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
-# if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-# define BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR 1
-# endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-#endif // !defined(BOOST_ASIO_DISABLE_POSIX_STREAM_DESCRIPTOR)
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <cstddef>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/reactive_descriptor_service.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace posix {
@@ -181,9 +171,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP

Modified: trunk/boost/asio/raw_socket_service.hpp
==============================================================================
--- trunk/boost/asio/raw_socket_service.hpp (original)
+++ trunk/boost/asio/raw_socket_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,10 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
@@ -32,6 +26,8 @@
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/read.hpp
==============================================================================
--- trunk/boost/asio/read.hpp (original)
+++ trunk/boost/asio/read.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/basic_streambuf_fwd.hpp>
 #include <boost/asio/error.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -538,8 +535,8 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/read.ipp>
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/impl/read.hpp>
+
 #endif // BOOST_ASIO_READ_HPP

Modified: trunk/boost/asio/read_at.hpp
==============================================================================
--- trunk/boost/asio/read_at.hpp (original)
+++ trunk/boost/asio/read_at.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/basic_streambuf_fwd.hpp>
 #include <boost/asio/error.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -571,8 +568,8 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/read_at.ipp>
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/impl/read_at.hpp>
+
 #endif // BOOST_ASIO_READ_AT_HPP

Modified: trunk/boost/asio/read_until.hpp
==============================================================================
--- trunk/boost/asio/read_until.hpp (original)
+++ trunk/boost/asio/read_until.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,27 +15,22 @@
 # 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>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
-#include <boost/regex.hpp>
 #include <boost/type_traits/is_function.hpp>
 #include <boost/type_traits/remove_pointer.hpp>
 #include <boost/utility/enable_if.hpp>
 #include <boost/detail/workaround.hpp>
 #include <string>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/detail/regex_fwd.hpp>
 #include <boost/asio/error.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -916,10 +911,10 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/read_until.ipp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/read_until.hpp>
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_READ_UNTIL_HPP

Modified: trunk/boost/asio/serial_port.hpp
==============================================================================
--- trunk/boost/asio/serial_port.hpp (original)
+++ trunk/boost/asio/serial_port.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,13 +16,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/basic_serial_port.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <boost/asio/basic_serial_port.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -35,6 +35,4 @@
 #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_SERIAL_PORT_HPP

Modified: trunk/boost/asio/serial_port_base.hpp
==============================================================================
--- trunk/boost/asio/serial_port_base.hpp (original)
+++ trunk/boost/asio/serial_port_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,32 +16,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-#include <stdexcept>
-#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#if !defined(BOOST_ASIO_DISABLE_SERIAL_PORT)
-# if defined(BOOST_ASIO_HAS_IOCP) \
- || !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-# define BOOST_ASIO_HAS_SERIAL_PORT 1
-# endif // defined(BOOST_ASIO_HAS_IOCP)
-#endif // !defined(BOOST_ASIO_DISABLE_STREAM_HANDLE)
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
   || defined(GENERATING_DOCUMENTATION)
 
 #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
-# include <boost/asio/detail/push_options.hpp>
 # include <termios.h>
-# include <boost/asio/detail/pop_options.hpp>
 #endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
 
+#include <boost/detail/workaround.hpp>
 #include <boost/asio/detail/socket_types.hpp>
+#include <boost/system/error_code.hpp>
 
 #if defined(GENERATING_DOCUMENTATION)
 # define BOOST_ASIO_OPTION_STORAGE implementation_defined
@@ -51,6 +37,8 @@
 # define BOOST_ASIO_OPTION_STORAGE termios
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -68,9 +56,11 @@
   public:
     explicit baud_rate(unsigned int rate = 0);
     unsigned int value() const;
- boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code store(
+ BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec) const;
- boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code load(
+ const BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec);
   private:
     unsigned int value_;
@@ -84,11 +74,13 @@
   {
   public:
     enum type { none, software, hardware };
- explicit flow_control(type t = none);
+ BOOST_ASIO_DECL explicit flow_control(type t = none);
     type value() const;
- boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code store(
+ BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec) const;
- boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code load(
+ const BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec);
   private:
     type value_;
@@ -102,11 +94,13 @@
   {
   public:
     enum type { none, odd, even };
- explicit parity(type t = none);
+ BOOST_ASIO_DECL explicit parity(type t = none);
     type value() const;
- boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code store(
+ BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec) const;
- boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code load(
+ const BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec);
   private:
     type value_;
@@ -120,11 +114,13 @@
   {
   public:
     enum type { one, onepointfive, two };
- explicit stop_bits(type t = one);
+ BOOST_ASIO_DECL explicit stop_bits(type t = one);
     type value() const;
- boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code store(
+ BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec) const;
- boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code load(
+ const BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec);
   private:
     type value_;
@@ -137,11 +133,13 @@
   class character_size
   {
   public:
- explicit character_size(unsigned int t = 8);
+ BOOST_ASIO_DECL explicit character_size(unsigned int t = 8);
     unsigned int value() const;
- boost::system::error_code store(BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code store(
+ BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec) const;
- boost::system::error_code load(const BOOST_ASIO_OPTION_STORAGE& storage,
+ BOOST_ASIO_DECL boost::system::error_code load(
+ const BOOST_ASIO_OPTION_STORAGE& storage,
         boost::system::error_code& ec);
   private:
     unsigned int value_;
@@ -163,13 +161,16 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/serial_port_base.ipp>
+#include <boost/asio/detail/pop_options.hpp>
 
 #undef BOOST_ASIO_OPTION_STORAGE
 
+#include <boost/asio/impl/serial_port_base.hpp>
+#if defined(BOOST_ASIO_HEADER_ONLY)
+# include <boost/asio/impl/serial_port_base.ipp>
+#endif // defined(BOOST_ASIO_HEADER_ONLY)
+
 #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_SERIAL_PORT_BASE_HPP

Modified: trunk/boost/asio/serial_port_service.hpp
==============================================================================
--- trunk/boost/asio/serial_port_service.hpp (original)
+++ trunk/boost/asio/serial_port_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,23 +15,20 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
+ || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <string>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/reactive_serial_port_service.hpp>
+#include <boost/asio/detail/win_iocp_serial_port_service.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/serial_port_base.hpp>
-#include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/reactive_serial_port_service.hpp>
-#include <boost/asio/detail/win_iocp_serial_port_service.hpp>
 
-#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -201,9 +198,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_SERIAL_PORT_SERVICE_HPP

Modified: trunk/boost/asio/socket_acceptor_service.hpp
==============================================================================
--- trunk/boost/asio/socket_acceptor_service.hpp (original)
+++ trunk/boost/asio/socket_acceptor_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,12 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/basic_socket.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
@@ -28,6 +26,8 @@
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/socket_base.hpp
==============================================================================
--- trunk/boost/asio/socket_base.hpp (original)
+++ trunk/boost/asio/socket_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/config.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/io_control.hpp>
 #include <boost/asio/detail/socket_option.hpp>
 #include <boost/asio/detail/socket_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/ssl/basic_context.hpp
==============================================================================
--- trunk/boost/asio/ssl/basic_context.hpp (original)
+++ trunk/boost/asio/ssl/basic_context.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_context.hpp
-// ~~~~~~~~~~~~~~~~~
+// ssl/basic_context.hpp
+// ~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,17 +16,15 @@
 # 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/asio/detail/config.hpp>
 #include <string>
 #include <boost/noncopyable.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ssl/context_base.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ssl/context.hpp
==============================================================================
--- trunk/boost/asio/ssl/context.hpp (original)
+++ trunk/boost/asio/ssl/context.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// context.hpp
-// ~~~~~~~~~~~
+// ssl/context.hpp
+// ~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,8 +16,7 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
+#include <boost/asio/detail/config.hpp>
 #include <boost/asio/ssl/basic_context.hpp>
 #include <boost/asio/ssl/context_service.hpp>
 
@@ -32,6 +31,4 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_SSL_CONTEXT_HPP

Modified: trunk/boost/asio/ssl/context_base.hpp
==============================================================================
--- trunk/boost/asio/ssl/context_base.hpp (original)
+++ trunk/boost/asio/ssl/context_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// context_base.hpp
-// ~~~~~~~~~~~~~~~~
+// ssl/context_base.hpp
+// ~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,12 @@
 # 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/config.hpp>
 #include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/ssl/detail/openssl_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ssl {

Modified: trunk/boost/asio/ssl/context_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/context_service.hpp (original)
+++ trunk/boost/asio/ssl/context_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// context_service.hpp
-// ~~~~~~~~~~~~~~~~~~~
+// ssl/context_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,19 +16,16 @@
 # 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/asio/detail/config.hpp>
 #include <string>
 #include <boost/noncopyable.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/ssl/context_base.hpp>
 #include <boost/asio/ssl/detail/openssl_context_service.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ssl {

Modified: trunk/boost/asio/ssl/detail/openssl_context_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_context_service.hpp (original)
+++ trunk/boost/asio/ssl/detail/openssl_context_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// openssl_context_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// ssl/detail/openssl_context_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,21 +16,18 @@
 # 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/asio/detail/config.hpp>
 #include <cstring>
 #include <string>
 #include <boost/function.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/ssl/context_base.hpp>
 #include <boost/asio/ssl/detail/openssl_init.hpp>
 #include <boost/asio/ssl/detail/openssl_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ssl {

Modified: trunk/boost/asio/ssl/detail/openssl_init.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_init.hpp (original)
+++ trunk/boost/asio/ssl/detail/openssl_init.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// openssl_init.hpp
-// ~~~~~~~~~~~~~~~~
+// ssl/detail/openssl_init.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,20 +16,17 @@
 # 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/asio/detail/config.hpp>
 #include <cstring>
 #include <vector>
 #include <boost/assert.hpp>
-#include <boost/config.hpp>
 #include <boost/shared_ptr.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/detail/mutex.hpp>
 #include <boost/asio/detail/tss_ptr.hpp>
 #include <boost/asio/ssl/detail/openssl_types.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 namespace ssl {

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// openssl_operation.hpp
-// ~~~~~~~~~~~~~~~~~~~~~
+// ssl/detail/openssl_operation.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 //
@@ -15,19 +15,19 @@
 # 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/asio/detail/config.hpp>
 #include <boost/function.hpp>
 #include <boost/assert.hpp>
 #include <boost/bind.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/buffer.hpp>
-#include <boost/asio/placeholders.hpp>
-#include <boost/asio/write.hpp>
 #include <boost/asio/detail/socket_ops.hpp>
+#include <boost/asio/placeholders.hpp>
 #include <boost/asio/ssl/detail/openssl_types.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/asio/write.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_service.hpp
-// ~~~~~~~~~~~~~~~~~~
+// ssl/detail/stream_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,9 +16,7 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
 #include <climits>
 #include <memory>
@@ -26,17 +24,17 @@
 #include <boost/noncopyable.hpp>
 #include <boost/function.hpp>
 #include <boost/bind.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/buffer_sequence_adapter.hpp>
 #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>
 #include <boost/asio/ssl/detail/openssl_operation.hpp>
 #include <boost/asio/ssl/detail/openssl_types.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/system/system_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -93,7 +91,7 @@
       : base_handler<Stream>(io_service)
       , handler_(handler)
     {
- set_func(boost::bind(
+ this->set_func(boost::bind(
         &io_handler<Stream, Handler>::handler_impl,
         this, boost::arg<1>(), boost::arg<2>() ));
     }
@@ -117,7 +115,7 @@
       : base_handler<Stream>(io_service)
       , handler_(handler)
     {
- set_func(boost::bind(
+ this->set_func(boost::bind(
         &handshake_handler<Stream, Handler>::handler_impl,
         this, boost::arg<1>(), boost::arg<2>() ));
     }
@@ -142,7 +140,7 @@
       : base_handler<Stream>(io_service),
         handler_(handler)
     {
- set_func(boost::bind(
+ this->set_func(boost::bind(
         &shutdown_handler<Stream, Handler>::handler_impl,
         this, boost::arg<1>(), boost::arg<2>() ));
     }

Modified: trunk/boost/asio/ssl/detail/openssl_types.hpp
==============================================================================
--- trunk/boost/asio/ssl/detail/openssl_types.hpp (original)
+++ trunk/boost/asio/ssl/detail/openssl_types.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// openssl_types.hpp
-// ~~~~~~~~~~~~~~~~~
+// ssl/detail/openssl_types.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,17 +15,11 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/detail/socket_types.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 #include <openssl/conf.h>
 #include <openssl/ssl.h>
 #include <openssl/engine.h>
 #include <openssl/err.h>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/detail/pop_options.hpp>
+#include <boost/asio/detail/socket_types.hpp>
 
 #endif // BOOST_ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP

Modified: trunk/boost/asio/ssl/stream.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream.hpp (original)
+++ trunk/boost/asio/ssl/stream.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream.hpp
-// ~~~~~~~~~~
+// ssl/stream.hpp
+// ~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,20 +16,17 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <boost/noncopyable.hpp>
 #include <boost/type_traits/remove_reference.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/ssl/basic_context.hpp>
 #include <boost/asio/ssl/stream_base.hpp>
 #include <boost/asio/ssl/stream_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ssl/stream_base.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream_base.hpp (original)
+++ trunk/boost/asio/ssl/stream_base.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_base.hpp
-// ~~~~~~~~~~~~~~~
+// ssl/stream_base.hpp
+// ~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,11 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+#include <boost/detail/workaround.hpp>
 
 #include <boost/asio/detail/push_options.hpp>
-#include <boost/detail/workaround.hpp>
-#include <boost/asio/detail/pop_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/ssl/stream_service.hpp
==============================================================================
--- trunk/boost/asio/ssl/stream_service.hpp (original)
+++ trunk/boost/asio/ssl/stream_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_service.hpp
-// ~~~~~~~~~~~~~~~~~~
+// ssl/stream_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
 // Copyright (c) 2005-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
@@ -16,19 +16,15 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <boost/noncopyable.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 #include <boost/asio/ssl/basic_context.hpp>
-#include <boost/asio/ssl/stream_base.hpp>
 #include <boost/asio/ssl/detail/openssl_stream_service.hpp>
+#include <boost/asio/ssl/stream_base.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/strand.hpp
==============================================================================
--- trunk/boost/asio/strand.hpp (original)
+++ trunk/boost/asio/strand.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,11 +15,12 @@
 # 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/config.hpp>
 #include <boost/asio/detail/strand_service.hpp>
 #include <boost/asio/detail/wrapped_handler.hpp>
+#include <boost/asio/io_service.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {

Modified: trunk/boost/asio/stream_socket_service.hpp
==============================================================================
--- trunk/boost/asio/stream_socket_service.hpp (original)
+++ trunk/boost/asio/stream_socket_service.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,10 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
 
 #if defined(BOOST_ASIO_HAS_IOCP)
 # include <boost/asio/detail/win_iocp_socket_service.hpp>
@@ -32,6 +26,8 @@
 # include <boost/asio/detail/reactive_socket_service.hpp>
 #endif
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/streambuf.hpp
==============================================================================
--- trunk/boost/asio/streambuf.hpp (original)
+++ trunk/boost/asio/streambuf.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,12 +15,12 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if !defined(BOOST_NO_IOSTREAM)
 
+#include <boost/asio/basic_streambuf.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -32,6 +32,4 @@
 
 #endif // !defined(BOOST_NO_IOSTREAM)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_STREAMBUF_HPP

Modified: trunk/boost/asio/time_traits.hpp
==============================================================================
--- trunk/boost/asio/time_traits.hpp (original)
+++ trunk/boost/asio/time_traits.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,14 +15,14 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#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/push_options.hpp>
+
 namespace boost {
 namespace asio {
 

Modified: trunk/boost/asio/version.hpp
==============================================================================
--- trunk/boost/asio/version.hpp (original)
+++ trunk/boost/asio/version.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -18,6 +18,6 @@
 // BOOST_ASIO_VERSION % 100 is the sub-minor version
 // BOOST_ASIO_VERSION / 100 % 1000 is the minor version
 // BOOST_ASIO_VERSION / 100000 is the major version
-#define BOOST_ASIO_VERSION 100403 // 1.4.3
+#define BOOST_ASIO_VERSION 100405 // 1.4.5
 
 #endif // BOOST_ASIO_VERSION_HPP

Modified: trunk/boost/asio/windows/basic_handle.hpp
==============================================================================
--- trunk/boost/asio/windows/basic_handle.hpp (original)
+++ trunk/boost/asio/windows/basic_handle.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_handle.hpp
-// ~~~~~~~~~~~~~~~~
+// windows/basic_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,15 +15,17 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+ || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
 
 #include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/error.hpp>
 #include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/error.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -224,4 +226,8 @@
 
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
+ // || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
+ // || defined(GENERATING_DOCUMENTATION)
+
 #endif // BOOST_ASIO_WINDOWS_BASIC_HANDLE_HPP

Modified: trunk/boost/asio/windows/basic_random_access_handle.hpp
==============================================================================
--- trunk/boost/asio/windows/basic_random_access_handle.hpp (original)
+++ trunk/boost/asio/windows/basic_random_access_handle.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_random_access_handle.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// windows/basic_random_access_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
 
+#include <cstddef>
+#include <boost/asio/detail/throw_error.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/windows/basic_handle.hpp>
 #include <boost/asio/windows/random_access_handle_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
 
-#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -314,9 +312,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP

Modified: trunk/boost/asio/windows/basic_stream_handle.hpp
==============================================================================
--- trunk/boost/asio/windows/basic_stream_handle.hpp (original)
+++ trunk/boost/asio/windows/basic_stream_handle.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// basic_stream_handle.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
+// windows/basic_stream_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,18 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
 
+#include <cstddef>
 #include <boost/asio/error.hpp>
 #include <boost/asio/windows/basic_handle.hpp>
 #include <boost/asio/windows/stream_handle_service.hpp>
 #include <boost/asio/detail/throw_error.hpp>
 
-#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -296,9 +294,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP

Modified: trunk/boost/asio/windows/overlapped_ptr.hpp
==============================================================================
--- trunk/boost/asio/windows/overlapped_ptr.hpp (original)
+++ trunk/boost/asio/windows/overlapped_ptr.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// overlapped_ptr.hpp
-// ~~~~~~~~~~~~~~~~~~
+// windows/overlapped_ptr.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,20 +15,16 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \
+ || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/io_service.hpp>
 #include <boost/asio/detail/noncopyable.hpp>
 #include <boost/asio/detail/win_iocp_overlapped_ptr.hpp>
+#include <boost/asio/io_service.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
-# if defined(BOOST_ASIO_HAS_IOCP)
-# define BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR 1
-# endif // defined(BOOST_ASIO_HAS_IOCP)
-#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_OVERLAPPED_PTR)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -112,9 +108,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_OVERLAPPED_PTR)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_OVERLAPPED_PTR_HPP

Modified: trunk/boost/asio/windows/random_access_handle.hpp
==============================================================================
--- trunk/boost/asio/windows/random_access_handle.hpp (original)
+++ trunk/boost/asio/windows/random_access_handle.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// random_access_handle.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
+// windows/random_access_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/windows/basic_random_access_handle.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <boost/asio/windows/basic_random_access_handle.hpp>
+
 namespace boost {
 namespace asio {
 namespace windows {
@@ -36,6 +36,4 @@
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// random_access_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// windows/random_access_handle_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,27 +15,19 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
+
+#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/push_options.hpp>
 #include <cstddef>
 #include <boost/config.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/win_iocp_handle_service.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
-# if defined(BOOST_ASIO_HAS_IOCP)
-# define BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE 1
-# endif // defined(BOOST_ASIO_HAS_IOCP)
-#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_RANDOM_ACCESS_HANDLE)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -174,9 +166,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP

Modified: trunk/boost/asio/windows/stream_handle.hpp
==============================================================================
--- trunk/boost/asio/windows/stream_handle.hpp (original)
+++ trunk/boost/asio/windows/stream_handle.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_handle.hpp
-// ~~~~~~~~~~~~~~~~~~
+// windows/stream_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,13 +15,13 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
-
-#include <boost/asio/windows/basic_stream_handle.hpp>
+#include <boost/asio/detail/config.hpp>
 
 #if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
   || defined(GENERATING_DOCUMENTATION)
 
+#include <boost/asio/windows/basic_stream_handle.hpp>
+
 namespace boost {
 namespace asio {
 namespace windows {
@@ -36,6 +36,4 @@
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_STREAM_HANDLE_HPP

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-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -1,6 +1,6 @@
 //
-// stream_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// windows/stream_handle_service.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
 // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
 //
@@ -15,26 +15,17 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/detail/config.hpp>
 
-#include <boost/asio/detail/push_options.hpp>
-#include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
+#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
 
+#include <cstddef>
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
 #include <boost/asio/error.hpp>
 #include <boost/asio/io_service.hpp>
-#include <boost/asio/detail/service_base.hpp>
-#include <boost/asio/detail/win_iocp_handle_service.hpp>
 
-#if !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
-# if defined(BOOST_ASIO_HAS_IOCP)
-# define BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE 1
-# endif // defined(BOOST_ASIO_HAS_IOCP)
-#endif // !defined(BOOST_ASIO_DISABLE_WINDOWS_STREAM_HANDLE)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/detail/push_options.hpp>
 
 namespace boost {
 namespace asio {
@@ -172,9 +163,9 @@
 } // namespace asio
 } // namespace boost
 
+#include <boost/asio/detail/pop_options.hpp>
+
 #endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
        // || defined(GENERATING_DOCUMENTATION)
 
-#include <boost/asio/detail/pop_options.hpp>
-
 #endif // BOOST_ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP

Modified: trunk/boost/asio/write.hpp
==============================================================================
--- trunk/boost/asio/write.hpp (original)
+++ trunk/boost/asio/write.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,16 +15,13 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/basic_streambuf_fwd.hpp>
 #include <boost/asio/error.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -535,8 +532,8 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/write.ipp>
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/impl/write.hpp>
+
 #endif // BOOST_ASIO_WRITE_HPP

Modified: trunk/boost/asio/write_at.hpp
==============================================================================
--- trunk/boost/asio/write_at.hpp (original)
+++ trunk/boost/asio/write_at.hpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -15,17 +15,14 @@
 # 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/asio/detail/config.hpp>
 #include <cstddef>
-#include <boost/config.hpp>
 #include <boost/cstdint.hpp>
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/basic_streambuf.hpp>
+#include <boost/asio/basic_streambuf_fwd.hpp>
 #include <boost/asio/error.hpp>
 
+#include <boost/asio/detail/push_options.hpp>
+
 namespace boost {
 namespace asio {
 
@@ -558,8 +555,8 @@
 } // namespace asio
 } // namespace boost
 
-#include <boost/asio/impl/write_at.ipp>
-
 #include <boost/asio/detail/pop_options.hpp>
 
+#include <boost/asio/impl/write_at.hpp>
+
 #endif // BOOST_ASIO_WRITE_AT_HPP

Modified: trunk/libs/asio/doc/reference.qbk
==============================================================================
--- trunk/libs/asio/doc/reference.qbk (original)
+++ trunk/libs/asio/doc/reference.qbk 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -424,7 +424,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 
 [heading Parameters]
@@ -574,7 +574,7 @@
 This function is used to asynchronously read a certain number of bytes of data from a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's async\_read\_some function, and is known as a [*composed operation]. The program must ensure that the stream performs no other read operations (such as async\_read, the stream's async\_read\_some function, or any other composed operations that perform reads) until this operation completes.
 
@@ -795,7 +795,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 
 [heading Parameters]
@@ -951,7 +951,7 @@
 This function is used to asynchronously read a certain number of bytes of data from a random access device at the specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's async\_read\_some\_at function.
 
@@ -1666,7 +1666,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a [*composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
 
@@ -1746,7 +1746,7 @@
 This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
 * An error occurred.
@@ -1806,10 +1806,10 @@
 This function is used to asynchronously write a certain number of bytes of data to a stream. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's async\_write\_some function, and is known as a [*composed operation]. The program must ensure that the stream performs no other write operations (such as async\_write, the stream's async\_write\_some function, or any other composed operations that perform writes) until this operation completes.
 
@@ -2015,7 +2015,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function.
 
@@ -2098,7 +2098,7 @@
 This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
 * An error occurred.
@@ -2161,10 +2161,10 @@
 This function is used to asynchronously write a certain number of bytes of data to a random access device at a specified offset. The function call always returns immediately. The asynchronous operation will continue until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's async\_write\_some\_at function.
 
@@ -3901,10 +3901,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -3952,10 +3952,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -7430,10 +7430,10 @@
 
 
 
-* The boost::asio::basic_deadline_timer::expires_from_now() function cancels any pending asynchronous waits, and returns the number of asynchronous waits that were cancelled. If it returns 0 then you were too late and the wait handler has already been executed, or will soon be executed. If it returns 1 then the wait handler was successfully cancelled.
+* The `boost::asio::basic_deadline_timer::expires_from_now()` function cancels any pending asynchronous waits, and returns the number of asynchronous waits that were cancelled. If it returns 0 then you were too late and the wait handler has already been executed, or will soon be executed. If it returns 1 then the wait handler was successfully cancelled.
 
 
-* If a wait handler is cancelled, the boost::system::error_code passed to it contains the value boost::asio::error::operation_aborted.
+* If a wait handler is cancelled, the boost::system::error\_code passed to it contains the value `boost::asio::error::operation_aborted`.
 
 
 
@@ -7464,7 +7464,7 @@
 * The timer has expired.
 
 
-* The timer was cancelled, in which case the handler is passed the error code boost::asio::error::operation_aborted.
+* The timer was cancelled, in which case the handler is passed the error code `boost::asio::error::operation_aborted`.
 
 
 [heading Parameters]
@@ -10211,10 +10211,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -10262,10 +10262,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -16320,10 +16320,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -16368,10 +16368,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -22849,10 +22849,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -22900,10 +22900,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -27034,10 +27034,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -27085,10 +27085,10 @@
 For portable cancellation, consider using one of the following alternatives:
 
 
-* Disable asio's I/O completion port backend by defining BOOST_ASIO_DISABLE_IOCP.
+* Disable asio's I/O completion port backend by defining BOOST\_ASIO\_DISABLE\_IOCP.
 
 
-* Use the close() function to simultaneously cancel the outstanding operations and close the socket.
+* Use the `close()` function to simultaneously cancel the outstanding operations and close the socket.
 
 When running on Windows Vista, Windows Server 2008, and later, the CancelIoEx function is always used. This function does not have the problems described above.
 
@@ -35911,7 +35911,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -36129,10 +36129,10 @@
 
 
 
-* The boost::asio::basic_deadline_timer::expires_from_now() function cancels any pending asynchronous waits, and returns the number of asynchronous waits that were cancelled. If it returns 0 then you were too late and the wait handler has already been executed, or will soon be executed. If it returns 1 then the wait handler was successfully cancelled.
+* The `boost::asio::basic_deadline_timer::expires_from_now()` function cancels any pending asynchronous waits, and returns the number of asynchronous waits that were cancelled. If it returns 0 then you were too late and the wait handler has already been executed, or will soon be executed. If it returns 1 then the wait handler was successfully cancelled.
 
 
-* If a wait handler is cancelled, the boost::system::error_code passed to it contains the value boost::asio::error::operation_aborted.
+* If a wait handler is cancelled, the boost::system::error\_code passed to it contains the value `boost::asio::error::operation_aborted`.
 
 
 
@@ -36558,7 +36558,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -37483,13 +37483,13 @@
 The [link boost_asio.reference.io_service `io_service`] class provides the core I/O functionality for users of the asynchronous I/O objects, including:
 
 
-* boost::asio::ip::tcp::socket
+* `boost::asio::ip::tcp::socket`
 
-* boost::asio::ip::tcp::acceptor
+* `boost::asio::ip::tcp::acceptor`
 
-* boost::asio::ip::udp::socket
+* `boost::asio::ip::udp::socket`
 
-* boost::asio::deadline_timer.
+* `boost::asio::deadline_timer`.
 
 The [link boost_asio.reference.io_service `io_service`] class also includes facilities intended for developers of custom asynchronous services.
 
@@ -37688,7 +37688,7 @@
 This function throws an exception only if:
 
 
-* the handler's asio_handler_allocate function; or
+* the handler's `asio_handler_allocate` function; or
 
 
 * the handler's copy constructor
@@ -38000,7 +38000,7 @@
 This function throws an exception only if:
 
 
-* the handler's asio_handler_allocate function; or
+* the handler's `asio_handler_allocate` function; or
 
 
 * the handler's copy constructor
@@ -38342,13 +38342,13 @@
 On destruction, the [link boost_asio.reference.io_service `io_service`] performs the following sequence of operations:
 
 
-* For each service object svc in the io_service set, in reverse order of the beginning of service object lifetime, performs svc->shutdown_service().
+* For each service object `svc` in the [link boost_asio.reference.io_service `io_service`] set, in reverse order of the beginning of service object lifetime, performs `svc->shutdown_service()`.
 
 
-* Uninvoked handler objects that were scheduled for deferred invocation on the io_service, or any associated strand, are destroyed.
+* Uninvoked handler objects that were scheduled for deferred invocation on the [link boost_asio.reference.io_service `io_service`], or any associated strand, are destroyed.
 
 
-* For each service object svc in the io_service set, in reverse order of the beginning of service object lifetime, performs delete static_cast<io_service::service*>(svc).
+* For each service object `svc` in the [link boost_asio.reference.io_service `io_service`] set, in reverse order of the beginning of service object lifetime, performs `delete static_cast<io_service::service*>(svc)`.
 
 
 [heading Remarks]
@@ -38356,10 +38356,10 @@
 The destruction sequence described above permits programs to simplify their resource management by using `shared_ptr<>`. Where an object's lifetime is tied to the lifetime of a connection (or some other sequence of asynchronous operations), a `shared_ptr` to the object would be bound into the handlers for all asynchronous operations associated with it. This works as follows:
 
 
-* When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all shared_ptr references to the objects are destroyed.
+* When a single connection ends, all associated asynchronous operations complete. The corresponding handler objects are destroyed, and all `shared_ptr` references to the objects are destroyed.
 
 
-* To shut down the whole program, the io_service function stop() is called to terminate any run() calls as soon as possible. The io_service destructor defined above destroys all handlers, causing all shared_ptr references to all connection objects to be destroyed.
+* To shut down the whole program, the [link boost_asio.reference.io_service `io_service`] function `stop()` is called to terminate any `run()` calls as soon as possible. The [link boost_asio.reference.io_service `io_service`] destructor defined above destroys all handlers, causing all `shared_ptr` references to all connection objects to be destroyed.
 
 
 
@@ -38592,33 +38592,33 @@
 Given:
 
 
-* a strand object s
+* a strand object `s`
 
 
-* an object a meeting completion handler requirements
+* an object `a` meeting completion handler requirements
 
 
-* an object a1 which is an arbitrary copy of a made by the implementation
+* an object `a1` which is an arbitrary copy of `a` made by the implementation
 
 
-* an object b meeting completion handler requirements
+* an object `b` meeting completion handler requirements
 
 
-* an object b1 which is an arbitrary copy of b made by the implementation
+* an object `b1` which is an arbitrary copy of `b` made by the implementation
 
 if any of the following conditions are true:
 
 
-* s.post(a) happens-before s.post(b)
+* `s.post(a)` happens-before `s.post(b)`
 
 
-* s.post(a) happens-before s.dispatch(b), where the latter is performed outside the strand
+* `s.post(a)` happens-before `s.dispatch(b)`, where the latter is performed outside the strand
 
 
-* s.dispatch(a) happens-before s.post(b), where the former is performed outside the strand
+* `s.dispatch(a)` happens-before `s.post(b)`, where the former is performed outside the strand
 
 
-* s.dispatch(a) happens-before s.dispatch(b), where both are performed outside the strand
+* `s.dispatch(a)` happens-before `s.dispatch(b)`, where both are performed outside the strand
 
 then `asio_handler_invoke(a1, &a1)` happens-before `asio_handler_invoke(b1, &b1)`.
 
@@ -39106,10 +39106,25 @@
   ]
   
   [
+ [[link boost_asio.reference.ip__address.operator_lt__eq_ [*operator<=]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.ip__address.operator_eq__eq_ [*operator==]]]
     [Compare two addresses for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.ip__address.operator_gt_ [*operator>]]]
+ [Compare addresses for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.ip__address.operator_gt__eq_ [*operator>=]]]
+ [Compare addresses for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -39434,6 +39449,28 @@
 [endsect]
 
 
+
+[section:operator_lt__eq_ ip::address::operator<=]
+
+[indexterm2 operator<=..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator<=(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/address.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
 [section:operator_eq_ ip::address::operator=]
 
 [indexterm2 operator=..ip::address]
@@ -39529,6 +39566,50 @@
 [endsect]
 
 
+
+[section:operator_gt_ ip::address::operator>]
+
+[indexterm2 operator>..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator>(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/address.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::address::operator>=]
+
+[indexterm2 operator>=..ip::address]
+Compare addresses for ordering.
+
+
+ friend bool operator>=(
+ const address & a1,
+ const address & a2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/address.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
 [section:to_string ip::address::to_string]
 
 [indexterm2 to_string..ip::address]
@@ -41424,10 +41505,25 @@
   ]
   
   [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -41781,6 +41877,28 @@
 
 
 
+[section:operator_lt__eq_ ip::basic_endpoint::operator<=]
+
+[indexterm2 operator<=..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<=(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
+
 [section:operator_eq_ ip::basic_endpoint::operator=]
 
 [indexterm2 operator=..ip::basic_endpoint]
@@ -41817,6 +41935,50 @@
 [endsect]
 
 
+
+[section:operator_gt_ ip::basic_endpoint::operator>]
+
+[indexterm2 operator>..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ ip::basic_endpoint::operator>=]
+
+[indexterm2 operator>=..ip::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>=(
+ const basic_endpoint< InternetProtocol > & e1,
+ const basic_endpoint< InternetProtocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/ip/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
 [section:port ip::basic_endpoint::port]
 
 [indexterm2 port..ip::basic_endpoint]
@@ -44160,10 +44322,25 @@
   ]
   
   [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -46137,7 +46314,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -46718,10 +46895,25 @@
   ]
   
   [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -47936,10 +48128,25 @@
   ]
   
   [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.ip__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.ip__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -49165,10 +49372,25 @@
   ]
   
   [
+ [[link boost_asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -49449,6 +49671,28 @@
 
 
 
+[section:operator_lt__eq_ local::basic_endpoint::operator<=]
+
+[indexterm2 operator<=..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator<=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/local/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
+
 [section:operator_eq_ local::basic_endpoint::operator=]
 
 [indexterm2 operator=..local::basic_endpoint]
@@ -49485,6 +49729,50 @@
 [endsect]
 
 
+
+[section:operator_gt_ local::basic_endpoint::operator>]
+
+[indexterm2 operator>..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/local/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
+
+[section:operator_gt__eq_ local::basic_endpoint::operator>=]
+
+[indexterm2 operator>=..local::basic_endpoint]
+Compare endpoints for ordering.
+
+
+ friend bool operator>=(
+ const basic_endpoint< Protocol > & e1,
+ const basic_endpoint< Protocol > & e2);
+
+
+[heading Requirements]
+
+[*Header: ][^boost/asio/local/basic_endpoint.hpp]
+
+[*Convenience header: ][^boost/asio.hpp]
+
+
+[endsect]
+
+
 [section:path local::basic_endpoint::path]
 
 [indexterm2 path..local::basic_endpoint]
@@ -49858,10 +50146,25 @@
   ]
   
   [
+ [[link boost_asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -50837,10 +51140,25 @@
   ]
   
   [
+ [[link boost_asio.reference.local__basic_endpoint.operator_lt__eq_ [*operator<=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
     [[link boost_asio.reference.local__basic_endpoint.operator_eq__eq_ [*operator==]]]
     [Compare two endpoints for equality. ]
   ]
   
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt_ [*operator>]]]
+ [Compare endpoints for ordering. ]
+ ]
+
+ [
+ [[link boost_asio.reference.local__basic_endpoint.operator_gt__eq_ [*operator>=]]]
+ [Compare endpoints for ordering. ]
+ ]
+
 ]
 
 [heading Related Functions]
@@ -55429,7 +55747,7 @@
 Destroy all user-defined descriptorr objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -56333,7 +56651,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -56516,7 +56834,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's read\_some function.
 
@@ -56600,7 +56918,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's read\_some function.
 
@@ -56728,7 +57046,7 @@
 This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's read\_some function.
 
@@ -56798,7 +57116,7 @@
 This function is used to read a certain number of bytes of data from a stream. The call will block until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's read\_some function.
 
@@ -57024,7 +57342,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
 
@@ -57111,7 +57429,7 @@
 * The supplied buffers are full. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
 
@@ -57245,7 +57563,7 @@
 This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
 
@@ -57318,7 +57636,7 @@
 This function is used to read a certain number of bytes of data from a random access device at the specified offset. The call will block until one of the following conditions is true:
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's read\_some\_at function.
 
@@ -59527,7 +59845,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -60180,7 +60498,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -63730,7 +64048,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -65605,7 +65923,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -65710,33 +66028,33 @@
 Given:
 
 
-* a strand object s
+* a strand object `s`
 
 
-* an object a meeting completion handler requirements
+* an object `a` meeting completion handler requirements
 
 
-* an object a1 which is an arbitrary copy of a made by the implementation
+* an object `a1` which is an arbitrary copy of `a` made by the implementation
 
 
-* an object b meeting completion handler requirements
+* an object `b` meeting completion handler requirements
 
 
-* an object b1 which is an arbitrary copy of b made by the implementation
+* an object `b1` which is an arbitrary copy of `b` made by the implementation
 
 if any of the following conditions are true:
 
 
-* s.post(a) happens-before s.post(b)
+* `s.post(a)` happens-before `s.post(b)`
 
 
-* s.post(a) happens-before s.dispatch(b), where the latter is performed outside the strand
+* `s.post(a)` happens-before `s.dispatch(b)`, where the latter is performed outside the strand
 
 
-* s.dispatch(a) happens-before s.post(b), where the former is performed outside the strand
+* `s.dispatch(a)` happens-before `s.post(b)`, where the former is performed outside the strand
 
 
-* s.dispatch(a) happens-before s.dispatch(b), where both are performed outside the strand
+* `s.dispatch(a)` happens-before `s.dispatch(b)`, where both are performed outside the strand
 
 then `asio_handler_invoke(a1, &a1)` happens-before `asio_handler_invoke(b1, &b1)`.
 
@@ -66512,7 +66830,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -71192,7 +71510,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -71773,7 +72091,7 @@
 Destroy all user-defined handler objects owned by the service.
 
 
- void shutdown_service();
+ virtual void shutdown_service();
 
 
 
@@ -71990,7 +72308,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's write\_some function.
 
@@ -72074,7 +72392,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's write\_some function.
 
@@ -72133,7 +72451,7 @@
 This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
 * An error occurred.
@@ -72205,10 +72523,10 @@
 This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's write\_some function.
 
@@ -72278,10 +72596,10 @@
 This function is used to write a certain number of bytes of data to a stream. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the stream's write\_some function.
 
@@ -72507,7 +72825,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
 
@@ -72594,7 +72912,7 @@
 * All of the data in the supplied buffers has been written. That is, the bytes transferred is equal to the sum of the buffer sizes.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
 
@@ -72656,7 +72974,7 @@
 This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
 * An error occurred.
@@ -72731,10 +73049,10 @@
 This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
 
@@ -72807,10 +73125,10 @@
 This function is used to write a certain number of bytes of data to a random access device at a specified offset. The call will block until one of the following conditions is true:
 
 
-* All of the data in the supplied basic_streambuf has been written.
+* All of the data in the supplied [link boost_asio.reference.basic_streambuf `basic_streambuf`] has been written.
 
 
-* The completion_condition function object returns 0.
+* The completion\_condition function object returns 0.
 
 This operation is implemented in terms of zero or more calls to the device's write\_some\_at function.
 

Modified: trunk/libs/asio/doc/reference.xsl
==============================================================================
--- trunk/libs/asio/doc/reference.xsl (original)
+++ trunk/libs/asio/doc/reference.xsl 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -103,7 +103,8 @@
         <xsl:if test="
             not(contains(ancestor::*/compoundname, '::detail')) and
             not(contains(ancestor::*/compoundname, '::service::key')) and
- not(contains(ancestor::*/compoundname, '_helper'))">
+ not(contains(ancestor::*/compoundname, '_helper')) and
+ not(contains(name, '_helper'))">
           <xsl:call-template name="namespace-memberdef"/>
         </xsl:if>
       </xsl:otherwise>
@@ -164,6 +165,23 @@
 </xsl:template>
 
 
+<xsl:template name="cleanup-type">
+ <xsl:param name="name"/>
+ <xsl:choose>
+ <xsl:when test="contains($name, 'BOOST_ASIO_DECL ')">
+ <xsl:value-of select="substring-after($name, 'BOOST_ASIO_DECL ')"/>
+ </xsl:when>
+ <xsl:when test="contains($name, 'BOOST_ASIO_DECL')">
+ <xsl:value-of select="substring-after($name, 'BOOST_ASIO_DECL')"/>
+ </xsl:when>
+ <xsl:when test="$name = 'virtual'"></xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$name"/>
+ </xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
 <xsl:template name="make-id">
   <xsl:param name="name"/>
   <xsl:choose>
@@ -365,8 +383,11 @@
 
 
 <xsl:template match="listitem" mode="markup">
-* <xsl:value-of select="."/><xsl:text>
-</xsl:text>
+* <xsl:call-template name="strip-leading-whitespace">
+ <xsl:with-param name="text">
+ <xsl:apply-templates mode="markup"/>
+ </xsl:with-param>
+</xsl:call-template>
 </xsl:template>
 
 
@@ -1054,8 +1075,14 @@
 <xsl:text> </xsl:text>
  <xsl:if test="@explicit='yes'">explicit </xsl:if>
  <xsl:if test="@static='yes'">static </xsl:if>
- <xsl:if test="string-length(type) > 0">
- <xsl:value-of select="type"/><xsl:text> </xsl:text>
+ <xsl:if test="@virt='virtual'">virtual </xsl:if>
+ <xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:if test="string-length($stripped-type) &gt; 0">
+ <xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text>
 </xsl:if>``[link boost_asio.reference.<xsl:value-of select="$class-id"/>.<xsl:value-of
  select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text><xsl:value-of
  select="name"/>]``(<xsl:apply-templates select="param"
@@ -1217,8 +1244,14 @@
     <xsl:apply-templates select="templateparamlist" mode="class-detail"/>
   </xsl:otherwise>
 </xsl:choose>
-<xsl:text> </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:if
- test="string-length(type) > 0"><xsl:value-of select="type"/><xsl:text> </xsl:text></xsl:if>
+<xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+</xsl:variable>
+<xsl:text> </xsl:text><xsl:if test="@static='yes'">static </xsl:if><xsl:if
+ test="@virt='virtual'">virtual </xsl:if><xsl:if
+ test="string-length($stripped-type) &gt; 0"><xsl:value-of select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>
 <xsl:value-of select="name"/>(<xsl:apply-templates select="param"
  mode="class-detail"/>)<xsl:if test="@const='yes'"> const</xsl:if>;
 </xsl:template>
@@ -1394,10 +1427,15 @@
 </xsl:choose>
 
 <xsl:for-each select="../memberdef[name = $unqualified-name]">
+<xsl:variable name="stripped-type">
+ <xsl:call-template name="cleanup-type">
+ <xsl:with-param name="name" select="type"/>
+ </xsl:call-template>
+</xsl:variable>
 <xsl:text>
 </xsl:text><xsl:apply-templates select="templateparamlist" mode="class-detail"/>
-<xsl:text> </xsl:text><xsl:if test="string-length(type) > 0"><xsl:value-of
- select="type"/><xsl:text> </xsl:text></xsl:if>``[link boost_asio.reference.<xsl:value-of
+<xsl:text> </xsl:text><xsl:if test="string-length($stripped-type) &gt; 0"><xsl:value-of
+ select="$stripped-type"/><xsl:text> </xsl:text></xsl:if>``[link boost_asio.reference.<xsl:value-of
  select="$id"/>.overload<xsl:value-of select="position()"/><xsl:text> </xsl:text>
 <xsl:value-of select="name"/>]``(<xsl:apply-templates select="param" mode="class-detail"/>);
 <xsl:text> `` [''''&amp;raquo;'''</xsl:text>

Modified: trunk/libs/asio/example/local/iostream_client.cpp
==============================================================================
--- trunk/libs/asio/example/local/iostream_client.cpp (original)
+++ trunk/libs/asio/example/local/iostream_client.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -28,10 +28,13 @@
       return 1;
     }
 
- boost::asio::io_service io_service;
-
     stream_protocol::endpoint ep(argv[1]);
     stream_protocol::iostream s(ep);
+ if (!s)
+ {
+ std::cerr << "Unable to connect\n";
+ return 1;
+ }
 
     using namespace std; // For strlen.
     std::cout << "Enter message: ";

Modified: trunk/libs/asio/test/Jamfile
==============================================================================
--- trunk/libs/asio/test/Jamfile (original)
+++ trunk/libs/asio/test/Jamfile 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -26,6 +26,7 @@
 
 template asio_unit_test
   : <lib>@boost/libs/thread/build/boost_thread
+ <lib>@boost/libs/regex/build/boost_regex
     <lib>@boost_system/libs/system/build/boost_system
   : <include>../../.. <include>@boost <include>@boost_system
     <define>BOOST_ALL_NO_LIB=1

Modified: trunk/libs/asio/test/Jamfile.v2
==============================================================================
--- trunk/libs/asio/test/Jamfile.v2 (original)
+++ trunk/libs/asio/test/Jamfile.v2 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -39,6 +39,7 @@
     <library>/boost/date_time//boost_date_time
     <library>/boost/system//boost_system
     <library>/boost/thread//boost_thread
+ <library>/boost/regex//boost_regex
     <define>BOOST_ALL_NO_LIB=1
     <threading>multi
     <os>LINUX:<define>_XOPEN_SOURCE=600

Modified: trunk/libs/asio/test/buffer.cpp
==============================================================================
--- trunk/libs/asio/test/buffer.cpp (original)
+++ trunk/libs/asio/test/buffer.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,6 +16,7 @@
 // Test that header file is self-contained.
 #include <boost/asio/buffer.hpp>
 
+#include <boost/array.hpp>
 #include "unit_test.hpp"
 
 //------------------------------------------------------------------------------

Modified: trunk/libs/asio/test/buffered_read_stream.cpp
==============================================================================
--- trunk/libs/asio/test/buffered_read_stream.cpp (original)
+++ trunk/libs/asio/test/buffered_read_stream.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -22,6 +22,7 @@
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/tcp.hpp>
 #include <boost/asio/placeholders.hpp>
+#include <boost/system/system_error.hpp>
 #include "unit_test.hpp"
 
 typedef boost::asio::buffered_read_stream<

Modified: trunk/libs/asio/test/buffered_stream.cpp
==============================================================================
--- trunk/libs/asio/test/buffered_stream.cpp (original)
+++ trunk/libs/asio/test/buffered_stream.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -22,6 +22,7 @@
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/tcp.hpp>
 #include <boost/asio/placeholders.hpp>
+#include <boost/system/system_error.hpp>
 #include "unit_test.hpp"
 
 typedef boost::asio::buffered_stream<

Modified: trunk/libs/asio/test/buffered_write_stream.cpp
==============================================================================
--- trunk/libs/asio/test/buffered_write_stream.cpp (original)
+++ trunk/libs/asio/test/buffered_write_stream.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -22,6 +22,7 @@
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/ip/tcp.hpp>
 #include <boost/asio/placeholders.hpp>
+#include <boost/system/system_error.hpp>
 #include "unit_test.hpp"
 
 typedef boost::asio::buffered_write_stream<

Modified: trunk/libs/asio/test/buffers_iterator.cpp
==============================================================================
--- trunk/libs/asio/test/buffers_iterator.cpp (original)
+++ trunk/libs/asio/test/buffers_iterator.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,6 +16,7 @@
 // Test that header file is self-contained.
 #include <boost/asio/buffers_iterator.hpp>
 
+#include <boost/array.hpp>
 #include <boost/asio/buffer.hpp>
 #include "unit_test.hpp"
 
@@ -212,18 +213,18 @@
     bi11 += 1;
     bi12 += 1;
 
- static_cast<std::ptrdiff_t>(bi13 - bi1);
- static_cast<std::ptrdiff_t>(bi14 - bi2);
- static_cast<std::ptrdiff_t>(bi15 - bi3);
- static_cast<std::ptrdiff_t>(bi16 - bi4);
- static_cast<std::ptrdiff_t>(bi17 - bi5);
- static_cast<std::ptrdiff_t>(bi18 - bi6);
- static_cast<std::ptrdiff_t>(bi19 - bi7);
- static_cast<std::ptrdiff_t>(bi20 - bi8);
- static_cast<std::ptrdiff_t>(bi21 - bi9);
- static_cast<std::ptrdiff_t>(bi22 - bi10);
- static_cast<std::ptrdiff_t>(bi23 - bi11);
- static_cast<std::ptrdiff_t>(bi24 - bi12);
+ (void)static_cast<std::ptrdiff_t>(bi13 - bi1);
+ (void)static_cast<std::ptrdiff_t>(bi14 - bi2);
+ (void)static_cast<std::ptrdiff_t>(bi15 - bi3);
+ (void)static_cast<std::ptrdiff_t>(bi16 - bi4);
+ (void)static_cast<std::ptrdiff_t>(bi17 - bi5);
+ (void)static_cast<std::ptrdiff_t>(bi18 - bi6);
+ (void)static_cast<std::ptrdiff_t>(bi19 - bi7);
+ (void)static_cast<std::ptrdiff_t>(bi20 - bi8);
+ (void)static_cast<std::ptrdiff_t>(bi21 - bi9);
+ (void)static_cast<std::ptrdiff_t>(bi22 - bi10);
+ (void)static_cast<std::ptrdiff_t>(bi23 - bi11);
+ (void)static_cast<std::ptrdiff_t>(bi24 - bi12);
   }
   catch (std::exception&)
   {

Modified: trunk/libs/asio/test/ip/multicast.cpp
==============================================================================
--- trunk/libs/asio/test/ip/multicast.cpp (original)
+++ trunk/libs/asio/test/ip/multicast.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -76,7 +76,7 @@
     ip::multicast::hops hops2;
     sock.get_option(hops2);
     hops1 = 1;
- static_cast<int>(hops1.value());
+ (void)static_cast<int>(hops1.value());
 
     // enable_loopback class.
 
@@ -85,9 +85,9 @@
     ip::multicast::enable_loopback enable_loopback2;
     sock.get_option(enable_loopback2);
     enable_loopback1 = true;
- static_cast<bool>(enable_loopback1);
- static_cast<bool>(!enable_loopback1);
- static_cast<bool>(enable_loopback1.value());
+ (void)static_cast<bool>(enable_loopback1);
+ (void)static_cast<bool>(!enable_loopback1);
+ (void)static_cast<bool>(enable_loopback1.value());
   }
   catch (std::exception&)
   {

Modified: trunk/libs/asio/test/ip/tcp.cpp
==============================================================================
--- trunk/libs/asio/test/ip/tcp.cpp (original)
+++ trunk/libs/asio/test/ip/tcp.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -54,9 +54,9 @@
     ip::tcp::no_delay no_delay2;
     sock.get_option(no_delay2);
     no_delay1 = true;
- static_cast<bool>(no_delay1);
- static_cast<bool>(!no_delay1);
- static_cast<bool>(no_delay1.value());
+ (void)static_cast<bool>(no_delay1);
+ (void)static_cast<bool>(!no_delay1);
+ (void)static_cast<bool>(no_delay1.value());
   }
   catch (std::exception&)
   {
@@ -551,6 +551,68 @@
 
 //------------------------------------------------------------------------------
 
+// ip_tcp_resolver_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::tcp::resolver compile and link correctly. Runtime failures are ignored.
+
+namespace ip_tcp_resolver_compile {
+
+void resolve_handler(const boost::system::error_code&,
+ boost::asio::ip::tcp::resolver::iterator)
+{
+}
+
+void test()
+{
+ using namespace boost::asio;
+ namespace ip = boost::asio::ip;
+
+ try
+ {
+ io_service ios;
+ boost::system::error_code ec;
+ ip::tcp::resolver::query q(ip::tcp::v4(), "localhost", "0");
+ ip::tcp::endpoint e(ip::address_v4::loopback(), 0);
+
+ // basic_resolver constructors.
+
+ ip::tcp::resolver resolver(ios);
+
+ // basic_io_object functions.
+
+ io_service& ios_ref = resolver.io_service();
+ (void)ios_ref;
+
+ // basic_resolver functions.
+
+ resolver.cancel();
+
+ ip::tcp::resolver::iterator iter1 = resolver.resolve(q);
+ (void)iter1;
+
+ ip::tcp::resolver::iterator iter2 = resolver.resolve(q, ec);
+ (void)iter2;
+
+ ip::tcp::resolver::iterator iter3 = resolver.resolve(e);
+ (void)iter3;
+
+ ip::tcp::resolver::iterator iter4 = resolver.resolve(e, ec);
+ (void)iter4;
+
+ resolver.async_resolve(q, resolve_handler);
+
+ resolver.async_resolve(e, resolve_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_tcp_resolver_compile
+
+//------------------------------------------------------------------------------
+
 test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/tcp");
@@ -559,5 +621,6 @@
   test->add(BOOST_TEST_CASE(&ip_tcp_socket_compile::test));
   test->add(BOOST_TEST_CASE(&ip_tcp_socket_runtime::test));
   test->add(BOOST_TEST_CASE(&ip_tcp_acceptor_runtime::test));
+ test->add(BOOST_TEST_CASE(&ip_tcp_resolver_compile::test));
   return test;
 }

Modified: trunk/libs/asio/test/ip/udp.cpp
==============================================================================
--- trunk/libs/asio/test/ip/udp.cpp (original)
+++ trunk/libs/asio/test/ip/udp.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -334,10 +334,73 @@
 
 //------------------------------------------------------------------------------
 
+// ip_udp_resolver_compile test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks that all public member functions on the class
+// ip::udp::resolver compile and link correctly. Runtime failures are ignored.
+
+namespace ip_udp_resolver_compile {
+
+void resolve_handler(const boost::system::error_code&,
+ boost::asio::ip::udp::resolver::iterator)
+{
+}
+
+void test()
+{
+ using namespace boost::asio;
+ namespace ip = boost::asio::ip;
+
+ try
+ {
+ io_service ios;
+ boost::system::error_code ec;
+ ip::udp::resolver::query q(ip::udp::v4(), "localhost", "0");
+ ip::udp::endpoint e(ip::address_v4::loopback(), 0);
+
+ // basic_resolver constructors.
+
+ ip::udp::resolver resolver(ios);
+
+ // basic_io_object functions.
+
+ io_service& ios_ref = resolver.io_service();
+ (void)ios_ref;
+
+ // basic_resolver functions.
+
+ resolver.cancel();
+
+ ip::udp::resolver::iterator iter1 = resolver.resolve(q);
+ (void)iter1;
+
+ ip::udp::resolver::iterator iter2 = resolver.resolve(q, ec);
+ (void)iter2;
+
+ ip::udp::resolver::iterator iter3 = resolver.resolve(e);
+ (void)iter3;
+
+ ip::udp::resolver::iterator iter4 = resolver.resolve(e, ec);
+ (void)iter4;
+
+ resolver.async_resolve(q, resolve_handler);
+
+ resolver.async_resolve(e, resolve_handler);
+ }
+ catch (std::exception&)
+ {
+ }
+}
+
+} // namespace ip_udp_resolver_compile
+
+//------------------------------------------------------------------------------
+
 test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/udp");
   test->add(BOOST_TEST_CASE(&ip_udp_socket_compile::test));
   test->add(BOOST_TEST_CASE(&ip_udp_socket_runtime::test));
+ test->add(BOOST_TEST_CASE(&ip_udp_resolver_compile::test));
   return test;
 }

Modified: trunk/libs/asio/test/ip/unicast.cpp
==============================================================================
--- trunk/libs/asio/test/ip/unicast.cpp (original)
+++ trunk/libs/asio/test/ip/unicast.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -46,7 +46,7 @@
     ip::unicast::hops hops2;
     sock.get_option(hops2);
     hops1 = 1;
- static_cast<int>(hops1.value());
+ (void)static_cast<int>(hops1.value());
   }
   catch (std::exception&)
   {

Modified: trunk/libs/asio/test/ip/v6_only.cpp
==============================================================================
--- trunk/libs/asio/test/ip/v6_only.cpp (original)
+++ trunk/libs/asio/test/ip/v6_only.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -47,9 +47,9 @@
     ip::v6_only v6_only2;
     sock.get_option(v6_only2);
     v6_only1 = true;
- static_cast<bool>(v6_only1);
- static_cast<bool>(!v6_only1);
- static_cast<bool>(v6_only1.value());
+ (void)static_cast<bool>(v6_only1);
+ (void)static_cast<bool>(!v6_only1);
+ (void)static_cast<bool>(v6_only1.value());
   }
   catch (std::exception&)
   {

Modified: trunk/libs/asio/test/read.cpp
==============================================================================
--- trunk/libs/asio/test/read.cpp (original)
+++ trunk/libs/asio/test/read.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,6 +16,7 @@
 // Test that header file is self-contained.
 #include <boost/asio/read.hpp>
 
+#include <boost/array.hpp>
 #include <boost/bind.hpp>
 #include <boost/noncopyable.hpp>
 #include <cstring>
@@ -61,7 +62,7 @@
   }
 
   template <typename Const_Buffers>
- bool check(const Const_Buffers& buffers, size_t length)
+ bool check_buffers(const Const_Buffers& buffers, size_t length)
   {
     if (length != position_)
       return false;
@@ -147,21 +148,21 @@
   memset(read_buf, 0, sizeof(read_buf));
   size_t bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_2_arg_multi_buffers_read()
@@ -177,21 +178,21 @@
   memset(read_buf, 0, sizeof(read_buf));
   size_t bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_2_arg_streambuf_read()
@@ -205,7 +206,7 @@
   size_t bytes_transferred = boost::asio::read(s, sb);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -213,7 +214,7 @@
   bytes_transferred = boost::asio::read(s, sb);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -221,7 +222,7 @@
   bytes_transferred = boost::asio::read(s, sb);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 }
 
 bool old_style_transfer_all(const boost::system::error_code& ec,
@@ -249,7 +250,7 @@
   size_t bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -257,7 +258,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -265,14 +266,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -280,7 +281,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -288,14 +289,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -303,7 +304,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -311,14 +312,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -326,7 +327,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -334,47 +335,47 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_3_arg_multi_buffers_read()
@@ -391,7 +392,7 @@
   size_t bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -399,7 +400,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -407,14 +408,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -422,7 +423,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -430,14 +431,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -445,7 +446,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -453,14 +454,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -468,7 +469,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -476,47 +477,47 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_3_arg_streambuf_read()
@@ -531,7 +532,7 @@
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -540,7 +541,7 @@
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -549,7 +550,7 @@
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -557,7 +558,7 @@
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -566,7 +567,7 @@
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
   BOOST_CHECK(sb.size() == 1);
- BOOST_CHECK(s.check(sb.data(), 1));
+ BOOST_CHECK(s.check_buffers(sb.data(), 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -575,7 +576,7 @@
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -583,7 +584,7 @@
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -592,7 +593,7 @@
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -601,7 +602,7 @@
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -609,7 +610,7 @@
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -618,7 +619,7 @@
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
   BOOST_CHECK(sb.size() == 42);
- BOOST_CHECK(s.check(sb.data(), 42));
+ BOOST_CHECK(s.check_buffers(sb.data(), 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -627,14 +628,14 @@
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
   BOOST_CHECK(sb.size() == 50);
- BOOST_CHECK(s.check(sb.data(), 50));
+ BOOST_CHECK(s.check_buffers(sb.data(), 50));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
   bytes_transferred = boost::asio::read(s, sb, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -642,7 +643,7 @@
   bytes_transferred = boost::asio::read(s, sb, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -650,14 +651,14 @@
   bytes_transferred = boost::asio::read(s, sb, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
   bytes_transferred = boost::asio::read(s, sb, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -665,7 +666,7 @@
   bytes_transferred = boost::asio::read(s, sb, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -673,7 +674,7 @@
   bytes_transferred = boost::asio::read(s, sb, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 }
 
 void test_4_arg_mutable_buffers_1_read()
@@ -690,7 +691,7 @@
   size_t bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -700,7 +701,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -710,7 +711,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -719,7 +720,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -729,7 +730,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -739,7 +740,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -748,7 +749,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -758,7 +759,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -768,7 +769,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -777,7 +778,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -787,7 +788,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -797,7 +798,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -805,7 +806,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -815,7 +816,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -825,14 +826,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -841,7 +842,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -850,7 +851,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 }
 
@@ -869,7 +870,7 @@
   size_t bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -879,7 +880,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -889,7 +890,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -898,7 +899,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -908,7 +909,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -918,7 +919,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -927,7 +928,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -937,7 +938,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -947,7 +948,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -956,7 +957,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -966,7 +967,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -976,7 +977,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -984,7 +985,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -994,7 +995,7 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1004,14 +1005,14 @@
   bytes_transferred = boost::asio::read(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1020,7 +1021,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1029,7 +1030,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::read(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
   BOOST_CHECK(!error);
 }
 
@@ -1046,7 +1047,7 @@
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1057,7 +1058,7 @@
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1068,7 +1069,7 @@
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1078,7 +1079,7 @@
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1089,7 +1090,7 @@
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
   BOOST_CHECK(sb.size() == 1);
- BOOST_CHECK(s.check(sb.data(), 1));
+ BOOST_CHECK(s.check_buffers(sb.data(), 1));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1100,7 +1101,7 @@
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1110,7 +1111,7 @@
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1121,7 +1122,7 @@
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1132,7 +1133,7 @@
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1142,7 +1143,7 @@
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1153,7 +1154,7 @@
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
   BOOST_CHECK(sb.size() == 42);
- BOOST_CHECK(s.check(sb.data(), 42));
+ BOOST_CHECK(s.check_buffers(sb.data(), 42));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1164,7 +1165,7 @@
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
   BOOST_CHECK(sb.size() == 50);
- BOOST_CHECK(s.check(sb.data(), 50));
+ BOOST_CHECK(s.check_buffers(sb.data(), 50));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1173,7 +1174,7 @@
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1184,7 +1185,7 @@
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1195,7 +1196,7 @@
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1203,7 +1204,7 @@
   bytes_transferred = boost::asio::read(s, sb, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1213,7 +1214,7 @@
   bytes_transferred = boost::asio::read(s, sb, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 
   s.reset(read_data, sizeof(read_data));
@@ -1223,7 +1224,7 @@
   bytes_transferred = boost::asio::read(s, sb, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
   BOOST_CHECK(!error);
 }
 
@@ -1254,7 +1255,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1268,7 +1269,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1282,7 +1283,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_3_arg_multi_buffers_async_read()
@@ -1305,7 +1306,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1319,7 +1320,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1333,7 +1334,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_3_arg_streambuf_async_read()
@@ -1354,7 +1355,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1369,7 +1370,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1384,7 +1385,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 }
 
 void test_4_arg_mutable_buffers_1_async_read()
@@ -1406,7 +1407,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1420,7 +1421,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1434,7 +1435,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1447,7 +1448,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1461,7 +1462,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1475,7 +1476,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1488,7 +1489,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1502,7 +1503,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1516,7 +1517,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1529,7 +1530,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1543,7 +1544,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1557,7 +1558,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1570,7 +1571,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1584,7 +1585,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1598,7 +1599,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1611,7 +1612,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1625,7 +1626,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1639,7 +1640,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_4_arg_multi_buffers_async_read()
@@ -1662,7 +1663,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1676,7 +1677,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1690,7 +1691,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1703,7 +1704,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1717,7 +1718,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1731,7 +1732,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1744,7 +1745,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1758,7 +1759,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1772,7 +1773,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1785,7 +1786,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1799,7 +1800,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1813,7 +1814,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1826,7 +1827,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1840,7 +1841,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1854,7 +1855,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
@@ -1867,7 +1868,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1881,7 +1882,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1895,7 +1896,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(read_data)));
 }
 
 void test_4_arg_streambuf_async_read()
@@ -1916,7 +1917,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1931,7 +1932,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1946,7 +1947,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -1960,7 +1961,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -1975,7 +1976,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 1);
- BOOST_CHECK(s.check(sb.data(), 1));
+ BOOST_CHECK(s.check_buffers(sb.data(), 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -1990,7 +1991,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -2004,7 +2005,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -2019,7 +2020,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -2034,7 +2035,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 10);
- BOOST_CHECK(s.check(sb.data(), 10));
+ BOOST_CHECK(s.check_buffers(sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -2048,7 +2049,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -2063,7 +2064,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 42);
- BOOST_CHECK(s.check(sb.data(), 42));
+ BOOST_CHECK(s.check_buffers(sb.data(), 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -2078,7 +2079,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == 50);
- BOOST_CHECK(s.check(sb.data(), 50));
+ BOOST_CHECK(s.check_buffers(sb.data(), 50));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -2092,7 +2093,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -2107,7 +2108,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -2122,7 +2123,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   sb.consume(sb.size());
@@ -2136,7 +2137,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -2151,7 +2152,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -2166,7 +2167,7 @@
   ios.run();
   BOOST_CHECK(called);
   BOOST_CHECK(sb.size() == sizeof(read_data));
- BOOST_CHECK(s.check(sb.data(), sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(sb.data(), sizeof(read_data)));
 }
 
 test_suite* init_unit_test_suite(int, char*[])

Modified: trunk/libs/asio/test/read_at.cpp
==============================================================================
--- trunk/libs/asio/test/read_at.cpp (original)
+++ trunk/libs/asio/test/read_at.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,11 +16,13 @@
 // Test that header file is self-contained.
 #include <boost/asio/read_at.hpp>
 
+#include <boost/array.hpp>
 #include <boost/bind.hpp>
 #include <boost/noncopyable.hpp>
 #include <cstring>
 #include <boost/asio/io_service.hpp>
 #include <boost/asio/placeholders.hpp>
+#include <boost/asio/streambuf.hpp>
 #include "unit_test.hpp"
 
 using namespace std; // For memcmp, memcpy and memset.
@@ -63,7 +65,7 @@
   }
 
   template <typename Const_Buffers>
- bool check(boost::uint64_t offset,
+ bool check_buffers(boost::uint64_t offset,
       const Const_Buffers& buffers, size_t length)
   {
     if (offset + length > max_length)
@@ -139,7 +141,7 @@
 static const char read_data[]
   = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
-void test_3_arg_read_at()
+void test_3_arg_mutable_buffers_1_read_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
@@ -151,41 +153,144 @@
   memset(read_buf, 0, sizeof(read_buf));
   size_t bytes_transferred = boost::asio::read_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_3_arg_multi_buffers_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::array<boost::asio::mutable_buffer, 2> buffers = { {
+ boost::asio::buffer(read_buf, 32),
+ boost::asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ size_t bytes_transferred = boost::asio::read_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_3_arg_streambuf_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = boost::asio::read_at(s, 0, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 }
 
 bool old_style_transfer_all(const boost::system::error_code& ec,
@@ -200,7 +305,7 @@
   return !!ec ? 0 : 3;
 }
 
-void test_4_arg_read_at()
+void test_4_arg_mutable_buffers_1_read_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
@@ -213,14 +318,14 @@
   size_t bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -228,7 +333,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -236,7 +341,7 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -244,7 +349,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -252,21 +357,21 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -274,7 +379,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(0, buffers, 1));
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -282,7 +387,7 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(1234, buffers, 1));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -290,7 +395,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -298,21 +403,21 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -320,7 +425,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -328,7 +433,7 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -336,7 +441,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -344,21 +449,21 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -366,7 +471,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(0, buffers, 42));
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -374,7 +479,7 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(1234, buffers, 42));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -382,7 +487,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(0, buffers, 50));
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -390,21 +495,21 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(1234, buffers, 50));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -412,7 +517,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
@@ -420,7 +525,7 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -428,7 +533,7 @@
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
@@ -436,421 +541,2991 @@
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 }
 
-void test_5_arg_read_at()
+void test_4_arg_multi_buffers_read_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
   char read_buf[sizeof(read_data)];
- boost::asio::mutable_buffers_1 buffers
- = boost::asio::buffer(read_buf, sizeof(read_buf));
+ boost::array<boost::asio::mutable_buffer, 2> buffers = { {
+ boost::asio::buffer(read_buf, 32),
+ boost::asio::buffer(read_buf) + 32 } };
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- boost::system::error_code error;
   size_t bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(0, buffers, 1));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(1234, buffers, 1));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(0, buffers, 42));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(1234, buffers, 42));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(0, buffers, 50));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(1234, buffers, 50));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 0, buffers,
- old_style_transfer_all, error);
+ old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- old_style_transfer_all, error);
+ old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_streambuf_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ size_t bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 50));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+void test_5_arg_mutable_buffers_1_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+}
+
+void test_5_arg_multi_buffers_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::array<boost::asio::mutable_buffer, 2> buffers = { {
+ boost::asio::buffer(read_buf, 32),
+ boost::asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(!error);
+}
+
+void test_5_arg_streambuf_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 1));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 42));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 50));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 0, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::read_at(s, 1234, sb,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(read_data));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+ BOOST_CHECK(!error);
+}
+
+void async_read_handler(const boost::system::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!e);
+ BOOST_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_4_arg_mutable_buffers_1_async_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_multi_buffers_async_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::array<boost::asio::mutable_buffer, 2> buffers = { {
+ boost::asio::buffer(read_buf, 32),
+ boost::asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_4_arg_streambuf_async_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::streambuf sb(sizeof(read_data));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ bool called = false;
+ boost::asio::async_read_at(s, 0, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ sb.consume(sb.size());
+ called = false;
+ boost::asio::async_read_at(s, 1234, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ boost::asio::async_read_at(s, 0, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ sb.consume(sb.size());
+ called = false;
+ boost::asio::async_read_at(s, 1234, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ boost::asio::async_read_at(s, 0, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ sb.consume(sb.size());
+ called = false;
+ boost::asio::async_read_at(s, 1234, sb,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
+}
+
+void test_5_arg_mutable_buffers_1_async_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(read_buf, sizeof(read_buf));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+}
+
+void test_5_arg_multi_buffers_async_read_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ char read_buf[sizeof(read_data)];
+ boost::array<boost::asio::mutable_buffer, 2> buffers = { {
+ boost::asio::buffer(read_buf, 32),
+ boost::asio::buffer(read_buf) + 32 } };
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ bool called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(1);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ s.next_read_length(10);
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
+
+ s.reset(read_data, sizeof(read_data));
+ memset(read_buf, 0, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 0, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 0, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- bytes_transferred = boost::asio::read_at(s, 0, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 0, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 0, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
- error = boost::system::error_code();
- bytes_transferred = boost::asio::read_at(s, 1234, buffers,
- short_transfer, error);
- BOOST_CHECK(bytes_transferred == sizeof(read_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
- BOOST_CHECK(!error);
-}
-
-void async_read_handler(const boost::system::error_code& e,
- size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
-{
- *called = true;
- BOOST_CHECK(!e);
- BOOST_CHECK(bytes_transferred == expected_bytes_transferred);
-}
-
-void test_4_arg_async_read_at()
-{
- boost::asio::io_service ios;
- test_random_access_device s(ios);
- char read_buf[sizeof(read_data)];
- boost::asio::mutable_buffers_1 buffers
- = boost::asio::buffer(read_buf, sizeof(read_buf));
+ called = false;
+ boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_read_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(read_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
- bool called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ called = false;
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -858,12 +3533,12 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   memset(read_buf, 0, sizeof(read_buf));
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -871,13 +3546,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -885,13 +3560,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
   memset(read_buf, 0, sizeof(read_buf));
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -899,13 +3574,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -913,13 +3588,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
   memset(read_buf, 0, sizeof(read_buf));
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, buffers, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -927,21 +3602,19 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(read_data)));
 }
 
-void test_5_arg_async_read_at()
+void test_5_arg_streambuf_async_read_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
- char read_buf[sizeof(read_data)];
- boost::asio::mutable_buffers_1 buffers
- = boost::asio::buffer(read_buf, sizeof(read_buf));
+ boost::asio::streambuf sb(sizeof(read_data));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   bool called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -950,12 +3623,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -964,13 +3638,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -979,13 +3654,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -994,13 +3670,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1009,13 +3686,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_all(),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1024,12 +3702,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1038,12 +3717,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1052,13 +3732,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1067,13 +3748,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 1));
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1082,13 +3764,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 1));
+ BOOST_CHECK(sb.size() == 1);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 1));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1097,13 +3780,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(1),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1112,12 +3796,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1126,12 +3811,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1140,13 +3826,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1155,13 +3842,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1170,13 +3858,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1185,13 +3874,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(10),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1200,12 +3890,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(sb.size() == 10);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 10));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1214,12 +3905,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1228,13 +3920,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1243,13 +3936,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 42));
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1258,13 +3952,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 42));
+ BOOST_CHECK(sb.size() == 42);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 42));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers,
+ boost::asio::async_read_at(s, 0, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1273,13 +3968,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 50));
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(0, sb.data(), 50));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers,
+ boost::asio::async_read_at(s, 1234, sb,
       boost::asio::transfer_at_least(42),
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
@@ -1288,12 +3984,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 50));
+ BOOST_CHECK(sb.size() == 50);
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), 50));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 0, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1301,12 +3998,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 1234, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1314,13 +4012,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 0, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1328,13 +4027,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 1234, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1342,13 +4042,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 0, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1356,13 +4057,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, old_style_transfer_all,
+ boost::asio::async_read_at(s, 1234, sb, old_style_transfer_all,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1370,12 +4072,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::asio::async_read_at(s, 0, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1383,12 +4086,13 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::asio::async_read_at(s, 1234, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1396,13 +4100,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::asio::async_read_at(s, 0, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1410,13 +4115,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(1);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::asio::async_read_at(s, 1234, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1424,13 +4130,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 0, buffers, short_transfer,
+ boost::asio::async_read_at(s, 0, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1438,13 +4145,14 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(0, sb.data(), sizeof(read_data)));
 
   s.reset(read_data, sizeof(read_data));
   s.next_read_length(10);
- memset(read_buf, 0, sizeof(read_buf));
+ sb.consume(sb.size());
   called = false;
- boost::asio::async_read_at(s, 1234, buffers, short_transfer,
+ boost::asio::async_read_at(s, 1234, sb, short_transfer,
       boost::bind(async_read_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
@@ -1452,16 +4160,27 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));
+ BOOST_CHECK(sb.size() == sizeof(read_data));
+ BOOST_CHECK(s.check_buffers(1234, sb.data(), sizeof(read_data)));
 }
 
 test_suite* init_unit_test_suite(int, char*[])
 {
- test_suite* test = BOOST_TEST_SUITE("read");
- test->add(BOOST_TEST_CASE(&test_3_arg_read_at));
- test->add(BOOST_TEST_CASE(&test_4_arg_read_at));
- test->add(BOOST_TEST_CASE(&test_5_arg_read_at));
- test->add(BOOST_TEST_CASE(&test_4_arg_async_read_at));
- test->add(BOOST_TEST_CASE(&test_5_arg_async_read_at));
+ test_suite* test = BOOST_TEST_SUITE("read_at");
+ test->add(BOOST_TEST_CASE(&test_3_arg_mutable_buffers_1_read_at));
+ test->add(BOOST_TEST_CASE(&test_3_arg_multi_buffers_read_at));
+ test->add(BOOST_TEST_CASE(&test_3_arg_streambuf_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_mutable_buffers_1_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_multi_buffers_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_streambuf_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_mutable_buffers_1_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_multi_buffers_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_streambuf_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_mutable_buffers_1_async_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_multi_buffers_async_read_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_streambuf_async_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_mutable_buffers_1_async_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_multi_buffers_async_read_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_streambuf_async_read_at));
   return test;
 }

Modified: trunk/libs/asio/test/serial_port_base.cpp
==============================================================================
--- trunk/libs/asio/test/serial_port_base.cpp (original)
+++ trunk/libs/asio/test/serial_port_base.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -46,7 +46,7 @@
     port.set_option(baud_rate1);
     serial_port_base::baud_rate baud_rate2;
     port.get_option(baud_rate2);
- static_cast<unsigned int>(baud_rate2.value());
+ (void)static_cast<unsigned int>(baud_rate2.value());
 
     // flow_control class.
 
@@ -55,7 +55,8 @@
     port.set_option(flow_control1);
     serial_port_base::flow_control flow_control2;
     port.get_option(flow_control2);
- static_cast<serial_port_base::flow_control::type>(flow_control2.value());
+ (void)static_cast<serial_port_base::flow_control::type>(
+ flow_control2.value());
 
     // parity class.
 
@@ -63,7 +64,7 @@
     port.set_option(parity1);
     serial_port_base::parity parity2;
     port.get_option(parity2);
- static_cast<serial_port_base::parity::type>(parity2.value());
+ (void)static_cast<serial_port_base::parity::type>(parity2.value());
 
     // stop_bits class.
 
@@ -71,7 +72,7 @@
     port.set_option(stop_bits1);
     serial_port_base::stop_bits stop_bits2;
     port.get_option(stop_bits2);
- static_cast<serial_port_base::stop_bits::type>(stop_bits2.value());
+ (void)static_cast<serial_port_base::stop_bits::type>(stop_bits2.value());
 
     // character_size class.
 
@@ -79,7 +80,7 @@
     port.set_option(character_size1);
     serial_port_base::character_size character_size2;
     port.get_option(character_size2);
- static_cast<unsigned int>(character_size2.value());
+ (void)static_cast<unsigned int>(character_size2.value());
   }
   catch (std::exception&)
   {

Modified: trunk/libs/asio/test/socket_base.cpp
==============================================================================
--- trunk/libs/asio/test/socket_base.cpp (original)
+++ trunk/libs/asio/test/socket_base.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -60,9 +60,9 @@
     socket_base::broadcast broadcast2;
     sock.get_option(broadcast2);
     broadcast1 = true;
- static_cast<bool>(broadcast1);
- static_cast<bool>(!broadcast1);
- static_cast<bool>(broadcast1.value());
+ (void)static_cast<bool>(broadcast1);
+ (void)static_cast<bool>(!broadcast1);
+ (void)static_cast<bool>(broadcast1.value());
 
     // debug class.
 
@@ -71,9 +71,9 @@
     socket_base::debug debug2;
     sock.get_option(debug2);
     debug1 = true;
- static_cast<bool>(debug1);
- static_cast<bool>(!debug1);
- static_cast<bool>(debug1.value());
+ (void)static_cast<bool>(debug1);
+ (void)static_cast<bool>(!debug1);
+ (void)static_cast<bool>(debug1.value());
 
     // do_not_route class.
 
@@ -82,9 +82,9 @@
     socket_base::do_not_route do_not_route2;
     sock.get_option(do_not_route2);
     do_not_route1 = true;
- static_cast<bool>(do_not_route1);
- static_cast<bool>(!do_not_route1);
- static_cast<bool>(do_not_route1.value());
+ (void)static_cast<bool>(do_not_route1);
+ (void)static_cast<bool>(!do_not_route1);
+ (void)static_cast<bool>(do_not_route1.value());
 
     // keep_alive class.
 
@@ -93,9 +93,9 @@
     socket_base::keep_alive keep_alive2;
     sock.get_option(keep_alive2);
     keep_alive1 = true;
- static_cast<bool>(keep_alive1);
- static_cast<bool>(!keep_alive1);
- static_cast<bool>(keep_alive1.value());
+ (void)static_cast<bool>(keep_alive1);
+ (void)static_cast<bool>(!keep_alive1);
+ (void)static_cast<bool>(keep_alive1.value());
 
     // send_buffer_size class.
 
@@ -104,7 +104,7 @@
     socket_base::send_buffer_size send_buffer_size2;
     sock.get_option(send_buffer_size2);
     send_buffer_size1 = 1;
- static_cast<int>(send_buffer_size1.value());
+ (void)static_cast<int>(send_buffer_size1.value());
 
     // send_low_watermark class.
 
@@ -113,7 +113,7 @@
     socket_base::send_low_watermark send_low_watermark2;
     sock.get_option(send_low_watermark2);
     send_low_watermark1 = 1;
- static_cast<int>(send_low_watermark1.value());
+ (void)static_cast<int>(send_low_watermark1.value());
 
     // receive_buffer_size class.
 
@@ -122,7 +122,7 @@
     socket_base::receive_buffer_size receive_buffer_size2;
     sock.get_option(receive_buffer_size2);
     receive_buffer_size1 = 1;
- static_cast<int>(receive_buffer_size1.value());
+ (void)static_cast<int>(receive_buffer_size1.value());
 
     // receive_low_watermark class.
 
@@ -131,7 +131,7 @@
     socket_base::receive_low_watermark receive_low_watermark2;
     sock.get_option(receive_low_watermark2);
     receive_low_watermark1 = 1;
- static_cast<int>(receive_low_watermark1.value());
+ (void)static_cast<int>(receive_low_watermark1.value());
 
     // reuse_address class.
 
@@ -140,9 +140,9 @@
     socket_base::reuse_address reuse_address2;
     sock.get_option(reuse_address2);
     reuse_address1 = true;
- static_cast<bool>(reuse_address1);
- static_cast<bool>(!reuse_address1);
- static_cast<bool>(reuse_address1.value());
+ (void)static_cast<bool>(reuse_address1);
+ (void)static_cast<bool>(!reuse_address1);
+ (void)static_cast<bool>(reuse_address1.value());
 
     // linger class.
 
@@ -151,9 +151,9 @@
     socket_base::linger linger2;
     sock.get_option(linger2);
     linger1.enabled(true);
- static_cast<bool>(linger1.enabled());
+ (void)static_cast<bool>(linger1.enabled());
     linger1.timeout(1);
- static_cast<int>(linger1.timeout());
+ (void)static_cast<int>(linger1.timeout());
 
     // enable_connection_aborted class.
 
@@ -162,9 +162,9 @@
     socket_base::enable_connection_aborted enable_connection_aborted2;
     sock.get_option(enable_connection_aborted2);
     enable_connection_aborted1 = true;
- static_cast<bool>(enable_connection_aborted1);
- static_cast<bool>(!enable_connection_aborted1);
- static_cast<bool>(enable_connection_aborted1.value());
+ (void)static_cast<bool>(enable_connection_aborted1);
+ (void)static_cast<bool>(!enable_connection_aborted1);
+ (void)static_cast<bool>(enable_connection_aborted1.value());
 
     // non_blocking_io class.
 

Modified: trunk/libs/asio/test/write.cpp
==============================================================================
--- trunk/libs/asio/test/write.cpp (original)
+++ trunk/libs/asio/test/write.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -62,7 +62,7 @@
   }
 
   template <typename Const_Buffers>
- bool check(const Const_Buffers& buffers, size_t length)
+ bool check_buffers(const Const_Buffers& buffers, size_t length)
   {
     if (length != position_)
       return false;
@@ -148,19 +148,19 @@
   s.reset();
   size_t bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_2_arg_mutable_buffers_1_write()
@@ -173,19 +173,19 @@
   s.reset();
   size_t bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 }
 
 void test_2_arg_multi_buffers_write()
@@ -199,19 +199,19 @@
   s.reset();
   size_t bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 bool old_style_transfer_all(const boost::system::error_code& ec,
@@ -237,115 +237,115 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_3_arg_mutable_buffers_1_write()
@@ -359,115 +359,115 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 }
 
 void test_3_arg_multi_buffers_write()
@@ -482,115 +482,115 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write(s, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_4_arg_const_buffers_1_write()
@@ -605,7 +605,7 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -614,7 +614,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -623,7 +623,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -631,7 +631,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -640,7 +640,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -649,7 +649,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -657,7 +657,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -666,7 +666,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -675,7 +675,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -683,7 +683,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -692,7 +692,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -701,14 +701,14 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -717,7 +717,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -726,13 +726,13 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -740,7 +740,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -748,7 +748,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 }
 
@@ -764,7 +764,7 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -773,7 +773,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -782,7 +782,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -790,7 +790,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -799,7 +799,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -808,7 +808,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -816,7 +816,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -825,7 +825,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -834,7 +834,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -842,7 +842,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -851,7 +851,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -860,14 +860,14 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -876,7 +876,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -885,13 +885,13 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -899,7 +899,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -907,7 +907,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
   BOOST_CHECK(!error);
 }
 
@@ -924,7 +924,7 @@
   size_t bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -933,7 +933,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -942,7 +942,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_all(), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -950,7 +950,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -959,7 +959,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -968,7 +968,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(1), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -976,7 +976,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -985,7 +985,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -994,7 +994,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(10), error);
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1002,7 +1002,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1011,7 +1011,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1020,14 +1020,14 @@
   bytes_transferred = boost::asio::write(s, buffers,
       boost::asio::transfer_at_least(42), error);
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1036,7 +1036,7 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1045,13 +1045,13 @@
   bytes_transferred = boost::asio::write(s, buffers,
       old_style_transfer_all, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1059,7 +1059,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 
   s.reset();
@@ -1067,7 +1067,7 @@
   error = boost::system::error_code();
   bytes_transferred = boost::asio::write(s, buffers, short_transfer, error);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
   BOOST_CHECK(!error);
 }
 
@@ -1096,7 +1096,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1109,7 +1109,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1122,7 +1122,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_3_arg_mutable_buffers_1_async_write()
@@ -1142,7 +1142,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1155,7 +1155,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1168,7 +1168,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 }
 
 void test_3_arg_multi_buffers_async_write()
@@ -1189,7 +1189,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1202,7 +1202,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1215,7 +1215,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_4_arg_const_buffers_1_async_write()
@@ -1235,7 +1235,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1248,7 +1248,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1261,7 +1261,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1273,7 +1273,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1286,7 +1286,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
@@ -1299,7 +1299,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1311,7 +1311,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1324,7 +1324,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1337,7 +1337,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1349,7 +1349,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1362,7 +1362,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
@@ -1375,7 +1375,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   called = false;
@@ -1387,7 +1387,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1400,7 +1400,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1413,7 +1413,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1425,7 +1425,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1438,7 +1438,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1451,7 +1451,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 void test_4_arg_mutable_buffers_1_async_write()
@@ -1471,7 +1471,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1484,7 +1484,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1497,7 +1497,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   called = false;
@@ -1509,7 +1509,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1522,7 +1522,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
@@ -1535,7 +1535,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1547,7 +1547,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1560,7 +1560,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1573,7 +1573,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1585,7 +1585,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1598,7 +1598,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
@@ -1611,7 +1611,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   called = false;
@@ -1623,7 +1623,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1636,7 +1636,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1649,7 +1649,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   called = false;
@@ -1661,7 +1661,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1674,7 +1674,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1687,7 +1687,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(mutable_write_data)));
 }
 
 void test_4_arg_multi_buffers_async_write()
@@ -1708,7 +1708,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1721,7 +1721,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1734,7 +1734,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1746,7 +1746,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1759,7 +1759,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 1));
+ BOOST_CHECK(s.check_buffers(buffers, 1));
 
   s.reset();
   s.next_write_length(10);
@@ -1772,7 +1772,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1784,7 +1784,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1797,7 +1797,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1810,7 +1810,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 10));
+ BOOST_CHECK(s.check_buffers(buffers, 10));
 
   s.reset();
   called = false;
@@ -1822,7 +1822,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1835,7 +1835,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 42));
+ BOOST_CHECK(s.check_buffers(buffers, 42));
 
   s.reset();
   s.next_write_length(10);
@@ -1848,7 +1848,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, 50));
+ BOOST_CHECK(s.check_buffers(buffers, 50));
 
   s.reset();
   called = false;
@@ -1860,7 +1860,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1873,7 +1873,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1886,7 +1886,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1898,7 +1898,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1911,7 +1911,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1924,7 +1924,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(buffers, sizeof(write_data)));
 }
 
 test_suite* init_unit_test_suite(int, char*[])

Modified: trunk/libs/asio/test/write_at.cpp
==============================================================================
--- trunk/libs/asio/test/write_at.cpp (original)
+++ trunk/libs/asio/test/write_at.cpp 2010-06-06 20:00:45 EDT (Sun, 06 Jun 2010)
@@ -16,6 +16,7 @@
 // Test that header file is self-contained.
 #include <boost/asio/write_at.hpp>
 
+#include <boost/array.hpp>
 #include <boost/bind.hpp>
 #include <boost/noncopyable.hpp>
 #include <cstring>
@@ -56,7 +57,7 @@
   }
 
   template <typename Const_Buffers>
- bool check(boost::uint64_t offset,
+ bool check_buffers(boost::uint64_t offset,
       const Const_Buffers& buffers, size_t length)
   {
     if (offset + length > max_length)
@@ -131,8 +132,10 @@
 
 static const char write_data[]
   = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+static char mutable_write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
 
-void test_3_arg_write_at()
+void test_3_arg_const_buffers_1_write_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
@@ -142,36 +145,121 @@
   s.reset();
   size_t bytes_transferred = boost::asio::write_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_3_arg_mutable_buffers_1_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+}
+
+void test_3_arg_multi_buffers_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::array<boost::asio::const_buffer, 2> buffers = { {
+ boost::asio::buffer(write_data, 32),
+ boost::asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 }
 
 bool old_style_transfer_all(const boost::system::error_code& ec,
@@ -186,7 +274,7 @@
   return !!ec ? 0 : 3;
 }
 
-void test_4_arg_write_at()
+void test_4_arg_const_buffers_1_write_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
@@ -197,662 +285,2948 @@
   size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(0, buffers, 1));
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(1234, buffers, 1));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(0, buffers, 42));
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(1234, buffers, 42));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(0, buffers, 50));
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(1234, buffers, 50));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
       old_style_transfer_all);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
   bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 }
 
-void test_5_arg_write_at()
+void test_4_arg_mutable_buffers_1_write_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
- boost::asio::const_buffers_1 buffers
- = boost::asio::buffer(write_data, sizeof(write_data));
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(mutable_write_data, sizeof(mutable_write_data));
 
   s.reset();
- boost::system::error_code error;
   size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_all(), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_all());
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(0, buffers, 1));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 1);
- BOOST_CHECK(s.check(1234, buffers, 1));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(1), error);
+ boost::asio::transfer_at_least(1));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(0, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(10), error);
+ boost::asio::transfer_at_least(10));
   BOOST_CHECK(bytes_transferred == 10);
- BOOST_CHECK(s.check(1234, buffers, 10));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(0, buffers, 42));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 42);
- BOOST_CHECK(s.check(1234, buffers, 42));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(0, buffers, 50));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- boost::asio::transfer_at_least(42), error);
+ boost::asio::transfer_at_least(42));
   BOOST_CHECK(bytes_transferred == 50);
- BOOST_CHECK(s.check(1234, buffers, 50));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- old_style_transfer_all, error);
- BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
- bytes_transferred = boost::asio::write_at(s, 0, buffers,
- short_transfer, error);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+}
+
+void test_4_arg_multi_buffers_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::array<boost::asio::const_buffer, 2> buffers = { {
+ boost::asio::buffer(write_data, 32),
+ boost::asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- short_transfer, error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- short_transfer, error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- short_transfer, error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 0, buffers,
- short_transfer, error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
- error = boost::system::error_code();
   bytes_transferred = boost::asio::write_at(s, 1234, buffers,
- short_transfer, error);
+ boost::asio::transfer_all());
   BOOST_CHECK(bytes_transferred == sizeof(write_data));
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
- BOOST_CHECK(!error);
-}
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
-void async_write_handler(const boost::system::error_code& e,
- size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
-{
- *called = true;
- BOOST_CHECK(!e);
- BOOST_CHECK(bytes_transferred == expected_bytes_transferred);
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10));
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42));
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 0, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers, short_transfer);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_const_buffers_1_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::const_buffers_1 buffers
+ = boost::asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+}
+
+void test_5_arg_mutable_buffers_1_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(mutable_write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ BOOST_CHECK(!error);
+}
+
+void test_5_arg_multi_buffers_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::array<boost::asio::const_buffer, 2> buffers = { {
+ boost::asio::buffer(write_data, 32),
+ boost::asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ boost::system::error_code error;
+ size_t bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_all(), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 1);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10), error);
+ BOOST_CHECK(bytes_transferred == 10);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 42);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42), error);
+ BOOST_CHECK(bytes_transferred == 50);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ old_style_transfer_all, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(1);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 0, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+
+ s.reset();
+ s.next_write_length(10);
+ error = boost::system::error_code();
+ bytes_transferred = boost::asio::write_at(s, 1234, buffers,
+ short_transfer, error);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(!error);
+}
+
+void async_write_handler(const boost::system::error_code& e,
+ size_t bytes_transferred, size_t expected_bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!e);
+ BOOST_CHECK(bytes_transferred == expected_bytes_transferred);
+}
+
+void test_4_arg_const_buffers_1_async_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::const_buffers_1 buffers
+ = boost::asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_4_arg_mutable_buffers_1_async_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+}
+
+void test_4_arg_multi_buffers_async_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::array<boost::asio::const_buffer, 2> buffers = { {
+ boost::asio::buffer(write_data, 32),
+ boost::asio::buffer(write_data) + 32 } };
+
+ s.reset();
+ bool called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+}
+
+void test_5_arg_const_buffers_1_async_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::const_buffers_1 buffers
+ = boost::asio::buffer(write_data, sizeof(write_data));
+
+ s.reset();
+ bool called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 }
 
-void test_4_arg_async_write_at()
-{
- boost::asio::io_service ios;
- test_random_access_device s(ios);
- boost::asio::const_buffers_1 buffers
- = boost::asio::buffer(write_data, sizeof(write_data));
+void test_5_arg_mutable_buffers_1_async_write_at()
+{
+ boost::asio::io_service ios;
+ test_random_access_device s(ios);
+ boost::asio::mutable_buffers_1 buffers
+ = boost::asio::buffer(mutable_write_data, sizeof(mutable_write_data));
+
+ s.reset();
+ bool called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_all(),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 1, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset();
- bool called = false;
+ s.next_write_length(10);
+ called = false;
   boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(1),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
+ s.next_write_length(10);
   called = false;
   boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(1),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 
   s.reset();
   s.next_write_length(1);
   called = false;
   boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(1);
   called = false;
   boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   called = false;
   boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(10),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
   called = false;
   boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(10),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 10, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 42, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
+
   s.reset();
   s.next_write_length(10);
   called = false;
   boost::asio::async_write_at(s, 0, buffers,
+ boost::asio::transfer_at_least(42),
       boost::bind(async_write_handler,
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred,
- sizeof(write_data), &called));
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers,
+ boost::asio::transfer_at_least(42),
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ 50, &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, old_style_transfer_all,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(1);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 0, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(called);
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(mutable_write_data)));
+
+ s.reset();
+ s.next_write_length(10);
+ called = false;
+ boost::asio::async_write_at(s, 1234, buffers, short_transfer,
+ boost::bind(async_write_handler,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ sizeof(mutable_write_data), &called));
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(mutable_write_data)));
 }
 
-void test_5_arg_async_write_at()
+void test_5_arg_multi_buffers_async_write_at()
 {
   boost::asio::io_service ios;
   test_random_access_device s(ios);
- boost::asio::const_buffers_1 buffers
- = boost::asio::buffer(write_data, sizeof(write_data));
+ boost::array<boost::asio::const_buffer, 2> buffers = { {
+ boost::asio::buffer(write_data, 32),
+ boost::asio::buffer(write_data) + 32 } };
 
   s.reset();
   bool called = false;
@@ -865,7 +3239,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -878,7 +3252,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -892,7 +3266,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -906,7 +3280,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -920,7 +3294,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -934,7 +3308,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -947,7 +3321,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -960,7 +3334,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -974,7 +3348,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 1));
+ BOOST_CHECK(s.check_buffers(0, buffers, 1));
 
   s.reset();
   s.next_write_length(1);
@@ -988,7 +3362,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 1));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 1));
 
   s.reset();
   s.next_write_length(10);
@@ -1002,7 +3376,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1016,7 +3390,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   called = false;
@@ -1029,7 +3403,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1042,7 +3416,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1056,7 +3430,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(1);
@@ -1070,7 +3444,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1084,7 +3458,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 10));
+ BOOST_CHECK(s.check_buffers(0, buffers, 10));
 
   s.reset();
   s.next_write_length(10);
@@ -1098,7 +3472,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 10));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 10));
 
   s.reset();
   called = false;
@@ -1111,7 +3485,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1124,7 +3498,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1138,7 +3512,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 42));
+ BOOST_CHECK(s.check_buffers(0, buffers, 42));
 
   s.reset();
   s.next_write_length(1);
@@ -1152,7 +3526,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 42));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 42));
 
   s.reset();
   s.next_write_length(10);
@@ -1166,7 +3540,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, 50));
+ BOOST_CHECK(s.check_buffers(0, buffers, 50));
 
   s.reset();
   s.next_write_length(10);
@@ -1180,7 +3554,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, 50));
+ BOOST_CHECK(s.check_buffers(1234, buffers, 50));
 
   s.reset();
   called = false;
@@ -1192,7 +3566,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1204,7 +3578,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1217,7 +3591,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1230,7 +3604,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1243,7 +3617,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1256,7 +3630,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1268,7 +3642,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   called = false;
@@ -1280,7 +3654,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1293,7 +3667,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(1);
@@ -1306,7 +3680,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1319,7 +3693,7 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(0, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(0, buffers, sizeof(write_data)));
 
   s.reset();
   s.next_write_length(10);
@@ -1332,16 +3706,26 @@
   ios.reset();
   ios.run();
   BOOST_CHECK(called);
- BOOST_CHECK(s.check(1234, buffers, sizeof(write_data)));
+ BOOST_CHECK(s.check_buffers(1234, buffers, sizeof(write_data)));
 }
 
 test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("write_at");
- test->add(BOOST_TEST_CASE(&test_3_arg_write_at));
- test->add(BOOST_TEST_CASE(&test_4_arg_write_at));
- test->add(BOOST_TEST_CASE(&test_5_arg_write_at));
- test->add(BOOST_TEST_CASE(&test_4_arg_async_write_at));
- test->add(BOOST_TEST_CASE(&test_5_arg_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_3_arg_const_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_3_arg_mutable_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_3_arg_multi_buffers_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_const_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_mutable_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_multi_buffers_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_const_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_mutable_buffers_1_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_multi_buffers_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_const_buffers_1_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_mutable_buffers_1_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_4_arg_multi_buffers_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_const_buffers_1_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_mutable_buffers_1_async_write_at));
+ test->add(BOOST_TEST_CASE(&test_5_arg_multi_buffers_async_write_at));
   return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk