summaryrefslogtreecommitdiff
path: root/boost/asio
diff options
context:
space:
mode:
Diffstat (limited to 'boost/asio')
-rw-r--r--boost/asio/associated_allocator.hpp2
-rw-r--r--boost/asio/associated_executor.hpp2
-rw-r--r--boost/asio/async_result.hpp267
-rw-r--r--boost/asio/awaitable.hpp125
-rw-r--r--boost/asio/basic_datagram_socket.hpp535
-rw-r--r--boost/asio/basic_deadline_timer.hpp258
-rw-r--r--boost/asio/basic_io_object.hpp2
-rw-r--r--boost/asio/basic_raw_socket.hpp537
-rw-r--r--boost/asio/basic_seq_packet_socket.hpp360
-rw-r--r--boost/asio/basic_serial_port.hpp347
-rw-r--r--boost/asio/basic_signal_set.hpp272
-rw-r--r--boost/asio/basic_socket.hpp539
-rw-r--r--boost/asio/basic_socket_acceptor.hpp1258
-rw-r--r--boost/asio/basic_socket_iostream.hpp65
-rw-r--r--boost/asio/basic_socket_streambuf.hpp50
-rw-r--r--boost/asio/basic_stream_socket.hpp428
-rw-r--r--boost/asio/basic_streambuf.hpp2
-rw-r--r--boost/asio/basic_streambuf_fwd.hpp2
-rw-r--r--boost/asio/basic_waitable_timer.hpp267
-rw-r--r--boost/asio/bind_executor.hpp33
-rw-r--r--boost/asio/buffer.hpp495
-rw-r--r--boost/asio/buffered_read_stream.hpp19
-rw-r--r--boost/asio/buffered_read_stream_fwd.hpp2
-rw-r--r--boost/asio/buffered_stream.hpp19
-rw-r--r--boost/asio/buffered_stream_fwd.hpp2
-rw-r--r--boost/asio/buffered_write_stream.hpp19
-rw-r--r--boost/asio/buffered_write_stream_fwd.hpp2
-rw-r--r--boost/asio/buffers_iterator.hpp2
-rw-r--r--boost/asio/co_spawn.hpp90
-rw-r--r--boost/asio/completion_condition.hpp2
-rw-r--r--boost/asio/compose.hpp138
-rw-r--r--boost/asio/connect.hpp165
-rw-r--r--boost/asio/coroutine.hpp6
-rw-r--r--boost/asio/datagram_socket_service.hpp468
-rw-r--r--boost/asio/deadline_timer.hpp2
-rw-r--r--boost/asio/deadline_timer_service.hpp175
-rw-r--r--boost/asio/defer.hpp12
-rw-r--r--boost/asio/detached.hpp (renamed from boost/asio/experimental/detached.hpp)23
-rw-r--r--boost/asio/detail/array.hpp2
-rw-r--r--boost/asio/detail/array_fwd.hpp2
-rw-r--r--boost/asio/detail/assert.hpp2
-rw-r--r--boost/asio/detail/atomic_count.hpp2
-rw-r--r--boost/asio/detail/base_from_completion_cond.hpp7
-rw-r--r--boost/asio/detail/bind_handler.hpp2
-rw-r--r--boost/asio/detail/buffer_resize_guard.hpp2
-rw-r--r--boost/asio/detail/buffer_sequence_adapter.hpp2
-rw-r--r--boost/asio/detail/buffered_stream_storage.hpp2
-rw-r--r--boost/asio/detail/call_stack.hpp2
-rw-r--r--boost/asio/detail/chrono.hpp2
-rw-r--r--boost/asio/detail/chrono_time_traits.hpp2
-rw-r--r--boost/asio/detail/completion_handler.hpp2
-rw-r--r--boost/asio/detail/concurrency_hint.hpp2
-rw-r--r--boost/asio/detail/conditionally_enabled_event.hpp2
-rw-r--r--boost/asio/detail/conditionally_enabled_mutex.hpp2
-rw-r--r--boost/asio/detail/config.hpp64
-rw-r--r--boost/asio/detail/consuming_buffers.hpp2
-rw-r--r--boost/asio/detail/cstddef.hpp2
-rw-r--r--boost/asio/detail/cstdint.hpp2
-rw-r--r--boost/asio/detail/date_time_fwd.hpp2
-rw-r--r--boost/asio/detail/deadline_timer_service.hpp22
-rw-r--r--boost/asio/detail/dependent_type.hpp2
-rw-r--r--boost/asio/detail/descriptor_ops.hpp2
-rw-r--r--boost/asio/detail/descriptor_read_op.hpp16
-rw-r--r--boost/asio/detail/descriptor_write_op.hpp16
-rw-r--r--boost/asio/detail/dev_poll_reactor.hpp2
-rw-r--r--boost/asio/detail/epoll_reactor.hpp2
-rw-r--r--boost/asio/detail/event.hpp2
-rw-r--r--boost/asio/detail/eventfd_select_interrupter.hpp2
-rw-r--r--boost/asio/detail/executor_function.hpp106
-rw-r--r--boost/asio/detail/executor_op.hpp2
-rw-r--r--boost/asio/detail/fd_set_adapter.hpp2
-rw-r--r--boost/asio/detail/fenced_block.hpp2
-rw-r--r--boost/asio/detail/functional.hpp2
-rw-r--r--boost/asio/detail/future.hpp2
-rw-r--r--boost/asio/detail/gcc_arm_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_hppa_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_sync_fenced_block.hpp2
-rw-r--r--boost/asio/detail/gcc_x86_fenced_block.hpp2
-rw-r--r--boost/asio/detail/global.hpp2
-rw-r--r--boost/asio/detail/handler_alloc_helpers.hpp19
-rw-r--r--boost/asio/detail/handler_cont_helpers.hpp2
-rw-r--r--boost/asio/detail/handler_invoke_helpers.hpp2
-rw-r--r--boost/asio/detail/handler_tracking.hpp2
-rw-r--r--boost/asio/detail/handler_type_requirements.hpp2
-rw-r--r--boost/asio/detail/handler_work.hpp34
-rw-r--r--boost/asio/detail/hash_map.hpp2
-rw-r--r--boost/asio/detail/impl/buffer_sequence_adapter.ipp2
-rw-r--r--boost/asio/detail/impl/descriptor_ops.ipp2
-rw-r--r--boost/asio/detail/impl/dev_poll_reactor.hpp2
-rw-r--r--boost/asio/detail/impl/dev_poll_reactor.ipp2
-rw-r--r--boost/asio/detail/impl/epoll_reactor.hpp2
-rw-r--r--boost/asio/detail/impl/epoll_reactor.ipp2
-rw-r--r--boost/asio/detail/impl/eventfd_select_interrupter.ipp2
-rw-r--r--boost/asio/detail/impl/handler_tracking.ipp2
-rw-r--r--boost/asio/detail/impl/kqueue_reactor.hpp2
-rw-r--r--boost/asio/detail/impl/kqueue_reactor.ipp2
-rw-r--r--boost/asio/detail/impl/null_event.ipp2
-rw-r--r--boost/asio/detail/impl/pipe_select_interrupter.ipp2
-rw-r--r--boost/asio/detail/impl/posix_event.ipp2
-rw-r--r--boost/asio/detail/impl/posix_mutex.ipp2
-rw-r--r--boost/asio/detail/impl/posix_thread.ipp2
-rw-r--r--boost/asio/detail/impl/posix_tss_ptr.ipp2
-rw-r--r--boost/asio/detail/impl/reactive_descriptor_service.ipp8
-rw-r--r--boost/asio/detail/impl/reactive_serial_port_service.ipp8
-rw-r--r--boost/asio/detail/impl/reactive_socket_service_base.ipp7
-rw-r--r--boost/asio/detail/impl/resolver_service_base.ipp64
-rw-r--r--boost/asio/detail/impl/scheduler.ipp54
-rw-r--r--boost/asio/detail/impl/select_reactor.hpp2
-rw-r--r--boost/asio/detail/impl/select_reactor.ipp2
-rw-r--r--boost/asio/detail/impl/service_registry.hpp2
-rw-r--r--boost/asio/detail/impl/service_registry.ipp2
-rw-r--r--boost/asio/detail/impl/signal_set_service.ipp42
-rw-r--r--boost/asio/detail/impl/socket_ops.ipp9
-rw-r--r--boost/asio/detail/impl/socket_select_interrupter.ipp2
-rw-r--r--boost/asio/detail/impl/strand_executor_service.hpp2
-rw-r--r--boost/asio/detail/impl/strand_executor_service.ipp2
-rw-r--r--boost/asio/detail/impl/strand_service.hpp2
-rw-r--r--boost/asio/detail/impl/strand_service.ipp2
-rw-r--r--boost/asio/detail/impl/throw_error.ipp2
-rw-r--r--boost/asio/detail/impl/timer_queue_ptime.ipp2
-rw-r--r--boost/asio/detail/impl/timer_queue_set.ipp2
-rw-r--r--boost/asio/detail/impl/win_event.ipp2
-rw-r--r--boost/asio/detail/impl/win_iocp_handle_service.ipp9
-rw-r--r--boost/asio/detail/impl/win_iocp_io_context.hpp2
-rw-r--r--boost/asio/detail/impl/win_iocp_io_context.ipp43
-rw-r--r--boost/asio/detail/impl/win_iocp_serial_port_service.ipp8
-rw-r--r--boost/asio/detail/impl/win_iocp_socket_service_base.ipp10
-rw-r--r--boost/asio/detail/impl/win_mutex.ipp2
-rw-r--r--boost/asio/detail/impl/win_object_handle_service.ipp35
-rw-r--r--boost/asio/detail/impl/win_static_mutex.ipp2
-rw-r--r--boost/asio/detail/impl/win_thread.ipp2
-rw-r--r--boost/asio/detail/impl/win_tss_ptr.ipp2
-rw-r--r--boost/asio/detail/impl/winrt_ssocket_service_base.ipp30
-rw-r--r--boost/asio/detail/impl/winrt_timer_scheduler.hpp8
-rw-r--r--boost/asio/detail/impl/winrt_timer_scheduler.ipp15
-rw-r--r--boost/asio/detail/impl/winsock_init.ipp2
-rw-r--r--boost/asio/detail/io_control.hpp2
-rw-r--r--boost/asio/detail/io_object_executor.hpp162
-rw-r--r--boost/asio/detail/io_object_impl.hpp195
-rw-r--r--boost/asio/detail/is_buffer_sequence.hpp51
-rw-r--r--boost/asio/detail/is_executor.hpp2
-rw-r--r--boost/asio/detail/keyword_tss_ptr.hpp2
-rw-r--r--boost/asio/detail/kqueue_reactor.hpp2
-rw-r--r--boost/asio/detail/local_free_on_block_exit.hpp2
-rw-r--r--boost/asio/detail/macos_fenced_block.hpp2
-rw-r--r--boost/asio/detail/memory.hpp2
-rw-r--r--boost/asio/detail/mutex.hpp2
-rw-r--r--boost/asio/detail/non_const_lvalue.hpp56
-rw-r--r--boost/asio/detail/noncopyable.hpp2
-rw-r--r--boost/asio/detail/null_event.hpp2
-rw-r--r--boost/asio/detail/null_fenced_block.hpp2
-rw-r--r--boost/asio/detail/null_global.hpp2
-rw-r--r--boost/asio/detail/null_mutex.hpp2
-rw-r--r--boost/asio/detail/null_reactor.hpp2
-rw-r--r--boost/asio/detail/null_signal_blocker.hpp2
-rw-r--r--boost/asio/detail/null_socket_service.hpp115
-rw-r--r--boost/asio/detail/null_static_mutex.hpp2
-rw-r--r--boost/asio/detail/null_thread.hpp2
-rw-r--r--boost/asio/detail/null_tss_ptr.hpp2
-rw-r--r--boost/asio/detail/object_pool.hpp2
-rw-r--r--boost/asio/detail/old_win_sdk_compat.hpp2
-rw-r--r--boost/asio/detail/op_queue.hpp2
-rw-r--r--boost/asio/detail/operation.hpp2
-rw-r--r--boost/asio/detail/pipe_select_interrupter.hpp2
-rw-r--r--boost/asio/detail/pop_options.hpp14
-rw-r--r--boost/asio/detail/posix_event.hpp4
-rw-r--r--boost/asio/detail/posix_fd_set_adapter.hpp2
-rw-r--r--boost/asio/detail/posix_global.hpp2
-rw-r--r--boost/asio/detail/posix_mutex.hpp2
-rw-r--r--boost/asio/detail/posix_signal_blocker.hpp2
-rw-r--r--boost/asio/detail/posix_static_mutex.hpp2
-rw-r--r--boost/asio/detail/posix_thread.hpp2
-rw-r--r--boost/asio/detail/posix_tss_ptr.hpp2
-rw-r--r--boost/asio/detail/push_options.hpp14
-rw-r--r--boost/asio/detail/reactive_descriptor_service.hpp53
-rw-r--r--boost/asio/detail/reactive_null_buffers_op.hpp14
-rw-r--r--boost/asio/detail/reactive_serial_port_service.hpp24
-rw-r--r--boost/asio/detail/reactive_socket_accept_op.hpp51
-rw-r--r--boost/asio/detail/reactive_socket_connect_op.hpp15
-rw-r--r--boost/asio/detail/reactive_socket_recv_op.hpp18
-rw-r--r--boost/asio/detail/reactive_socket_recvfrom_op.hpp16
-rw-r--r--boost/asio/detail/reactive_socket_recvmsg_op.hpp15
-rw-r--r--boost/asio/detail/reactive_socket_send_op.hpp18
-rw-r--r--boost/asio/detail/reactive_socket_sendto_op.hpp16
-rw-r--r--boost/asio/detail/reactive_socket_service.hpp115
-rw-r--r--boost/asio/detail/reactive_socket_service_base.hpp83
-rw-r--r--boost/asio/detail/reactive_wait_op.hpp14
-rw-r--r--boost/asio/detail/reactor.hpp2
-rw-r--r--boost/asio/detail/reactor_fwd.hpp2
-rw-r--r--boost/asio/detail/reactor_op.hpp2
-rw-r--r--boost/asio/detail/reactor_op_queue.hpp2
-rw-r--r--boost/asio/detail/recycling_allocator.hpp30
-rw-r--r--boost/asio/detail/regex_fwd.hpp2
-rw-r--r--boost/asio/detail/resolve_endpoint_op.hpp36
-rw-r--r--boost/asio/detail/resolve_op.hpp2
-rw-r--r--boost/asio/detail/resolve_query_op.hpp34
-rw-r--r--boost/asio/detail/resolver_service.hpp36
-rw-r--r--boost/asio/detail/resolver_service_base.hpp41
-rw-r--r--boost/asio/detail/scheduler.hpp15
-rw-r--r--boost/asio/detail/scheduler_operation.hpp2
-rw-r--r--boost/asio/detail/scheduler_thread_info.hpp2
-rw-r--r--boost/asio/detail/scoped_lock.hpp2
-rw-r--r--boost/asio/detail/scoped_ptr.hpp2
-rw-r--r--boost/asio/detail/select_interrupter.hpp2
-rw-r--r--boost/asio/detail/select_reactor.hpp2
-rw-r--r--boost/asio/detail/service_registry.hpp2
-rw-r--r--boost/asio/detail/signal_blocker.hpp2
-rw-r--r--boost/asio/detail/signal_handler.hpp14
-rw-r--r--boost/asio/detail/signal_init.hpp2
-rw-r--r--boost/asio/detail/signal_op.hpp2
-rw-r--r--boost/asio/detail/signal_set_service.hpp36
-rw-r--r--boost/asio/detail/socket_holder.hpp2
-rw-r--r--boost/asio/detail/socket_ops.hpp2
-rw-r--r--boost/asio/detail/socket_option.hpp2
-rw-r--r--boost/asio/detail/socket_select_interrupter.hpp2
-rw-r--r--boost/asio/detail/socket_types.hpp2
-rw-r--r--boost/asio/detail/solaris_fenced_block.hpp2
-rw-r--r--boost/asio/detail/static_mutex.hpp2
-rw-r--r--boost/asio/detail/std_event.hpp2
-rw-r--r--boost/asio/detail/std_fenced_block.hpp2
-rw-r--r--boost/asio/detail/std_global.hpp2
-rw-r--r--boost/asio/detail/std_mutex.hpp2
-rw-r--r--boost/asio/detail/std_static_mutex.hpp2
-rw-r--r--boost/asio/detail/std_thread.hpp2
-rw-r--r--boost/asio/detail/strand_executor_service.hpp2
-rw-r--r--boost/asio/detail/strand_service.hpp2
-rw-r--r--boost/asio/detail/string_view.hpp2
-rw-r--r--boost/asio/detail/thread.hpp2
-rw-r--r--boost/asio/detail/thread_context.hpp2
-rw-r--r--boost/asio/detail/thread_group.hpp8
-rw-r--r--boost/asio/detail/thread_info_base.hpp11
-rw-r--r--boost/asio/detail/throw_error.hpp2
-rw-r--r--boost/asio/detail/throw_exception.hpp2
-rw-r--r--boost/asio/detail/timer_queue.hpp2
-rw-r--r--boost/asio/detail/timer_queue_base.hpp2
-rw-r--r--boost/asio/detail/timer_queue_ptime.hpp2
-rw-r--r--boost/asio/detail/timer_queue_set.hpp2
-rw-r--r--boost/asio/detail/timer_scheduler.hpp2
-rw-r--r--boost/asio/detail/timer_scheduler_fwd.hpp2
-rw-r--r--boost/asio/detail/tss_ptr.hpp2
-rw-r--r--boost/asio/detail/type_traits.hpp2
-rw-r--r--boost/asio/detail/variadic_templates.hpp16
-rw-r--r--boost/asio/detail/wait_handler.hpp16
-rw-r--r--boost/asio/detail/wait_op.hpp2
-rw-r--r--boost/asio/detail/win_event.hpp2
-rw-r--r--boost/asio/detail/win_fd_set_adapter.hpp2
-rw-r--r--boost/asio/detail/win_fenced_block.hpp2
-rw-r--r--boost/asio/detail/win_global.hpp13
-rw-r--r--boost/asio/detail/win_iocp_handle_read_op.hpp16
-rw-r--r--boost/asio/detail/win_iocp_handle_service.hpp72
-rw-r--r--boost/asio/detail/win_iocp_handle_write_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_io_context.hpp14
-rw-r--r--boost/asio/detail/win_iocp_null_buffers_op.hpp14
-rw-r--r--boost/asio/detail/win_iocp_operation.hpp2
-rw-r--r--boost/asio/detail/win_iocp_overlapped_op.hpp14
-rw-r--r--boost/asio/detail/win_iocp_overlapped_ptr.hpp42
-rw-r--r--boost/asio/detail/win_iocp_serial_port_service.hpp24
-rw-r--r--boost/asio/detail/win_iocp_socket_accept_op.hpp41
-rw-r--r--boost/asio/detail/win_iocp_socket_connect_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_socket_recv_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_socket_recvfrom_op.hpp16
-rw-r--r--boost/asio/detail/win_iocp_socket_recvmsg_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_socket_send_op.hpp15
-rw-r--r--boost/asio/detail/win_iocp_socket_service.hpp132
-rw-r--r--boost/asio/detail/win_iocp_socket_service_base.hpp101
-rw-r--r--boost/asio/detail/win_iocp_thread_info.hpp2
-rw-r--r--boost/asio/detail/win_iocp_wait_op.hpp14
-rw-r--r--boost/asio/detail/win_mutex.hpp2
-rw-r--r--boost/asio/detail/win_object_handle_service.hpp35
-rw-r--r--boost/asio/detail/win_static_mutex.hpp2
-rw-r--r--boost/asio/detail/win_thread.hpp2
-rw-r--r--boost/asio/detail/win_tss_ptr.hpp2
-rw-r--r--boost/asio/detail/winapp_thread.hpp2
-rw-r--r--boost/asio/detail/wince_thread.hpp2
-rw-r--r--boost/asio/detail/winrt_async_manager.hpp39
-rw-r--r--boost/asio/detail/winrt_async_op.hpp2
-rw-r--r--boost/asio/detail/winrt_resolve_op.hpp15
-rw-r--r--boost/asio/detail/winrt_resolver_service.hpp54
-rw-r--r--boost/asio/detail/winrt_socket_connect_op.hpp14
-rw-r--r--boost/asio/detail/winrt_socket_recv_op.hpp15
-rw-r--r--boost/asio/detail/winrt_socket_send_op.hpp15
-rw-r--r--boost/asio/detail/winrt_ssocket_service.hpp23
-rw-r--r--boost/asio/detail/winrt_ssocket_service_base.hpp59
-rw-r--r--boost/asio/detail/winrt_timer_scheduler.hpp26
-rw-r--r--boost/asio/detail/winrt_utils.hpp2
-rw-r--r--boost/asio/detail/winsock_init.hpp2
-rw-r--r--boost/asio/detail/work_dispatcher.hpp7
-rw-r--r--boost/asio/detail/wrapped_handler.hpp2
-rw-r--r--boost/asio/dispatch.hpp10
-rw-r--r--boost/asio/error.hpp2
-rw-r--r--boost/asio/execution_context.hpp5
-rw-r--r--boost/asio/executor.hpp2
-rw-r--r--boost/asio/executor_work_guard.hpp4
-rw-r--r--boost/asio/experimental.hpp22
-rw-r--r--boost/asio/experimental/co_spawn.hpp228
-rw-r--r--boost/asio/experimental/impl/co_spawn.hpp878
-rw-r--r--boost/asio/experimental/impl/detached.hpp93
-rw-r--r--boost/asio/generic/basic_endpoint.hpp2
-rw-r--r--boost/asio/generic/datagram_protocol.hpp2
-rw-r--r--boost/asio/generic/detail/endpoint.hpp2
-rw-r--r--boost/asio/generic/detail/impl/endpoint.ipp2
-rw-r--r--boost/asio/generic/raw_protocol.hpp2
-rw-r--r--boost/asio/generic/seq_packet_protocol.hpp2
-rw-r--r--boost/asio/generic/stream_protocol.hpp2
-rw-r--r--boost/asio/handler_alloc_hook.hpp2
-rw-r--r--boost/asio/handler_continuation_hook.hpp2
-rw-r--r--boost/asio/handler_invoke_hook.hpp2
-rw-r--r--boost/asio/handler_type.hpp52
-rw-r--r--boost/asio/high_resolution_timer.hpp2
-rw-r--r--boost/asio/impl/awaitable.hpp424
-rw-r--r--boost/asio/impl/buffered_read_stream.hpp107
-rw-r--r--boost/asio/impl/buffered_write_stream.hpp99
-rw-r--r--boost/asio/impl/co_spawn.hpp140
-rw-r--r--boost/asio/impl/compose.hpp421
-rw-r--r--boost/asio/impl/connect.hpp410
-rw-r--r--boost/asio/impl/defer.hpp58
-rw-r--r--boost/asio/impl/detached.hpp132
-rw-r--r--boost/asio/impl/dispatch.hpp59
-rw-r--r--boost/asio/impl/error.ipp2
-rw-r--r--boost/asio/impl/execution_context.hpp14
-rw-r--r--boost/asio/impl/execution_context.ipp2
-rw-r--r--boost/asio/impl/executor.hpp31
-rw-r--r--boost/asio/impl/executor.ipp2
-rw-r--r--boost/asio/impl/handler_alloc_hook.ipp2
-rw-r--r--boost/asio/impl/io_context.hpp130
-rw-r--r--boost/asio/impl/io_context.ipp7
-rw-r--r--boost/asio/impl/post.hpp58
-rw-r--r--boost/asio/impl/read.hpp570
-rw-r--r--boost/asio/impl/read_at.hpp147
-rw-r--r--boost/asio/impl/read_until.hpp2070
-rw-r--r--boost/asio/impl/redirect_error.hpp (renamed from boost/asio/experimental/impl/redirect_error.hpp)174
-rw-r--r--boost/asio/impl/serial_port_base.hpp2
-rw-r--r--boost/asio/impl/serial_port_base.ipp2
-rw-r--r--boost/asio/impl/spawn.hpp47
-rw-r--r--boost/asio/impl/src.cpp2
-rw-r--r--boost/asio/impl/src.hpp2
-rw-r--r--boost/asio/impl/system_context.hpp2
-rw-r--r--boost/asio/impl/system_context.ipp11
-rw-r--r--boost/asio/impl/system_executor.hpp2
-rw-r--r--boost/asio/impl/thread_pool.hpp2
-rw-r--r--boost/asio/impl/thread_pool.ipp21
-rw-r--r--boost/asio/impl/use_awaitable.hpp278
-rw-r--r--boost/asio/impl/use_future.hpp52
-rw-r--r--boost/asio/impl/write.hpp520
-rw-r--r--boost/asio/impl/write_at.hpp146
-rw-r--r--boost/asio/io_context.hpp16
-rw-r--r--boost/asio/io_context_strand.hpp92
-rw-r--r--boost/asio/io_service.hpp2
-rw-r--r--boost/asio/io_service_strand.hpp2
-rw-r--r--boost/asio/ip/address.hpp62
-rw-r--r--boost/asio/ip/address_v4.hpp58
-rw-r--r--boost/asio/ip/address_v4_iterator.hpp2
-rw-r--r--boost/asio/ip/address_v4_range.hpp2
-rw-r--r--boost/asio/ip/address_v6.hpp77
-rw-r--r--boost/asio/ip/address_v6_iterator.hpp2
-rw-r--r--boost/asio/ip/address_v6_range.hpp2
-rw-r--r--boost/asio/ip/bad_address_cast.hpp2
-rw-r--r--boost/asio/ip/basic_endpoint.hpp47
-rw-r--r--boost/asio/ip/basic_resolver.hpp306
-rw-r--r--boost/asio/ip/basic_resolver_entry.hpp2
-rw-r--r--boost/asio/ip/basic_resolver_iterator.hpp2
-rw-r--r--boost/asio/ip/basic_resolver_query.hpp2
-rw-r--r--boost/asio/ip/basic_resolver_results.hpp2
-rw-r--r--boost/asio/ip/detail/endpoint.hpp40
-rw-r--r--boost/asio/ip/detail/impl/endpoint.ipp20
-rw-r--r--boost/asio/ip/detail/socket_option.hpp2
-rw-r--r--boost/asio/ip/host_name.hpp2
-rw-r--r--boost/asio/ip/icmp.hpp2
-rw-r--r--boost/asio/ip/impl/address.hpp2
-rw-r--r--boost/asio/ip/impl/address.ipp41
-rw-r--r--boost/asio/ip/impl/address_v4.hpp2
-rw-r--r--boost/asio/ip/impl/address_v4.ipp22
-rw-r--r--boost/asio/ip/impl/address_v6.hpp2
-rw-r--r--boost/asio/ip/impl/address_v6.ipp52
-rw-r--r--boost/asio/ip/impl/basic_endpoint.hpp2
-rw-r--r--boost/asio/ip/impl/host_name.ipp2
-rw-r--r--boost/asio/ip/impl/network_v4.hpp2
-rw-r--r--boost/asio/ip/impl/network_v4.ipp2
-rw-r--r--boost/asio/ip/impl/network_v6.hpp2
-rw-r--r--boost/asio/ip/impl/network_v6.ipp2
-rw-r--r--boost/asio/ip/multicast.hpp16
-rw-r--r--boost/asio/ip/network_v4.hpp2
-rw-r--r--boost/asio/ip/network_v6.hpp2
-rw-r--r--boost/asio/ip/resolver_base.hpp2
-rw-r--r--boost/asio/ip/resolver_query_base.hpp2
-rw-r--r--boost/asio/ip/resolver_service.hpp202
-rw-r--r--boost/asio/ip/tcp.hpp6
-rw-r--r--boost/asio/ip/udp.hpp2
-rw-r--r--boost/asio/ip/unicast.hpp6
-rw-r--r--boost/asio/ip/v6_only.hpp6
-rw-r--r--boost/asio/is_executor.hpp2
-rw-r--r--boost/asio/is_read_buffered.hpp2
-rw-r--r--boost/asio/is_write_buffered.hpp2
-rw-r--r--boost/asio/local/basic_endpoint.hpp10
-rw-r--r--boost/asio/local/connect_pair.hpp33
-rw-r--r--boost/asio/local/datagram_protocol.hpp2
-rw-r--r--boost/asio/local/detail/endpoint.hpp8
-rw-r--r--boost/asio/local/detail/impl/endpoint.ipp9
-rw-r--r--boost/asio/local/stream_protocol.hpp2
-rw-r--r--boost/asio/packaged_task.hpp2
-rw-r--r--boost/asio/placeholders.hpp2
-rw-r--r--boost/asio/posix/basic_descriptor.hpp228
-rw-r--r--boost/asio/posix/basic_stream_descriptor.hpp192
-rw-r--r--boost/asio/posix/descriptor.hpp617
-rw-r--r--boost/asio/posix/descriptor_base.hpp4
-rw-r--r--boost/asio/posix/stream_descriptor.hpp329
-rw-r--r--boost/asio/posix/stream_descriptor_service.hpp281
-rw-r--r--boost/asio/post.hpp8
-rw-r--r--boost/asio/raw_socket_service.hpp468
-rw-r--r--boost/asio/read.hpp370
-rw-r--r--boost/asio/read_at.hpp26
-rw-r--r--boost/asio/read_until.hpp1095
-rw-r--r--boost/asio/redirect_error.hpp (renamed from boost/asio/experimental/redirect_error.hpp)19
-rw-r--r--boost/asio/seq_packet_socket_service.hpp418
-rw-r--r--boost/asio/serial_port.hpp739
-rw-r--r--boost/asio/serial_port_base.hpp2
-rw-r--r--boost/asio/serial_port_service.hpp251
-rw-r--r--boost/asio/signal_set.hpp425
-rw-r--r--boost/asio/signal_set_service.hpp144
-rw-r--r--boost/asio/socket_acceptor_service.hpp374
-rw-r--r--boost/asio/socket_base.hpp52
-rw-r--r--boost/asio/spawn.hpp2
-rw-r--r--boost/asio/ssl.hpp2
-rw-r--r--boost/asio/ssl/context.hpp2
-rw-r--r--boost/asio/ssl/context_base.hpp2
-rw-r--r--boost/asio/ssl/detail/buffered_handshake_op.hpp2
-rw-r--r--boost/asio/ssl/detail/engine.hpp2
-rw-r--r--boost/asio/ssl/detail/handshake_op.hpp2
-rw-r--r--boost/asio/ssl/detail/impl/engine.ipp28
-rw-r--r--boost/asio/ssl/detail/impl/openssl_init.ipp2
-rw-r--r--boost/asio/ssl/detail/io.hpp17
-rw-r--r--boost/asio/ssl/detail/openssl_init.hpp2
-rw-r--r--boost/asio/ssl/detail/openssl_types.hpp2
-rw-r--r--boost/asio/ssl/detail/password_callback.hpp2
-rw-r--r--boost/asio/ssl/detail/read_op.hpp2
-rw-r--r--boost/asio/ssl/detail/shutdown_op.hpp14
-rw-r--r--boost/asio/ssl/detail/stream_core.hpp9
-rw-r--r--boost/asio/ssl/detail/verify_callback.hpp2
-rw-r--r--boost/asio/ssl/detail/write_op.hpp2
-rw-r--r--boost/asio/ssl/error.hpp26
-rw-r--r--boost/asio/ssl/impl/context.hpp2
-rw-r--r--boost/asio/ssl/impl/context.ipp2
-rw-r--r--boost/asio/ssl/impl/error.ipp4
-rw-r--r--boost/asio/ssl/impl/rfc2818_verification.ipp2
-rw-r--r--boost/asio/ssl/impl/src.hpp2
-rw-r--r--boost/asio/ssl/rfc2818_verification.hpp2
-rw-r--r--boost/asio/ssl/stream.hpp188
-rw-r--r--boost/asio/ssl/stream_base.hpp2
-rw-r--r--boost/asio/ssl/verify_context.hpp2
-rw-r--r--boost/asio/ssl/verify_mode.hpp2
-rw-r--r--boost/asio/steady_timer.hpp2
-rw-r--r--boost/asio/strand.hpp29
-rw-r--r--boost/asio/stream_socket_service.hpp414
-rw-r--r--boost/asio/streambuf.hpp2
-rw-r--r--boost/asio/system_context.hpp5
-rw-r--r--boost/asio/system_executor.hpp2
-rw-r--r--boost/asio/system_timer.hpp2
-rw-r--r--boost/asio/this_coro.hpp47
-rw-r--r--boost/asio/thread_pool.hpp5
-rw-r--r--boost/asio/time_traits.hpp2
-rw-r--r--boost/asio/ts/buffer.hpp2
-rw-r--r--boost/asio/ts/executor.hpp3
-rw-r--r--boost/asio/ts/internet.hpp2
-rw-r--r--boost/asio/ts/io_context.hpp2
-rw-r--r--boost/asio/ts/net.hpp2
-rw-r--r--boost/asio/ts/netfwd.hpp74
-rw-r--r--boost/asio/ts/socket.hpp2
-rw-r--r--boost/asio/ts/timer.hpp2
-rw-r--r--boost/asio/unyield.hpp2
-rw-r--r--boost/asio/use_awaitable.hpp73
-rw-r--r--boost/asio/use_future.hpp2
-rw-r--r--boost/asio/uses_executor.hpp2
-rw-r--r--boost/asio/version.hpp4
-rw-r--r--boost/asio/wait_traits.hpp2
-rw-r--r--boost/asio/waitable_timer_service.hpp212
-rw-r--r--boost/asio/windows/basic_handle.hpp275
-rw-r--r--boost/asio/windows/basic_object_handle.hpp292
-rw-r--r--boost/asio/windows/basic_overlapped_handle.hpp355
-rw-r--r--boost/asio/windows/basic_random_access_handle.hpp167
-rw-r--r--boost/asio/windows/basic_stream_handle.hpp170
-rw-r--r--boost/asio/windows/object_handle.hpp349
-rw-r--r--boost/asio/windows/object_handle_service.hpp185
-rw-r--r--boost/asio/windows/overlapped_handle.hpp300
-rw-r--r--boost/asio/windows/overlapped_ptr.hpp45
-rw-r--r--boost/asio/windows/random_access_handle.hpp347
-rw-r--r--boost/asio/windows/random_access_handle_service.hpp216
-rw-r--r--boost/asio/windows/stream_handle.hpp331
-rw-r--r--boost/asio/windows/stream_handle_service.hpp212
-rw-r--r--boost/asio/write.hpp363
-rw-r--r--boost/asio/write_at.hpp26
-rw-r--r--boost/asio/yield.hpp2
491 files changed, 14959 insertions, 14811 deletions
diff --git a/boost/asio/associated_allocator.hpp b/boost/asio/associated_allocator.hpp
index bcf1eca3ae..c70852b534 100644
--- a/boost/asio/associated_allocator.hpp
+++ b/boost/asio/associated_allocator.hpp
@@ -2,7 +2,7 @@
// associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/associated_executor.hpp b/boost/asio/associated_executor.hpp
index c31800f394..a44190b5fd 100644
--- a/boost/asio/associated_executor.hpp
+++ b/boost/asio/associated_executor.hpp
@@ -2,7 +2,7 @@
// associated_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/async_result.hpp b/boost/asio/async_result.hpp
index a2aafce134..4f3bb1ec09 100644
--- a/boost/asio/async_result.hpp
+++ b/boost/asio/async_result.hpp
@@ -2,7 +2,7 @@
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,7 +17,7 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/handler_type.hpp>
+#include <boost/asio/detail/variadic_templates.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -42,30 +42,15 @@ namespace asio {
* The primary template assumes that the CompletionToken is the completion
* handler.
*/
-#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature>
-#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
-template <typename CompletionToken, typename Signature = void>
-#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
class async_result
{
public:
-#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type;
/// The return type of the initiating function.
typedef void return_type;
-#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- // For backward compatibility, determine the concrete completion handler type
- // by using the legacy handler_type trait.
- typedef typename handler_type<CompletionToken, Signature>::type
- completion_handler_type;
-
- // For backward compatibility, determine the initiating function return type
- // using the legacy single-parameter version of async_result.
- typedef typename async_result<completion_handler_type>::type return_type;
-#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// Construct an async result from a given handler.
/**
@@ -74,11 +59,6 @@ public:
* then returned from the initiating function.
*/
explicit async_result(completion_handler_type& h)
-#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- // No data members to initialise.
-#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- : legacy_result_(h)
-#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
(void)h;
}
@@ -86,55 +66,59 @@ public:
/// Obtain the value to be returned from the initiating function.
return_type get()
{
-#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- // Nothing to do.
-#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- return legacy_result_.get();
-#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
}
-private:
- async_result(const async_result&) BOOST_ASIO_DELETED;
- async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
-
-#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- // No data members.
-#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- async_result<completion_handler_type> legacy_result_;
-#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
-};
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-
-/// (Deprecated: Use two-parameter version of async_result.) An interface for
-/// customising the behaviour of an initiating function.
-/**
- * This template may be specialised for user-defined handler types.
- */
-template <typename Handler>
-class async_result<Handler>
-{
-public:
- /// The return type of the initiating function.
- typedef void type;
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
+ || defined(GENERATING_DOCUMENTATION)
- /// Construct an async result from a given handler.
- /**
- * When using a specalised async_result, the constructor has an opportunity
- * to initialise some state associated with the handler, which is then
- * returned from the initiating function.
- */
- explicit async_result(Handler&)
+ /// Initiate the asynchronous operation that will produce the result, and
+ /// obtain the value to be returned from the initiating function.
+ template <typename Initiation, typename RawCompletionToken, typename... Args>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(Args)... args)
{
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token),
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
}
- /// Obtain the value to be returned from the initiating function.
- type get()
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // || defined(GENERATING_DOCUMENTATION)
+
+ template <typename Initiation, typename RawCompletionToken>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
{
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token));
}
-};
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
+ template <typename Initiation, typename RawCompletionToken, \
+ BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ static return_type initiate( \
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
+ BOOST_ASIO_MOVE_CAST(RawCompletionToken)(token), \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
+#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // || defined(GENERATING_DOCUMENTATION)
+
+private:
+ async_result(const async_result&) BOOST_ASIO_DELETED;
+ async_result& operator=(const async_result&) BOOST_ASIO_DELETED;
+};
/// Helper template to deduce the handler type from a CompletionToken, capture
/// a local copy of the handler, and then create an async_result for the
@@ -195,11 +179,40 @@ struct async_result_helper
{
};
-} // namespace detail
-} // namespace asio
-} // namespace boost
+struct async_result_memfns_base
+{
+ void initiate();
+};
-#include <boost/asio/detail/pop_options.hpp>
+template <typename T>
+struct async_result_memfns_derived
+ : T, async_result_memfns_base
+{
+};
+
+template <typename T, T>
+struct async_result_memfns_check
+{
+};
+
+template <typename>
+char (&async_result_initiate_memfn_helper(...))[2];
+
+template <typename T>
+char async_result_initiate_memfn_helper(
+ async_result_memfns_check<
+ void (async_result_memfns_base::*)(),
+ &async_result_memfns_derived<T>::initiate>*);
+
+template <typename CompletionToken, typename Signature>
+struct async_result_has_initiate_memfn
+ : integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
+ async_result<typename decay<CompletionToken>::type, Signature>
+ >(0)) != 1>
+{
+};
+
+} // namespace detail
#if defined(GENERATING_DOCUMENTATION)
# define BOOST_ASIO_INITFN_RESULT_TYPE(ct, sig) \
@@ -220,4 +233,126 @@ struct async_result_helper
typename ::boost::asio::decay<ct>::type, sig>::completion_handler_type
#endif
+#if defined(GENERATING_DOCUMENTATION)
+
+template <typename CompletionToken, typename Signature,
+ typename Initiation, typename... Args>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
+async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken),
+ BOOST_ASIO_MOVE_ARG(Args)... args);
+
+#elif defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken, typename Signature,
+ typename Initiation, typename... Args>
+inline typename enable_if<
+ detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(Args)... args)
+{
+ return async_result<typename decay<CompletionToken>::type,
+ Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
+ BOOST_ASIO_MOVE_CAST(CompletionToken)(token),
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
+}
+
+template <typename CompletionToken, typename Signature,
+ typename Initiation, typename... Args>
+inline typename enable_if<
+ !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(Args)... args)
+{
+ async_completion<CompletionToken, Signature> completion(token);
+
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
+ Signature))(completion.completion_handler),
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
+
+ return completion.result.get();
+}
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken, typename Signature, typename Initiation>
+inline typename enable_if<
+ detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
+{
+ return async_result<typename decay<CompletionToken>::type,
+ Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation),
+ BOOST_ASIO_MOVE_CAST(CompletionToken)(token));
+}
+
+template <typename CompletionToken, typename Signature, typename Initiation>
+inline typename enable_if<
+ !detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
+async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
+{
+ async_completion<CompletionToken, Signature> completion(token);
+
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken,
+ Signature))(completion.completion_handler));
+
+ return completion.result.get();
+}
+
+#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
+ template <typename CompletionToken, typename Signature, \
+ typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ inline typename enable_if< \
+ detail::async_result_has_initiate_memfn< \
+ CompletionToken, Signature>::value, \
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
+ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ return async_result<typename decay<CompletionToken>::type, \
+ Signature>::initiate(BOOST_ASIO_MOVE_CAST(Initiation)(initiation), \
+ BOOST_ASIO_MOVE_CAST(CompletionToken)(token), \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ \
+ template <typename CompletionToken, typename Signature, \
+ typename Initiation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ inline typename enable_if< \
+ !detail::async_result_has_initiate_memfn< \
+ CompletionToken, Signature>::value, \
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \
+ async_initiate(BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ async_completion<CompletionToken, Signature> completion(token); \
+ \
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
+ BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(CompletionToken, \
+ Signature))(completion.completion_handler), \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ \
+ return completion.result.get(); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
+#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
#endif // BOOST_ASIO_ASYNC_RESULT_HPP
diff --git a/boost/asio/awaitable.hpp b/boost/asio/awaitable.hpp
new file mode 100644
index 0000000000..83f8647cb1
--- /dev/null
+++ b/boost/asio/awaitable.hpp
@@ -0,0 +1,125 @@
+//
+// awaitable.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_AWAITABLE_HPP
+#define BOOST_ASIO_AWAITABLE_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#include <experimental/coroutine>
+#include <boost/asio/executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+using std::experimental::coroutine_handle;
+using std::experimental::suspend_always;
+
+template <typename> class awaitable_thread;
+template <typename, typename> class awaitable_frame;
+
+} // namespace detail
+
+/// The return type of a coroutine or asynchronous operation.
+template <typename T, typename Executor = executor>
+class awaitable
+{
+public:
+ /// The type of the awaited value.
+ typedef T value_type;
+
+ /// The executor type that will be used for the coroutine.
+ typedef Executor executor_type;
+
+ /// Default constructor.
+ constexpr awaitable() noexcept
+ : frame_(nullptr)
+ {
+ }
+
+ /// Move constructor.
+ awaitable(awaitable&& other) noexcept
+ : frame_(std::exchange(other.frame_, nullptr))
+ {
+ }
+
+ /// Destructor
+ ~awaitable()
+ {
+ if (frame_)
+ frame_->destroy();
+ }
+
+ /// Checks if the awaitable refers to a future result.
+ bool valid() const noexcept
+ {
+ return !!frame_;
+ }
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+ // Support for co_await keyword.
+ bool await_ready() const noexcept
+ {
+ return false;
+ }
+
+ // Support for co_await keyword.
+ template <class U>
+ void await_suspend(
+ detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
+ {
+ frame_->push_frame(&h.promise());
+ }
+
+ // Support for co_await keyword.
+ T await_resume()
+ {
+ return frame_->get();
+ }
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+private:
+ template <typename> friend class detail::awaitable_thread;
+ template <typename, typename> friend class detail::awaitable_frame;
+
+ // Not copy constructible or copy assignable.
+ awaitable(const awaitable&) = delete;
+ awaitable& operator=(const awaitable&) = delete;
+
+ // Construct the awaitable from a coroutine's frame object.
+ explicit awaitable(detail::awaitable_frame<T, Executor>* a)
+ : frame_(a)
+ {
+ }
+
+ detail::awaitable_frame<T, Executor>* frame_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/awaitable.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_AWAITABLE_HPP
diff --git a/boost/asio/basic_datagram_socket.hpp b/boost/asio/basic_datagram_socket.hpp
index b512b75dde..b058f78c4c 100644
--- a/boost/asio/basic_datagram_socket.hpp
+++ b/boost/asio/basic_datagram_socket.hpp
@@ -2,7 +2,7 @@
// basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -19,19 +19,25 @@
#include <cstddef>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/datagram_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_datagram_socket;
+
+#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+
/// Provides datagram-oriented socket functionality.
/**
* The basic_datagram_socket class template provides asynchronous and blocking
@@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
+template <typename Protocol, typename Executor>
class basic_datagram_socket
- : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ : public basic_socket<Protocol, Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_datagram_socket<Protocol, Executor1> other;
+ };
+
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
- typedef typename basic_socket<
- Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+ typedef typename basic_socket<Protocol,
+ Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -66,12 +82,29 @@ public:
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
- * @param io_context The io_context object that the datagram socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_datagram_socket(const executor_type& ex)
+ : basic_socket<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_datagram_socket without opening it.
+ /**
+ * This constructor creates a datagram socket without opening it. The open()
+ * function must be called before data can be sent or received on the socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
*/
- explicit basic_datagram_socket(boost::asio::io_context& io_context)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_datagram_socket(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context)
{
}
@@ -79,17 +112,37 @@ public:
/**
* This constructor creates and opens a datagram socket.
*
- * @param io_context The io_context object that the datagram socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
+ : basic_socket<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_datagram_socket.
+ /**
+ * This constructor creates and opens a datagram socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_context& io_context,
- const protocol_type& protocol)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+ template <typename ExecutionContext>
+ basic_datagram_socket(ExecutionContext& context,
+ const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -100,18 +153,42 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_context The io_context object that the datagram socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the datagram
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
+ : basic_socket<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_datagram_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a datagram socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_context& io_context,
- const endpoint_type& endpoint)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+ template <typename ExecutionContext>
+ basic_datagram_socket(ExecutionContext& context,
+ const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -120,9 +197,8 @@ public:
* This constructor creates a datagram socket object to hold an existing
* native socket.
*
- * @param io_context The io_context object that the datagram socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -130,10 +206,34 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_datagram_socket(boost::asio::io_context& io_context,
+ basic_datagram_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
- io_context, protocol, native_socket)
+ : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_datagram_socket on an existing native socket.
+ /**
+ * This constructor creates a datagram socket object to hold an existing
+ * native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_datagram_socket(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -146,10 +246,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_context&) constructor.
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
*/
basic_datagram_socket(basic_datagram_socket&& other)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -162,11 +263,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_context&) constructor.
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
*/
basic_datagram_socket& operator=(basic_datagram_socket&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -179,13 +281,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_context&) constructor.
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_datagram_socket(
- basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ template <typename Protocol1, typename Executor1>
+ basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -199,14 +304,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_datagram_socket(io_context&) constructor.
+ * constructed using the @c basic_datagram_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_datagram_socket>::type& operator=(
- basic_datagram_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_datagram_socket&
+ >::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -246,8 +354,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -274,8 +382,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -301,8 +409,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send on a connected socket.
@@ -323,9 +431,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@@ -346,22 +454,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@@ -384,9 +480,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected datagram
@@ -399,22 +495,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
}
/// Send a datagram to the specified endpoint.
@@ -447,8 +530,8 @@ public:
const endpoint_type& destination)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send_to(
- this->get_implementation(), buffers, destination, 0, ec);
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@@ -474,8 +557,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send_to(
- this->get_implementation(), buffers, destination, flags, ec);
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@@ -501,7 +584,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
boost::system::error_code& ec)
{
- return this->get_service().send_to(this->get_implementation(),
+ return this->impl_.get_service().send_to(this->impl_.get_implementation(),
buffers, destination, flags, ec);
}
@@ -526,9 +609,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -549,24 +632,10 @@ public:
const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, 0,
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, 0,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers,
+ destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -592,9 +661,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -603,24 +672,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, flags,
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, flags,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@@ -651,8 +705,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -680,8 +734,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -708,8 +762,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive on a connected socket.
@@ -730,9 +784,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -754,22 +808,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@@ -792,9 +834,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -807,22 +849,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive a datagram with the endpoint of the sender.
@@ -856,8 +885,8 @@ public:
endpoint_type& sender_endpoint)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0, ec);
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@@ -883,8 +912,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags, ec);
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@@ -910,8 +939,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec)
{
- return this->get_service().receive_from(this->get_implementation(),
- buffers, sender_endpoint, flags, ec);
+ return this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
}
/// Start an asynchronous receive.
@@ -937,9 +966,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -957,24 +986,10 @@ public:
endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_from(), handler, this, buffers,
+ &sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -1002,9 +1017,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -1013,25 +1028,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_from(), handler,
+ this, buffers, &sender_endpoint, flags);
+ }
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_datagram_socket* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
- this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags,
- init.completion_handler);
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- }
+ struct initiate_async_send_to
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_datagram_socket* self, const ConstBufferSequence& buffers,
+ const endpoint_type& destination,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send_to(
+ self->impl_.get_implementation(), buffers, destination, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_datagram_socket* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive_from
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_datagram_socket* self, const MutableBufferSequence& buffers,
+ endpoint_type* sender_endpoint, socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive_from(
+ self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace asio
diff --git a/boost/asio/basic_deadline_timer.hpp b/boost/asio/basic_deadline_timer.hpp
index 56a265bfbc..75f0fcd8bc 100644
--- a/boost/asio/basic_deadline_timer.hpp
+++ b/boost/asio/basic_deadline_timer.hpp
@@ -2,7 +2,7 @@
// basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,19 +21,16 @@
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
-#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/time_traits.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/deadline_timer_service.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/detail/deadline_timer_service.hpp>
-# define BOOST_ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -58,7 +55,7 @@ namespace asio {
* Performing a blocking wait:
* @code
* // Construct a timer without setting an expiry time.
- * boost::asio::deadline_timer timer(io_context);
+ * boost::asio::deadline_timer timer(my_context);
*
* // Set an expiry time relative to now.
* timer.expires_from_now(boost::posix_time::seconds(5));
@@ -81,7 +78,7 @@ namespace asio {
* ...
*
* // Construct a timer with an absolute expiry time.
- * boost::asio::deadline_timer timer(io_context,
+ * boost::asio::deadline_timer timer(my_context,
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
*
* // Start an asynchronous wait.
@@ -128,14 +125,13 @@ namespace asio {
* it contains the value boost::asio::error::operation_aborted.
*/
template <typename Time,
- typename TimeTraits = boost::asio::time_traits<Time>
- BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)>
+ typename TimeTraits = boost::asio::time_traits<Time>,
+ typename Executor = executor>
class basic_deadline_timer
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
+ typedef Executor executor_type;
/// The time traits type.
typedef TimeTraits traits_type;
@@ -152,11 +148,30 @@ public:
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param ex The I/O executor that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
+ */
+ explicit basic_deadline_timer(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Constructor.
+ /**
+ * This constructor creates a timer without setting an expiry time. The
+ * expires_at() or expires_from_now() functions must be called to set an
+ * expiry time before the timer can be waited on.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
*/
- explicit basic_deadline_timer(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_deadline_timer(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -164,18 +179,40 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param ex The I/O executor that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
- basic_deadline_timer(boost::asio::io_context& io_context,
- const time_type& expiry_time)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
+ impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_at");
+ }
+
+ /// Constructor to set a particular expiry time as an absolute time.
+ /**
+ * This constructor creates a timer and sets the expiry time.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
+ *
+ * @param expiry_time The expiry time to be used for the timer, expressed
+ * as an absolute time.
+ */
+ template <typename ExecutionContext>
+ basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
@@ -183,19 +220,44 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param ex The I/O executor that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
- basic_deadline_timer(boost::asio::io_context& io_context,
+ basic_deadline_timer(const executor_type& ex,
const duration_type& expiry_time)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().expires_from_now(
- this->get_implementation(), expiry_time, ec);
+ impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_from_now");
+ }
+
+ /// Constructor to set a particular expiry time relative to now.
+ /**
+ * This constructor creates a timer and sets the expiry time.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
+ *
+ * @param expiry_time The expiry time to be used for the timer, relative to
+ * now.
+ */
+ template <typename ExecutionContext>
+ basic_deadline_timer(ExecutionContext& context,
+ const duration_type& expiry_time,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
}
@@ -208,10 +270,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_deadline_timer(io_context&) constructor.
+ * constructed using the @c basic_deadline_timer(const executor_type&)
+ * constructor.
*/
basic_deadline_timer(basic_deadline_timer&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -224,11 +287,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_deadline_timer(io_context&) constructor.
+ * constructed using the @c basic_deadline_timer(const executor_type&)
+ * constructor.
*/
basic_deadline_timer& operator=(basic_deadline_timer&& other)
{
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -242,45 +306,11 @@ public:
{
}
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ return impl_.get_executor();
}
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer.
/**
@@ -307,7 +337,7 @@ public:
std::size_t cancel()
{
boost::system::error_code ec;
- std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
+ std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
return s;
}
@@ -336,7 +366,7 @@ public:
*/
std::size_t cancel(boost::system::error_code& ec)
{
- return this->get_service().cancel(this->get_implementation(), ec);
+ return impl_.get_service().cancel(impl_.get_implementation(), ec);
}
/// Cancels one asynchronous operation that is waiting on the timer.
@@ -366,8 +396,8 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
- std::size_t s = this->get_service().cancel_one(
- this->get_implementation(), ec);
+ std::size_t s = impl_.get_service().cancel_one(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
@@ -398,7 +428,7 @@ public:
*/
std::size_t cancel_one(boost::system::error_code& ec)
{
- return this->get_service().cancel_one(this->get_implementation(), ec);
+ return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
}
/// Get the timer's expiry time as an absolute time.
@@ -408,7 +438,7 @@ public:
*/
time_type expires_at() const
{
- return this->get_service().expires_at(this->get_implementation());
+ return impl_.get_service().expires_at(impl_.get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -436,8 +466,8 @@ public:
std::size_t expires_at(const time_type& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().expires_at(
- this->get_implementation(), expiry_time, ec);
+ std::size_t s = impl_.get_service().expires_at(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
@@ -467,8 +497,8 @@ public:
std::size_t expires_at(const time_type& expiry_time,
boost::system::error_code& ec)
{
- return this->get_service().expires_at(
- this->get_implementation(), expiry_time, ec);
+ return impl_.get_service().expires_at(
+ impl_.get_implementation(), expiry_time, ec);
}
/// Get the timer's expiry time relative to now.
@@ -478,7 +508,7 @@ public:
*/
duration_type expires_from_now() const
{
- return this->get_service().expires_from_now(this->get_implementation());
+ return impl_.get_service().expires_from_now(impl_.get_implementation());
}
/// Set the timer's expiry time relative to now.
@@ -506,8 +536,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().expires_from_now(
- this->get_implementation(), expiry_time, ec);
+ std::size_t s = impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@@ -537,8 +567,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time,
boost::system::error_code& ec)
{
- return this->get_service().expires_from_now(
- this->get_implementation(), expiry_time, ec);
+ return impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
}
/// Perform a blocking wait on the timer.
@@ -551,7 +581,7 @@ public:
void wait()
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -564,7 +594,7 @@ public:
*/
void wait(boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -587,32 +617,44 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_wait(this->get_implementation(),
- BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this);
}
+
+private:
+ // Disallow copying and assignment.
+ basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED;
+ basic_deadline_timer& operator=(
+ const basic_deadline_timer&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_deadline_timer* self) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ detail::io_object_impl<
+ detail::deadline_timer_service<TimeTraits>, Executor> impl_;
};
} // namespace asio
@@ -620,10 +662,6 @@ public:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/basic_io_object.hpp b/boost/asio/basic_io_object.hpp
index c0c2c714eb..a9f44d1f04 100644
--- a/boost/asio/basic_io_object.hpp
+++ b/boost/asio/basic_io_object.hpp
@@ -2,7 +2,7 @@
// basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/basic_raw_socket.hpp b/boost/asio/basic_raw_socket.hpp
index b24d079659..cc45d372b5 100644
--- a/boost/asio/basic_raw_socket.hpp
+++ b/boost/asio/basic_raw_socket.hpp
@@ -2,7 +2,7 @@
// basic_raw_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -19,19 +19,25 @@
#include <cstddef>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/raw_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_raw_socket;
+
+#endif // !defined(BOOST_ASIO_BASIC_RAW_SOCKET_FWD_DECL)
+
/// Provides raw-oriented socket functionality.
/**
* The basic_raw_socket class template provides asynchronous and blocking
@@ -41,18 +47,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
+template <typename Protocol, typename Executor>
class basic_raw_socket
- : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ : public basic_socket<Protocol, Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_raw_socket<Protocol, Executor1> other;
+ };
+
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
- typedef typename basic_socket<
- Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+ typedef typename basic_socket<Protocol,
+ Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -66,12 +82,29 @@ public:
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
- * @param io_context The io_context object that the raw socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*/
- explicit basic_raw_socket(boost::asio::io_context& io_context)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+ explicit basic_raw_socket(const executor_type& ex)
+ : basic_socket<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_raw_socket without opening it.
+ /**
+ * This constructor creates a raw socket without opening it. The open()
+ * function must be called before data can be sent or received on the socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_raw_socket(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context)
{
}
@@ -79,17 +112,36 @@ public:
/**
* This constructor creates and opens a raw socket.
*
- * @param io_context The io_context object that the raw socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_context& io_context,
- const protocol_type& protocol)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+ basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
+ : basic_socket<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_raw_socket.
+ /**
+ * This constructor creates and opens a raw socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -100,18 +152,41 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_context The io_context object that the raw socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the raw
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
+ : basic_socket<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_raw_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a raw socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the raw
* socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_context& io_context,
- const endpoint_type& endpoint)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+ template <typename ExecutionContext>
+ basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -120,9 +195,8 @@ public:
* This constructor creates a raw socket object to hold an existing
* native socket.
*
- * @param io_context The io_context object that the raw socket will use
- * to dispatch handlers for any asynchronous operations performed on the
- * socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -130,10 +204,34 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_raw_socket(boost::asio::io_context& io_context,
+ basic_raw_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
- io_context, protocol, native_socket)
+ : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_raw_socket on an existing native socket.
+ /**
+ * This constructor creates a raw socket object to hold an existing
+ * native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_raw_socket(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -146,10 +244,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_context&) constructor.
+ * constructed using the @c basic_raw_socket(const executor_type&)
+ * constructor.
*/
basic_raw_socket(basic_raw_socket&& other)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -161,28 +260,34 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_context&) constructor.
+ * constructed using the @c basic_raw_socket(const executor_type&)
+ * constructor.
*/
basic_raw_socket& operator=(basic_raw_socket&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
- /// Move-construct a basic_raw_socket from a socket of another protocol type.
+ /// Move-construct a basic_raw_socket from a socket of another protocol
+ /// type.
/**
* This constructor moves a raw socket from one object to another.
*
- * @param other The other basic_raw_socket object from which the move will
- * occur.
+ * @param other The other basic_raw_socket object from which the move
+ * will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_context&) constructor.
+ * constructed using the @c basic_raw_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_raw_socket(basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ template <typename Protocol1, typename Executor1>
+ basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -194,14 +299,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_raw_socket(io_context&) constructor.
+ * constructed using the @c basic_raw_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_raw_socket>::type& operator=(
- basic_raw_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_raw_socket&
+ >::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -240,8 +348,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -267,8 +375,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -293,8 +401,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send on a connected socket.
@@ -315,9 +423,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@@ -338,22 +446,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@@ -376,9 +472,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_send operation can only be used with a connected socket.
* Use the async_send_to function to send data on an unconnected raw
@@ -391,22 +487,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
}
/// Send raw data to the specified endpoint.
@@ -439,8 +522,8 @@ public:
const endpoint_type& destination)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send_to(
- this->get_implementation(), buffers, destination, 0, ec);
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, 0, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@@ -466,8 +549,8 @@ public:
const endpoint_type& destination, socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send_to(
- this->get_implementation(), buffers, destination, flags, ec);
+ std::size_t s = this->impl_.get_service().send_to(
+ this->impl_.get_implementation(), buffers, destination, flags, ec);
boost::asio::detail::throw_error(ec, "send_to");
return s;
}
@@ -493,7 +576,7 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
boost::system::error_code& ec)
{
- return this->get_service().send_to(this->get_implementation(),
+ return this->impl_.get_service().send_to(this->impl_.get_implementation(),
buffers, destination, flags, ec);
}
@@ -518,9 +601,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -541,22 +624,10 @@ public:
const endpoint_type& destination,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send_to(this->get_implementation(),
- buffers, destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send_to(this->get_implementation(),
- buffers, destination, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers,
+ destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -582,9 +653,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -593,24 +664,9 @@ public:
const endpoint_type& destination, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, flags,
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send_to(
- this->get_implementation(), buffers, destination, flags,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@@ -641,8 +697,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -670,8 +726,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -698,8 +754,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive on a connected socket.
@@ -720,9 +776,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -744,22 +800,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@@ -782,9 +826,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The async_receive operation can only be used with a connected socket.
* Use the async_receive_from function to receive data on an unconnected
@@ -797,22 +841,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive raw data with the endpoint of the sender.
@@ -846,8 +877,8 @@ public:
endpoint_type& sender_endpoint)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0, ec);
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@@ -873,8 +904,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags, ec);
+ std::size_t s = this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
boost::asio::detail::throw_error(ec, "receive_from");
return s;
}
@@ -900,8 +931,8 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
boost::system::error_code& ec)
{
- return this->get_service().receive_from(this->get_implementation(),
- buffers, sender_endpoint, flags, ec);
+ return this->impl_.get_service().receive_from(
+ this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec);
}
/// Start an asynchronous receive.
@@ -927,9 +958,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -947,24 +978,10 @@ public:
endpoint_type& sender_endpoint,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, 0,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_from(), handler, this, buffers,
+ &sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -992,9 +1009,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -1003,25 +1020,85 @@ public:
endpoint_type& sender_endpoint, socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_from(), handler,
+ this, buffers, &sender_endpoint, flags);
+ }
+
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_raw_socket* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
- this->get_service().async_receive_from(
- this->get_implementation(), buffers, sender_endpoint, flags,
- init.completion_handler);
+ struct initiate_async_send_to
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_raw_socket* self, const ConstBufferSequence& buffers,
+ const endpoint_type& destination,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- }
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send_to(
+ self->impl_.get_implementation(), buffers, destination, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_raw_socket* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive_from
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_raw_socket* self, const MutableBufferSequence& buffers,
+ endpoint_type* sender_endpoint, socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive_from(
+ self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace asio
diff --git a/boost/asio/basic_seq_packet_socket.hpp b/boost/asio/basic_seq_packet_socket.hpp
index cc98656df3..7c3903ea59 100644
--- a/boost/asio/basic_seq_packet_socket.hpp
+++ b/boost/asio/basic_seq_packet_socket.hpp
@@ -2,7 +2,7 @@
// basic_seq_packet_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -22,15 +22,20 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/seq_packet_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_seq_packet_socket;
+
+#endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
+
/// Provides sequenced packet socket functionality.
/**
* The basic_seq_packet_socket class template provides asynchronous and blocking
@@ -40,18 +45,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
+template <typename Protocol, typename Executor>
class basic_seq_packet_socket
- : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ : public basic_socket<Protocol, Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_seq_packet_socket<Protocol, Executor1> other;
+ };
+
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
- typedef typename basic_socket<
- Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+ typedef typename basic_socket<Protocol,
+ Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -66,12 +81,30 @@ public:
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
- * @param io_context The io_context object that the sequenced packet socket
- * will use to dispatch handlers for any asynchronous operations performed on
- * the socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
+ */
+ explicit basic_seq_packet_socket(const executor_type& ex)
+ : basic_socket<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_seq_packet_socket without opening it.
+ /**
+ * This constructor creates a sequenced packet socket without opening it. The
+ * socket needs to be opened and then connected or accepted before data can
+ * be sent or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
*/
- explicit basic_seq_packet_socket(boost::asio::io_context& io_context)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_seq_packet_socket(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context)
{
}
@@ -81,17 +114,40 @@ public:
* needs to be connected or accepted before data can be sent or received on
* it.
*
- * @param io_context The io_context object that the sequenced packet socket
- * will use to dispatch handlers for any asynchronous operations performed on
- * the socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_context& io_context,
+ basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+ : basic_socket<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_seq_packet_socket.
+ /**
+ * This constructor creates and opens a sequenced_packet socket. The socket
+ * needs to be connected or accepted before data can be sent or received on
+ * it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_seq_packet_socket(ExecutionContext& context,
+ const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -102,18 +158,43 @@ public:
* it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint.
*
- * @param io_context The io_context object that the sequenced packet socket
- * will use to dispatch handlers for any asynchronous operations performed on
- * the socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the sequenced
* packet socket will be bound.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_context& io_context,
+ basic_seq_packet_socket(const executor_type& ex,
const endpoint_type& endpoint)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+ : basic_socket<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_seq_packet_socket, opening it and binding it to the
+ /// given local endpoint.
+ /**
+ * This constructor creates a sequenced packet socket and automatically opens
+ * it bound to the specified endpoint on the local machine. The protocol used
+ * is the protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the sequenced
+ * packet socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_seq_packet_socket(ExecutionContext& context,
+ const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -122,9 +203,8 @@ public:
* This constructor creates a sequenced packet socket object to hold an
* existing native socket.
*
- * @param io_context The io_context object that the sequenced packet socket
- * will use to dispatch handlers for any asynchronous operations performed on
- * the socket.
+ * @param ex The I/O executor that the socket will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -132,10 +212,34 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_seq_packet_socket(boost::asio::io_context& io_context,
+ basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
- io_context, protocol, native_socket)
+ : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_seq_packet_socket on an existing native socket.
+ /**
+ * This constructor creates a sequenced packet socket object to hold an
+ * existing native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_seq_packet_socket(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -149,10 +253,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+ * constructed using the @c basic_seq_packet_socket(const executor_type&)
+ * constructor.
*/
basic_seq_packet_socket(basic_seq_packet_socket&& other)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -165,11 +270,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+ * constructed using the @c basic_seq_packet_socket(const executor_type&)
+ * constructor.
*/
basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -183,13 +289,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+ * constructed using the @c basic_seq_packet_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_seq_packet_socket(
- basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ template <typename Protocol1, typename Executor1>
+ basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -203,14 +312,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
+ * constructed using the @c basic_seq_packet_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_seq_packet_socket>::type& operator=(
- basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_seq_packet_socket&
+ >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -252,8 +364,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -280,8 +392,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send.
@@ -304,9 +416,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -324,22 +436,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@@ -376,13 +475,8 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, 0, out_flags, ec);
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- std::size_t s = this->get_service().receive_with_flags(
- this->get_implementation(), buffers, 0, out_flags, ec);
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ std::size_t s = this->impl_.get_service().receive_with_flags(
+ this->impl_.get_implementation(), buffers, 0, out_flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -428,13 +522,8 @@ public:
socket_base::message_flags& out_flags)
{
boost::system::error_code ec;
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, in_flags, out_flags, ec);
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- std::size_t s = this->get_service().receive_with_flags(
- this->get_implementation(), buffers, in_flags, out_flags, ec);
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ std::size_t s = this->impl_.get_service().receive_with_flags(
+ this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -467,13 +556,8 @@ public:
socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, boost::system::error_code& ec)
{
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().receive(this->get_implementation(),
- buffers, in_flags, out_flags, ec);
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().receive_with_flags(this->get_implementation(),
- buffers, in_flags, out_flags, ec);
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return this->impl_.get_service().receive_with_flags(
+ this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
}
/// Start an asynchronous receive.
@@ -500,9 +584,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -521,24 +605,10 @@ public:
socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(
- this->get_implementation(), buffers, 0, out_flags,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive_with_flags(
- this->get_implementation(), buffers, 0, out_flags,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_with_flags(), handler, this,
+ buffers, socket_base::message_flags(0), &out_flags);
}
/// Start an asynchronous receive.
@@ -567,9 +637,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -591,25 +661,49 @@ public:
socket_base::message_flags& out_flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(
- this->get_implementation(), buffers, in_flags, out_flags,
- BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive_with_flags(
- this->get_implementation(), buffers, in_flags, out_flags,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive_with_flags(), handler,
+ this, buffers, in_flags, &out_flags);
}
+
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_seq_packet_socket* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive_with_flags
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_seq_packet_socket* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags in_flags,
+ socket_base::message_flags* out_flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive_with_flags(
+ self->impl_.get_implementation(), buffers, in_flags, *out_flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace asio
diff --git a/boost/asio/basic_serial_port.hpp b/boost/asio/basic_serial_port.hpp
index 2f6c8cf887..88a195a46a 100644
--- a/boost/asio/basic_serial_port.hpp
+++ b/boost/asio/basic_serial_port.hpp
@@ -2,7 +2,7 @@
// basic_serial_port.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -18,18 +18,29 @@
#include <boost/asio/detail/config.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION)
#include <string>
-#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/serial_port_base.hpp>
-#include <boost/asio/serial_port_service.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
+#else
+# include <boost/asio/detail/reactive_serial_port_service.hpp>
+#endif
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
#include <boost/asio/detail/push_options.hpp>
@@ -38,34 +49,63 @@ namespace asio {
/// Provides serial port functionality.
/**
- * The basic_serial_port class template provides functionality that is common
- * to all serial ports.
+ * The basic_serial_port class provides a wrapper over serial port
+ * functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename SerialPortService = serial_port_service>
+template <typename Executor = executor>
class basic_serial_port
- : public basic_io_object<SerialPortService>,
- public serial_port_base
+ : public serial_port_base
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a serial port.
- typedef typename SerialPortService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef detail::win_iocp_serial_port_service::native_handle_type
+ native_handle_type;
+#else
+ typedef detail::reactive_serial_port_service::native_handle_type
+ native_handle_type;
+#endif
+
+ /// A basic_basic_serial_port is always the lowest layer.
+ typedef basic_serial_port lowest_layer_type;
- /// A basic_serial_port is always the lowest layer.
- typedef basic_serial_port<SerialPortService> lowest_layer_type;
+ /// Construct a basic_serial_port without opening it.
+ /**
+ * This constructor creates a serial port without opening it.
+ *
+ * @param ex The I/O executor that the serial port will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * serial port.
+ */
+ explicit basic_serial_port(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
/// Construct a basic_serial_port without opening it.
/**
* This constructor creates a serial port without opening it.
*
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
+ * @param context An execution context which provides the I/O executor that
+ * the serial port will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the serial port.
*/
- explicit basic_serial_port(boost::asio::io_context& io_context)
- : basic_io_object<SerialPortService>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_serial_port(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value,
+ basic_serial_port
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -74,18 +114,18 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
+ * @param ex The I/O executor that the serial port will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
- explicit basic_serial_port(boost::asio::io_context& io_context,
- const char* device)
- : basic_io_object<SerialPortService>(io_context)
+ basic_serial_port(const executor_type& ex, const char* device)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -94,18 +134,66 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
+ * @param context An execution context which provides the I/O executor that
+ * the serial port will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
- explicit basic_serial_port(boost::asio::io_context& io_context,
- const std::string& device)
- : basic_io_object<SerialPortService>(io_context)
+ template <typename ExecutionContext>
+ basic_serial_port(ExecutionContext& context, const char* device,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct and open a basic_serial_port.
+ /**
+ * This constructor creates and opens a serial port for the specified device
+ * name.
+ *
+ * @param ex The I/O executor that the serial port will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * serial port.
+ *
+ * @param device The platform-specific device name for this serial
+ * port.
+ */
+ basic_serial_port(const executor_type& ex, const std::string& device)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct and open a basic_serial_port.
+ /**
+ * This constructor creates and opens a serial port for the specified device
+ * name.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the serial port will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the serial port.
+ *
+ * @param device The platform-specific device name for this serial
+ * port.
+ */
+ template <typename ExecutionContext>
+ basic_serial_port(ExecutionContext& context, const std::string& device,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -114,19 +202,47 @@ public:
* This constructor creates a serial port object to hold an existing native
* serial port.
*
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
+ * @param ex The I/O executor that the serial port will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * serial port.
*
* @param native_serial_port A native serial port.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_serial_port(boost::asio::io_context& io_context,
+ basic_serial_port(const executor_type& ex,
const native_handle_type& native_serial_port)
- : basic_io_object<SerialPortService>(io_context)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ native_serial_port, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_serial_port on an existing native serial port.
+ /**
+ * This constructor creates a serial port object to hold an existing native
+ * serial port.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the serial port will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the serial port.
+ *
+ * @param native_serial_port A native serial port.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_serial_port(ExecutionContext& context,
+ const native_handle_type& native_serial_port,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -140,11 +256,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_serial_port(io_context&) constructor.
+ * constructed using the @c basic_serial_port(const executor_type&)
+ * constructor.
*/
basic_serial_port(basic_serial_port&& other)
- : basic_io_object<SerialPortService>(
- BOOST_ASIO_MOVE_CAST(basic_serial_port)(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -156,16 +272,32 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_serial_port(io_context&) constructor.
+ * constructed using the @c basic_serial_port(const executor_type&)
+ * constructor.
*/
basic_serial_port& operator=(basic_serial_port&& other)
{
- basic_io_object<SerialPortService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_serial_port)(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Destroys the serial port.
+ /**
+ * This function destroys the serial port, cancelling any outstanding
+ * asynchronous wait operations associated with the serial port as if by
+ * calling @c cancel.
+ */
+ ~basic_serial_port()
+ {
+ }
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
@@ -205,7 +337,7 @@ public:
void open(const std::string& device)
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -221,7 +353,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
boost::system::error_code& ec)
{
- this->get_service().open(this->get_implementation(), device, ec);
+ impl_.get_service().open(impl_.get_implementation(), device, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -236,7 +368,7 @@ public:
void assign(const native_handle_type& native_serial_port)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -252,7 +384,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
boost::system::error_code& ec)
{
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -260,7 +392,7 @@ public:
/// Determine whether the serial port is open.
bool is_open() const
{
- return this->get_service().is_open(this->get_implementation());
+ return impl_.get_service().is_open(impl_.get_implementation());
}
/// Close the serial port.
@@ -274,7 +406,7 @@ public:
void close()
{
boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "close");
}
@@ -288,7 +420,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -300,7 +432,7 @@ public:
*/
native_handle_type native_handle()
{
- return this->get_service().native_handle(this->get_implementation());
+ return impl_.get_service().native_handle(impl_.get_implementation());
}
/// Cancel all asynchronous operations associated with the serial port.
@@ -314,7 +446,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -328,7 +460,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -342,7 +474,7 @@ public:
void send_break()
{
boost::system::error_code ec;
- this->get_service().send_break(this->get_implementation(), ec);
+ impl_.get_service().send_break(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "send_break");
}
@@ -355,7 +487,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
{
- this->get_service().send_break(this->get_implementation(), ec);
+ impl_.get_service().send_break(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -378,7 +510,7 @@ public:
void set_option(const SettableSerialPortOption& option)
{
boost::system::error_code ec;
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "set_option");
}
@@ -401,7 +533,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
boost::system::error_code& ec)
{
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -425,7 +557,7 @@ public:
void get_option(GettableSerialPortOption& option)
{
boost::system::error_code ec;
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "get_option");
}
@@ -449,7 +581,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
boost::system::error_code& ec)
{
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -474,7 +606,7 @@ public:
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
* @code
- * serial_port.write_some(boost::asio::buffer(data, size));
+ * basic_serial_port.write_some(boost::asio::buffer(data, size));
* @endcode
* See the @ref buffer documentation for information on writing multiple
* buffers in one go, and how to use it with arrays, boost::array or
@@ -484,8 +616,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = impl_.get_service().write_some(
+ impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@@ -510,8 +642,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ return impl_.get_service().write_some(
+ impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous write.
@@ -532,9 +664,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -543,7 +675,8 @@ public:
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
* @code
- * serial_port.async_write_some(boost::asio::buffer(data, size), handler);
+ * basic_serial_port.async_write_some(
+ * boost::asio::buffer(data, size), handler);
* @endcode
* See the @ref buffer documentation for information on writing multiple
* buffers in one go, and how to use it with arrays, boost::array or
@@ -555,12 +688,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- return this->get_service().async_write_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the serial port.
@@ -585,7 +715,7 @@ public:
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
* @code
- * serial_port.read_some(boost::asio::buffer(data, size));
+ * basic_serial_port.read_some(boost::asio::buffer(data, size));
* @endcode
* See the @ref buffer documentation for information on reading into multiple
* buffers in one go, and how to use it with arrays, boost::array or
@@ -595,8 +725,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = impl_.get_service().read_some(
+ impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@@ -622,8 +752,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ return impl_.get_service().read_some(
+ impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous read.
@@ -644,9 +774,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -656,7 +786,8 @@ public:
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
* @code
- * serial_port.async_read_some(boost::asio::buffer(data, size), handler);
+ * basic_serial_port.async_read_some(
+ * boost::asio::buffer(data, size), handler);
* @endcode
* See the @ref buffer documentation for information on reading into multiple
* buffers in one go, and how to use it with arrays, boost::array or
@@ -668,13 +799,55 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- return this->get_service().async_read_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_read_some(), handler, this, buffers);
}
+
+private:
+ // Disallow copying and assignment.
+ basic_serial_port(const basic_serial_port&) BOOST_ASIO_DELETED;
+ basic_serial_port& operator=(const basic_serial_port&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_write_some
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_serial_port* self, const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_write_some(
+ self->impl_.get_implementation(), buffers, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_read_some
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_serial_port* self, const MutableBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_read_some(
+ self->impl_.get_implementation(), buffers, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<detail::win_iocp_serial_port_service, Executor> impl_;
+#else
+ detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
+#endif
};
} // namespace asio
@@ -685,6 +858,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_BASIC_SERIAL_PORT_HPP
diff --git a/boost/asio/basic_signal_set.hpp b/boost/asio/basic_signal_set.hpp
index 8ca5dfa1d9..175b4f4832 100644
--- a/boost/asio/basic_signal_set.hpp
+++ b/boost/asio/basic_signal_set.hpp
@@ -2,7 +2,7 @@
// basic_signal_set.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,25 +17,24 @@
#include <boost/asio/detail/config.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/signal_set_service.hpp>
#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/signal_set_service.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
namespace boost {
namespace asio {
/// Provides signal functionality.
/**
- * The basic_signal_set class template provides the ability to perform an
- * asynchronous wait for one or more signals to occur.
- *
- * Most applications will use the boost::asio::signal_set typedef.
+ * The basic_signal_set class provides the ability to perform an asynchronous
+ * wait for one or more signals to occur.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
@@ -57,7 +56,7 @@ namespace asio {
* ...
*
* // Construct a signal set registered for process termination.
- * boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
+ * boost::asio::signal_set signals(my_context, SIGINT, SIGTERM);
*
* // Start an asynchronous wait for one of the signals to occur.
* signals.async_wait(handler);
@@ -92,20 +91,40 @@ namespace asio {
* that any signals registered using signal_set objects are unblocked in at
* least one thread.
*/
-template <typename SignalSetService = signal_set_service>
+template <typename Executor = executor>
class basic_signal_set
- : public basic_io_object<SignalSetService>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Construct a signal set without adding any signals.
+ /**
+ * This constructor creates a signal set without registering for any signals.
+ *
+ * @param ex The I/O executor that the signal set will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * signal set.
+ */
+ explicit basic_signal_set(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
/// Construct a signal set without adding any signals.
/**
* This constructor creates a signal set without registering for any signals.
*
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
+ * @param context An execution context which provides the I/O executor that
+ * the signal set will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the signal set.
*/
- explicit basic_signal_set(boost::asio::io_context& io_context)
- : basic_io_object<SignalSetService>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_signal_set(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -113,20 +132,47 @@ public:
/**
* This constructor creates a signal set and registers for one signal.
*
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
+ * @param ex The I/O executor that the signal set will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * signal set.
*
* @param signal_number_1 The signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
+ * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1); @endcode
*/
- basic_signal_set(boost::asio::io_context& io_context, int signal_number_1)
- : basic_io_object<SignalSetService>(io_context)
+ basic_signal_set(const executor_type& ex, int signal_number_1)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ }
+
+ /// Construct a signal set and add one signal.
+ /**
+ * This constructor creates a signal set and registers for one signal.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the signal set will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the signal set.
+ *
+ * @param signal_number_1 The signal number to be added.
+ *
+ * @note This constructor is equivalent to performing:
+ * @code boost::asio::signal_set signals(context);
+ * signals.add(signal_number_1); @endcode
+ */
+ template <typename ExecutionContext>
+ basic_signal_set(ExecutionContext& context, int signal_number_1,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -134,26 +180,59 @@ public:
/**
* This constructor creates a signal set and registers for two signals.
*
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
+ * @param ex The I/O executor that the signal set will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * signal set.
*
* @param signal_number_1 The first signal number to be added.
*
* @param signal_number_2 The second signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
+ * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1);
* signals.add(signal_number_2); @endcode
*/
- basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
+ basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2)
- : basic_io_object<SignalSetService>(io_context)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ }
+
+ /// Construct a signal set and add two signals.
+ /**
+ * This constructor creates a signal set and registers for two signals.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the signal set will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the signal set.
+ *
+ * @param signal_number_1 The first signal number to be added.
+ *
+ * @param signal_number_2 The second signal number to be added.
+ *
+ * @note This constructor is equivalent to performing:
+ * @code boost::asio::signal_set signals(context);
+ * signals.add(signal_number_1);
+ * signals.add(signal_number_2); @endcode
+ */
+ template <typename ExecutionContext>
+ basic_signal_set(ExecutionContext& context, int signal_number_1,
+ int signal_number_2,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_2, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -161,8 +240,9 @@ public:
/**
* This constructor creates a signal set and registers for three signals.
*
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
+ * @param ex The I/O executor that the signal set will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * signal set.
*
* @param signal_number_1 The first signal number to be added.
*
@@ -171,24 +251,77 @@ public:
* @param signal_number_3 The third signal number to be added.
*
* @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
+ * @code boost::asio::signal_set signals(ex);
* signals.add(signal_number_1);
* signals.add(signal_number_2);
* signals.add(signal_number_3); @endcode
*/
- basic_signal_set(boost::asio::io_context& io_context, int signal_number_1,
+ basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2, int signal_number_3)
- : basic_io_object<SignalSetService>(io_context)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_2, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_3, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
boost::asio::detail::throw_error(ec, "add");
}
+ /// Construct a signal set and add three signals.
+ /**
+ * This constructor creates a signal set and registers for three signals.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the signal set will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the signal set.
+ *
+ * @param signal_number_1 The first signal number to be added.
+ *
+ * @param signal_number_2 The second signal number to be added.
+ *
+ * @param signal_number_3 The third signal number to be added.
+ *
+ * @note This constructor is equivalent to performing:
+ * @code boost::asio::signal_set signals(context);
+ * signals.add(signal_number_1);
+ * signals.add(signal_number_2);
+ * signals.add(signal_number_3); @endcode
+ */
+ template <typename ExecutionContext>
+ basic_signal_set(ExecutionContext& context, int signal_number_1,
+ int signal_number_2, int signal_number_3,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
+ boost::asio::detail::throw_error(ec, "add");
+ }
+
+ /// Destroys the signal set.
+ /**
+ * This function destroys the signal set, cancelling any outstanding
+ * asynchronous wait operations associated with the signal set as if by
+ * calling @c cancel.
+ */
+ ~basic_signal_set()
+ {
+ }
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
/// Add a signal to a signal_set.
/**
* This function adds the specified signal to the set. It has no effect if the
@@ -201,7 +334,7 @@ public:
void add(int signal_number)
{
boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "add");
}
@@ -214,9 +347,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
- BOOST_ASIO_SYNC_OP_VOID add(int signal_number, boost::system::error_code& ec)
+ BOOST_ASIO_SYNC_OP_VOID add(int signal_number,
+ boost::system::error_code& ec)
{
- this->get_service().add(this->get_implementation(), signal_number, ec);
+ impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -235,7 +369,7 @@ public:
void remove(int signal_number)
{
boost::system::error_code ec;
- this->get_service().remove(this->get_implementation(), signal_number, ec);
+ impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
boost::asio::detail::throw_error(ec, "remove");
}
@@ -254,7 +388,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
boost::system::error_code& ec)
{
- this->get_service().remove(this->get_implementation(), signal_number, ec);
+ impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -270,7 +404,7 @@ public:
void clear()
{
boost::system::error_code ec;
- this->get_service().clear(this->get_implementation(), ec);
+ impl_.get_service().clear(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "clear");
}
@@ -285,7 +419,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
{
- this->get_service().clear(this->get_implementation(), ec);
+ impl_.get_service().clear(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -313,7 +447,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -340,7 +474,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -365,29 +499,45 @@ public:
* int signal_number // Indicates which signal occurred.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename SignalHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
void (boost::system::error_code, int))
async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a SignalHandler.
- BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
-
- return this->get_service().async_wait(this->get_implementation(),
- BOOST_ASIO_MOVE_CAST(SignalHandler)(handler));
+ return async_initiate<SignalHandler, void (boost::system::error_code, int)>(
+ initiate_async_wait(), handler, this);
}
+
+private:
+ // Disallow copying and assignment.
+ basic_signal_set(const basic_signal_set&) BOOST_ASIO_DELETED;
+ basic_signal_set& operator=(const basic_signal_set&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename SignalHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(SignalHandler) handler,
+ basic_signal_set* self) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a SignalHandler.
+ BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
+
+ detail::non_const_lvalue<SignalHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ detail::io_object_impl<detail::signal_set_service, Executor> impl_;
};
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_BASIC_SIGNAL_SET_HPP
diff --git a/boost/asio/basic_socket.hpp b/boost/asio/basic_socket.hpp
index ed22cd2b79..4f15f58a5c 100644
--- a/boost/asio/basic_socket.hpp
+++ b/boost/asio/basic_socket.hpp
@@ -2,7 +2,7 @@
// basic_socket.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,36 +17,43 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/post.hpp>
#include <boost/asio/socket_base.hpp>
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service.hpp>
+#endif
+
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_ssocket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service<Protocol>
-# elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
-# else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
-# endif
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_socket;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
+
/// Provides socket functionality.
/**
* The basic_socket class template provides functionality that is common to both
@@ -56,20 +63,34 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM>
+template <typename Protocol, typename Executor>
class basic_socket
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- public socket_base
+ : public socket_base
{
public:
/// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_socket<Protocol, Executor1> other;
+ };
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ typedef typename detail::null_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef typename detail::win_iocp_socket_service<
+ Protocol>::native_handle_type native_handle_type;
#else
- typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+ typedef typename detail::reactive_socket_service<
+ Protocol>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -80,18 +101,35 @@ public:
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
/// A basic_socket is always the lowest layer.
- typedef basic_socket<Protocol BOOST_ASIO_SVC_TARG> lowest_layer_type;
+ typedef basic_socket<Protocol, Executor> lowest_layer_type;
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Construct a basic_socket without opening it.
/**
* This constructor creates a socket without opening it.
*
- * @param io_context The io_context object that the socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
- explicit basic_socket(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ explicit basic_socket(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Construct a basic_socket without opening it.
+ /**
+ * This constructor creates a socket without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_socket(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -99,19 +137,42 @@ public:
/**
* This constructor creates and opens a socket.
*
- * @param io_context The io_context object that the socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_context& io_context,
- const protocol_type& protocol)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_socket(const executor_type& ex, const protocol_type& protocol)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct and open a basic_socket.
+ /**
+ * This constructor creates and opens a socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -122,7 +183,7 @@ public:
* specified endpoint on the local machine. The protocol used is the protocol
* associated with the given endpoint.
*
- * @param io_context The io_context object that the socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the socket will
@@ -130,15 +191,45 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_context& io_context,
- const endpoint_type& endpoint)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_socket(const executor_type& ex, const endpoint_type& endpoint)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ }
+
+ /// Construct a basic_socket, opening it and binding it to the given local
+ /// endpoint.
+ /**
+ * This constructor creates a socket and automatically opens it bound to the
+ * specified endpoint on the local machine. The protocol used is the protocol
+ * associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the socket will
+ * be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
const protocol_type protocol = endpoint.protocol();
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
boost::asio::detail::throw_error(ec, "bind");
}
@@ -146,7 +237,7 @@ public:
/**
* This constructor creates a socket object to hold an existing native socket.
*
- * @param io_context The io_context object that the socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
@@ -155,12 +246,40 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket(boost::asio::io_context& io_context,
- const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_socket(const executor_type& ex, const protocol_type& protocol,
+ const native_handle_type& native_socket)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_socket, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_socket on an existing native socket.
+ /**
+ * This constructor creates a socket object to hold an existing native socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket A native socket.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket(ExecutionContext& context, const protocol_type& protocol,
+ const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_socket, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -174,10 +293,10 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket(const executor_type&) constructor.
*/
basic_socket(basic_socket&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -189,16 +308,16 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket(const executor_type&) constructor.
*/
basic_socket& operator=(basic_socket&& other)
{
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ impl_ = std::move(other.impl_);
return *this;
}
// All sockets have access to each other's implementations.
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+ template <typename Protocol1, typename Executor1>
friend class basic_socket;
/// Move-construct a basic_socket from a socket of another protocol type.
@@ -209,13 +328,15 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket(const executor_type&) constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_socket(basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<BOOST_ASIO_SVC_T>(
- other.get_service(), other.get_implementation())
+ template <typename Protocol1, typename Executor1>
+ basic_socket(basic_socket<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : impl_(std::move(other.impl_))
{
}
@@ -227,58 +348,26 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket(const executor_type&) constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_socket>::type& operator=(
- basic_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_socket&
+ >::type operator=(basic_socket<Protocol1, Executor1> && other)
{
basic_socket tmp(std::move(other));
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
+ impl_ = std::move(tmp.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ return impl_.get_executor();
}
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
/// Get a reference to the lowest layer.
@@ -320,14 +409,14 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* socket.open(boost::asio::ip::tcp::v4());
* @endcode
*/
void open(const protocol_type& protocol = protocol_type())
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -341,7 +430,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::system::error_code ec;
* socket.open(boost::asio::ip::tcp::v4(), ec);
* if (ec)
@@ -353,7 +442,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
boost::system::error_code& ec)
{
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -371,7 +460,7 @@ public:
const native_handle_type& native_socket)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_socket, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -389,7 +478,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_socket, boost::system::error_code& ec)
{
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_socket, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -397,7 +486,7 @@ public:
/// Determine whether the socket is open.
bool is_open() const
{
- return this->get_service().is_open(this->get_implementation());
+ return impl_.get_service().is_open(impl_.get_implementation());
}
/// Close the socket.
@@ -415,7 +504,7 @@ public:
void close()
{
boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "close");
}
@@ -430,7 +519,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::system::error_code ec;
* socket.close(ec);
@@ -445,7 +534,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -471,8 +560,8 @@ public:
native_handle_type release()
{
boost::system::error_code ec;
- native_handle_type s = this->get_service().release(
- this->get_implementation(), ec);
+ native_handle_type s = impl_.get_service().release(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "release");
return s;
}
@@ -498,7 +587,7 @@ public:
#endif
native_handle_type release(boost::system::error_code& ec)
{
- return this->get_service().release(this->get_implementation(), ec);
+ return impl_.get_service().release(impl_.get_implementation(), ec);
}
/// Get the native socket representation.
@@ -509,7 +598,7 @@ public:
*/
native_handle_type native_handle()
{
- return this->get_service().native_handle(this->get_implementation());
+ return impl_.get_service().native_handle(impl_.get_implementation());
}
/// Cancel all asynchronous operations associated with the socket.
@@ -556,7 +645,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -603,7 +692,7 @@ public:
#endif
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -620,7 +709,7 @@ public:
bool at_mark() const
{
boost::system::error_code ec;
- bool b = this->get_service().at_mark(this->get_implementation(), ec);
+ bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "at_mark");
return b;
}
@@ -637,7 +726,7 @@ public:
*/
bool at_mark(boost::system::error_code& ec) const
{
- return this->get_service().at_mark(this->get_implementation(), ec);
+ return impl_.get_service().at_mark(impl_.get_implementation(), ec);
}
/// Determine the number of bytes available for reading.
@@ -653,8 +742,8 @@ public:
std::size_t available() const
{
boost::system::error_code ec;
- std::size_t s = this->get_service().available(
- this->get_implementation(), ec);
+ std::size_t s = impl_.get_service().available(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "available");
return s;
}
@@ -671,7 +760,7 @@ public:
*/
std::size_t available(boost::system::error_code& ec) const
{
- return this->get_service().available(this->get_implementation(), ec);
+ return impl_.get_service().available(impl_.get_implementation(), ec);
}
/// Bind the socket to the given local endpoint.
@@ -686,7 +775,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* socket.open(boost::asio::ip::tcp::v4());
* socket.bind(boost::asio::ip::tcp::endpoint(
* boost::asio::ip::tcp::v4(), 12345));
@@ -695,7 +784,7 @@ public:
void bind(const endpoint_type& endpoint)
{
boost::system::error_code ec;
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
boost::asio::detail::throw_error(ec, "bind");
}
@@ -711,7 +800,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* socket.open(boost::asio::ip::tcp::v4());
* boost::system::error_code ec;
* socket.bind(boost::asio::ip::tcp::endpoint(
@@ -725,7 +814,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
boost::system::error_code& ec)
{
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -746,7 +835,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* socket.connect(endpoint);
@@ -757,11 +846,11 @@ public:
boost::system::error_code ec;
if (!is_open())
{
- this->get_service().open(this->get_implementation(),
+ impl_.get_service().open(impl_.get_implementation(),
peer_endpoint.protocol(), ec);
boost::asio::detail::throw_error(ec, "connect");
}
- this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
boost::asio::detail::throw_error(ec, "connect");
}
@@ -782,7 +871,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* boost::system::error_code ec;
@@ -798,7 +887,7 @@ public:
{
if (!is_open())
{
- this->get_service().open(this->get_implementation(),
+ impl_.get_service().open(impl_.get_implementation(),
peer_endpoint.protocol(), ec);
if (ec)
{
@@ -806,7 +895,7 @@ public:
}
}
- this->get_service().connect(this->get_implementation(), peer_endpoint, ec);
+ impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -829,9 +918,9 @@ public:
* const boost::system::error_code& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -845,7 +934,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::asio::ip::tcp::endpoint endpoint(
* boost::asio::ip::address::from_string("1.2.3.4"), 12345);
* socket.async_connect(endpoint, connect_handler);
@@ -857,42 +946,15 @@ public:
async_connect(const endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ConnectHandler.
- BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
-
+ boost::system::error_code open_ec;
if (!is_open())
{
- boost::system::error_code ec;
const protocol_type protocol = peer_endpoint.protocol();
- this->get_service().open(this->get_implementation(), protocol, ec);
- if (ec)
- {
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- boost::asio::post(this->get_executor(),
- boost::asio::detail::bind_handler(
- BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE(
- ConnectHandler, void (boost::system::error_code)))(
- init.completion_handler), ec));
-
- return init.result.get();
- }
+ impl_.get_service().open(impl_.get_implementation(), protocol, open_ec);
}
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_connect(this->get_implementation(),
- peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_connect(
- this->get_implementation(), peer_endpoint, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ConnectHandler, void (boost::system::error_code)>(
+ initiate_async_connect(), handler, this, peer_endpoint, open_ec);
}
/// Set an option on the socket.
@@ -923,7 +985,7 @@ public:
* @par Example
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::no_delay option(true);
* socket.set_option(option);
@@ -933,7 +995,7 @@ public:
void set_option(const SettableSocketOption& option)
{
boost::system::error_code ec;
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "set_option");
}
@@ -965,7 +1027,7 @@ public:
* @par Example
* Setting the IPPROTO_TCP/TCP_NODELAY option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::no_delay option(true);
* boost::system::error_code ec;
@@ -980,7 +1042,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
boost::system::error_code& ec)
{
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1012,7 +1074,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::socket::keep_alive option;
* socket.get_option(option);
@@ -1023,7 +1085,7 @@ public:
void get_option(GettableSocketOption& option) const
{
boost::system::error_code ec;
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "get_option");
}
@@ -1055,7 +1117,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::socket::keep_alive option;
* boost::system::error_code ec;
@@ -1071,7 +1133,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
boost::system::error_code& ec) const
{
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1090,7 +1152,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::socket::bytes_readable command;
* socket.io_control(command);
@@ -1101,7 +1163,7 @@ public:
void io_control(IoControlCommand& command)
{
boost::system::error_code ec;
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
boost::asio::detail::throw_error(ec, "io_control");
}
@@ -1120,7 +1182,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::socket::bytes_readable command;
* boost::system::error_code ec;
@@ -1136,7 +1198,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
boost::system::error_code& ec)
{
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1153,7 +1215,7 @@ public:
*/
bool non_blocking() const
{
- return this->get_service().non_blocking(this->get_implementation());
+ return impl_.get_service().non_blocking(impl_.get_implementation());
}
/// Sets the non-blocking mode of the socket.
@@ -1172,7 +1234,7 @@ public:
void non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "non_blocking");
}
@@ -1192,7 +1254,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1282,7 +1344,7 @@ public:
*/
bool native_non_blocking() const
{
- return this->get_service().native_non_blocking(this->get_implementation());
+ return impl_.get_service().native_non_blocking(impl_.get_implementation());
}
/// Sets the non-blocking mode of the native socket implementation.
@@ -1373,8 +1435,8 @@ public:
void native_non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "native_non_blocking");
}
@@ -1466,8 +1528,8 @@ public:
BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1481,7 +1543,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
* @endcode
@@ -1489,8 +1551,8 @@ public:
endpoint_type local_endpoint() const
{
boost::system::error_code ec;
- endpoint_type ep = this->get_service().local_endpoint(
- this->get_implementation(), ec);
+ endpoint_type ep = impl_.get_service().local_endpoint(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "local_endpoint");
return ep;
}
@@ -1506,7 +1568,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
@@ -1518,7 +1580,7 @@ public:
*/
endpoint_type local_endpoint(boost::system::error_code& ec) const
{
- return this->get_service().local_endpoint(this->get_implementation(), ec);
+ return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
}
/// Get the remote endpoint of the socket.
@@ -1531,7 +1593,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
* @endcode
@@ -1539,8 +1601,8 @@ public:
endpoint_type remote_endpoint() const
{
boost::system::error_code ec;
- endpoint_type ep = this->get_service().remote_endpoint(
- this->get_implementation(), ec);
+ endpoint_type ep = impl_.get_service().remote_endpoint(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "remote_endpoint");
return ep;
}
@@ -1556,7 +1618,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
@@ -1568,7 +1630,7 @@ public:
*/
endpoint_type remote_endpoint(boost::system::error_code& ec) const
{
- return this->get_service().remote_endpoint(this->get_implementation(), ec);
+ return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec);
}
/// Disable sends or receives on the socket.
@@ -1583,7 +1645,7 @@ public:
* @par Example
* Shutting down the send side of the socket:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send);
* @endcode
@@ -1591,7 +1653,7 @@ public:
void shutdown(shutdown_type what)
{
boost::system::error_code ec;
- this->get_service().shutdown(this->get_implementation(), what, ec);
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
boost::asio::detail::throw_error(ec, "shutdown");
}
@@ -1607,7 +1669,7 @@ public:
* @par Example
* Shutting down the send side of the socket:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::system::error_code ec;
* socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
@@ -1620,7 +1682,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what,
boost::system::error_code& ec)
{
- this->get_service().shutdown(this->get_implementation(), what, ec);
+ impl_.get_service().shutdown(impl_.get_implementation(), what, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1635,7 +1697,7 @@ public:
* @par Example
* Waiting for a socket to become readable.
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* socket.wait(boost::asio::ip::tcp::socket::wait_read);
* @endcode
@@ -1643,7 +1705,7 @@ public:
void wait(wait_type w)
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -1660,7 +1722,7 @@ public:
* @par Example
* Waiting for a socket to become readable.
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::system::error_code ec;
* socket.wait(boost::asio::ip::tcp::socket::wait_read, ec);
@@ -1668,7 +1730,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1687,9 +1749,9 @@ public:
* const boost::system::error_code& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1703,7 +1765,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler);
* @endcode
@@ -1713,22 +1775,8 @@ public:
void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_wait(this->get_implementation(),
- w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- w, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
}
protected:
@@ -1741,10 +1789,65 @@ protected:
{
}
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ detail::io_object_impl<
+ detail::null_socket_service<Protocol>, Executor> impl_;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<
+ detail::win_iocp_socket_service<Protocol>, Executor> impl_;
+#else
+ detail::io_object_impl<
+ detail::reactive_socket_service<Protocol>, Executor> impl_;
+#endif
+
private:
// Disallow copying and assignment.
basic_socket(const basic_socket&) BOOST_ASIO_DELETED;
basic_socket& operator=(const basic_socket&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_connect
+ {
+ template <typename ConnectHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler,
+ basic_socket* self, const endpoint_type& peer_endpoint,
+ const boost::system::error_code& open_ec) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ConnectHandler.
+ BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
+
+ if (open_ec)
+ {
+ boost::asio::post(self->impl_.get_executor(),
+ boost::asio::detail::bind_handler(
+ BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec));
+ }
+ else
+ {
+ detail::non_const_lvalue<ConnectHandler> handler2(handler);
+ self->impl_.get_service().async_connect(
+ self->impl_.get_implementation(), peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ }
+ };
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_socket* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace asio
@@ -1752,8 +1855,4 @@ private:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_BASIC_SOCKET_HPP
diff --git a/boost/asio/basic_socket_acceptor.hpp b/boost/asio/basic_socket_acceptor.hpp
index 8afdfd3009..12613b8260 100644
--- a/boost/asio/basic_socket_acceptor.hpp
+++ b/boost/asio/basic_socket_acceptor.hpp
@@ -2,7 +2,7 @@
// basic_socket_acceptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,38 +16,43 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-#include <boost/asio/basic_io_object.hpp>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/socket_base.hpp>
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/null_socket_service.hpp>
+#elif defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_socket_service.hpp>
+#else
+# include <boost/asio/detail/reactive_socket_service.hpp>
+#endif
+
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/socket_acceptor_service.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::null_socket_service<Protocol>
-# elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service<Protocol>
-# else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_socket_service<Protocol>
-# endif
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_socket_acceptor;
+
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
+
/// Provides the ability to accept new connections.
/**
* The basic_socket_acceptor class template is used for accepting new socket
@@ -60,7 +65,7 @@ namespace asio {
* @par Example
* Opening a socket acceptor with the SO_REUSEADDR option enabled:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
* acceptor.open(endpoint.protocol());
* acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
@@ -68,21 +73,26 @@ namespace asio {
* acceptor.listen();
* @endcode
*/
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= socket_acceptor_service<Protocol>)>
+template <typename Protocol, typename Executor>
class basic_socket_acceptor
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- public socket_base
+ : public socket_base
{
public:
/// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
+ typedef Executor executor_type;
/// The native representation of an acceptor.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
+#elif defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ typedef typename detail::null_socket_service<
+ Protocol>::native_handle_type native_handle_type;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ typedef typename detail::win_iocp_socket_service<
+ Protocol>::native_handle_type native_handle_type;
#else
- typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
+ typedef typename detail::reactive_socket_service<
+ Protocol>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -97,12 +107,31 @@ public:
* connections. The open() function must be called before the acceptor can
* accept new socket connections.
*
- * @param io_context The io_context object that the acceptor will use to
+ * @param ex The I/O executor that the acceptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*/
- explicit basic_socket_acceptor(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ explicit basic_socket_acceptor(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Construct an acceptor without opening it.
+ /**
+ * This constructor creates an acceptor without opening it to listen for new
+ * connections. The open() function must be called before the acceptor can
+ * accept new socket connections.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ */
+ template <typename ExecutionContext>
+ explicit basic_socket_acceptor(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -110,7 +139,7 @@ public:
/**
* This constructor creates an acceptor and automatically opens it.
*
- * @param io_context The io_context object that the acceptor will use to
+ * @param ex The I/O executor that the acceptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -118,12 +147,36 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket_acceptor(boost::asio::io_context& io_context,
- const protocol_type& protocol)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ }
+
+ /// Construct an open acceptor.
+ /**
+ * This constructor creates an acceptor and automatically opens it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor(ExecutionContext& context,
+ const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -132,7 +185,7 @@ public:
* This constructor creates an acceptor and automatically opens it to listen
* for new connections on the specified endpoint.
*
- * @param io_context The io_context object that the acceptor will use to
+ * @param ex The I/O executor that the acceptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -146,31 +199,83 @@ public:
*
* @note This constructor is equivalent to the following code:
* @code
- * basic_socket_acceptor<Protocol> acceptor(io_context);
+ * basic_socket_acceptor<Protocol> acceptor(my_context);
* acceptor.open(endpoint.protocol());
* if (reuse_addr)
* acceptor.set_option(socket_base::reuse_address(true));
* acceptor.bind(endpoint);
- * acceptor.listen(listen_backlog);
+ * acceptor.listen();
* @endcode
*/
- basic_socket_acceptor(boost::asio::io_context& io_context,
+ basic_socket_acceptor(const executor_type& ex,
const endpoint_type& endpoint, bool reuse_addr = true)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ : impl_(ex)
{
boost::system::error_code ec;
const protocol_type protocol = endpoint.protocol();
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
if (reuse_addr)
{
- this->get_service().set_option(this->get_implementation(),
+ impl_.get_service().set_option(impl_.get_implementation(),
socket_base::reuse_address(true), ec);
boost::asio::detail::throw_error(ec, "set_option");
}
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
boost::asio::detail::throw_error(ec, "bind");
- this->get_service().listen(this->get_implementation(),
+ impl_.get_service().listen(impl_.get_implementation(),
+ socket_base::max_listen_connections, ec);
+ boost::asio::detail::throw_error(ec, "listen");
+ }
+
+ /// Construct an acceptor opened on the given endpoint.
+ /**
+ * This constructor creates an acceptor and automatically opens it to listen
+ * for new connections on the specified endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param endpoint An endpoint on the local machine on which the acceptor
+ * will listen for new connections.
+ *
+ * @param reuse_addr Whether the constructor should set the socket option
+ * socket_base::reuse_address.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This constructor is equivalent to the following code:
+ * @code
+ * basic_socket_acceptor<Protocol> acceptor(my_context);
+ * acceptor.open(endpoint.protocol());
+ * if (reuse_addr)
+ * acceptor.set_option(socket_base::reuse_address(true));
+ * acceptor.bind(endpoint);
+ * acceptor.listen();
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor(ExecutionContext& context,
+ const endpoint_type& endpoint, bool reuse_addr = true,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ const protocol_type protocol = endpoint.protocol();
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
+ boost::asio::detail::throw_error(ec, "open");
+ if (reuse_addr)
+ {
+ impl_.get_service().set_option(impl_.get_implementation(),
+ socket_base::reuse_address(true), ec);
+ boost::asio::detail::throw_error(ec, "set_option");
+ }
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
+ boost::asio::detail::throw_error(ec, "bind");
+ impl_.get_service().listen(impl_.get_implementation(),
socket_base::max_listen_connections, ec);
boost::asio::detail::throw_error(ec, "listen");
}
@@ -180,7 +285,7 @@ public:
* This constructor creates an acceptor object to hold an existing native
* acceptor.
*
- * @param io_context The io_context object that the acceptor will use to
+ * @param ex The I/O executor that the acceptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* acceptor.
*
@@ -190,12 +295,41 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_socket_acceptor(boost::asio::io_context& io_context,
+ basic_socket_acceptor(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_acceptor)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
+ protocol, native_acceptor, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a basic_socket_acceptor on an existing native acceptor.
+ /**
+ * This constructor creates an acceptor object to hold an existing native
+ * acceptor.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the acceptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the acceptor.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_acceptor A native acceptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_socket_acceptor(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_acceptor,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_acceptor, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -209,10 +343,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket_acceptor(io_context&) constructor.
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
*/
basic_socket_acceptor(basic_socket_acceptor&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -224,16 +359,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket_acceptor(io_context&) constructor.
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
*/
basic_socket_acceptor& operator=(basic_socket_acceptor&& other)
{
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ impl_ = std::move(other.impl_);
return *this;
}
// All socket acceptors have access to each other's implementations.
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
+ template <typename Protocol1, typename Executor1>
friend class basic_socket_acceptor;
/// Move-construct a basic_socket_acceptor from an acceptor of another
@@ -245,14 +381,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_socket_acceptor(
- basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_io_object<BOOST_ASIO_SVC_T>(
- other.get_service(), other.get_implementation())
+ template <typename Protocol1, typename Executor1>
+ basic_socket_acceptor(basic_socket_acceptor<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : impl_(std::move(other.impl_))
{
}
@@ -265,15 +403,18 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_socket(io_context&) constructor.
+ * constructed using the @c basic_socket_acceptor(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_socket_acceptor>::type& operator=(
- basic_socket_acceptor<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_socket_acceptor&
+ >::type operator=(basic_socket_acceptor<Protocol1, Executor1>&& other)
{
basic_socket_acceptor tmp(std::move(other));
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(tmp));
+ impl_ = std::move(tmp.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -288,45 +429,11 @@ public:
{
}
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ return impl_.get_executor();
}
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Open the acceptor using the specified protocol.
/**
@@ -339,14 +446,14 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* acceptor.open(boost::asio::ip::tcp::v4());
* @endcode
*/
void open(const protocol_type& protocol = protocol_type())
{
boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
boost::asio::detail::throw_error(ec, "open");
}
@@ -361,7 +468,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* boost::system::error_code ec;
* acceptor.open(boost::asio::ip::tcp::v4(), ec);
* if (ec)
@@ -373,7 +480,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol,
boost::system::error_code& ec)
{
- this->get_service().open(this->get_implementation(), protocol, ec);
+ impl_.get_service().open(impl_.get_implementation(), protocol, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -391,7 +498,7 @@ public:
const native_handle_type& native_acceptor)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_acceptor, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -409,7 +516,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol,
const native_handle_type& native_acceptor, boost::system::error_code& ec)
{
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
protocol, native_acceptor, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -417,7 +524,7 @@ public:
/// Determine whether the acceptor is open.
bool is_open() const
{
- return this->get_service().is_open(this->get_implementation());
+ return impl_.get_service().is_open(impl_.get_implementation());
}
/// Bind the acceptor to the given local endpoint.
@@ -432,7 +539,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
* acceptor.open(endpoint.protocol());
* acceptor.bind(endpoint);
@@ -441,7 +548,7 @@ public:
void bind(const endpoint_type& endpoint)
{
boost::system::error_code ec;
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
boost::asio::detail::throw_error(ec, "bind");
}
@@ -457,7 +564,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345);
* acceptor.open(endpoint.protocol());
* boost::system::error_code ec;
@@ -471,7 +578,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint,
boost::system::error_code& ec)
{
- this->get_service().bind(this->get_implementation(), endpoint, ec);
+ impl_.get_service().bind(impl_.get_implementation(), endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -488,7 +595,7 @@ public:
void listen(int backlog = socket_base::max_listen_connections)
{
boost::system::error_code ec;
- this->get_service().listen(this->get_implementation(), backlog, ec);
+ impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
boost::asio::detail::throw_error(ec, "listen");
}
@@ -504,7 +611,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::system::error_code ec;
* acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
@@ -516,7 +623,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec)
{
- this->get_service().listen(this->get_implementation(), backlog, ec);
+ impl_.get_service().listen(impl_.get_implementation(), backlog, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -533,7 +640,7 @@ public:
void close()
{
boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "close");
}
@@ -549,7 +656,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::system::error_code ec;
* acceptor.close(ec);
@@ -561,7 +668,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -587,8 +694,8 @@ public:
native_handle_type release()
{
boost::system::error_code ec;
- native_handle_type s = this->get_service().release(
- this->get_implementation(), ec);
+ native_handle_type s = impl_.get_service().release(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "release");
return s;
}
@@ -614,7 +721,7 @@ public:
#endif
native_handle_type release(boost::system::error_code& ec)
{
- return this->get_service().release(this->get_implementation(), ec);
+ return impl_.get_service().release(impl_.get_implementation(), ec);
}
/// Get the native acceptor representation.
@@ -625,7 +732,7 @@ public:
*/
native_handle_type native_handle()
{
- return this->get_service().native_handle(this->get_implementation());
+ return impl_.get_service().native_handle(impl_.get_implementation());
}
/// Cancel all asynchronous operations associated with the acceptor.
@@ -639,7 +746,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -653,7 +760,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -672,7 +779,7 @@ public:
* @par Example
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option(true);
* acceptor.set_option(option);
@@ -682,7 +789,7 @@ public:
void set_option(const SettableSocketOption& option)
{
boost::system::error_code ec;
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "set_option");
}
@@ -701,7 +808,7 @@ public:
* @par Example
* Setting the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option(true);
* boost::system::error_code ec;
@@ -716,7 +823,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option,
boost::system::error_code& ec)
{
- this->get_service().set_option(this->get_implementation(), option, ec);
+ impl_.get_service().set_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -735,7 +842,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option;
* acceptor.get_option(option);
@@ -746,7 +853,7 @@ public:
void get_option(GettableSocketOption& option) const
{
boost::system::error_code ec;
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
boost::asio::detail::throw_error(ec, "get_option");
}
@@ -765,7 +872,7 @@ public:
* @par Example
* Getting the value of the SOL_SOCKET/SO_REUSEADDR option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::reuse_address option;
* boost::system::error_code ec;
@@ -781,7 +888,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option,
boost::system::error_code& ec) const
{
- this->get_service().get_option(this->get_implementation(), option, ec);
+ impl_.get_service().get_option(impl_.get_implementation(), option, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -799,7 +906,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
* socket.io_control(command);
@@ -809,7 +916,7 @@ public:
void io_control(IoControlCommand& command)
{
boost::system::error_code ec;
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
boost::asio::detail::throw_error(ec, "io_control");
}
@@ -827,7 +934,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::acceptor::non_blocking_io command(true);
* boost::system::error_code ec;
@@ -842,7 +949,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
boost::system::error_code& ec)
{
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -859,7 +966,7 @@ public:
*/
bool non_blocking() const
{
- return this->get_service().non_blocking(this->get_implementation());
+ return impl_.get_service().non_blocking(impl_.get_implementation());
}
/// Sets the non-blocking mode of the acceptor.
@@ -878,7 +985,7 @@ public:
void non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "non_blocking");
}
@@ -898,7 +1005,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -918,7 +1025,7 @@ public:
*/
bool native_non_blocking() const
{
- return this->get_service().native_non_blocking(this->get_implementation());
+ return impl_.get_service().native_non_blocking(impl_.get_implementation());
}
/// Sets the non-blocking mode of the native acceptor implementation.
@@ -939,8 +1046,8 @@ public:
void native_non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "native_non_blocking");
}
@@ -962,8 +1069,8 @@ public:
BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -977,7 +1084,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint();
* @endcode
@@ -985,8 +1092,8 @@ public:
endpoint_type local_endpoint() const
{
boost::system::error_code ec;
- endpoint_type ep = this->get_service().local_endpoint(
- this->get_implementation(), ec);
+ endpoint_type ep = impl_.get_service().local_endpoint(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "local_endpoint");
return ep;
}
@@ -1003,7 +1110,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::system::error_code ec;
* boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec);
@@ -1015,7 +1122,7 @@ public:
*/
endpoint_type local_endpoint(boost::system::error_code& ec) const
{
- return this->get_service().local_endpoint(this->get_implementation(), ec);
+ return impl_.get_service().local_endpoint(impl_.get_implementation(), ec);
}
/// Wait for the acceptor to become ready to read, ready to write, or to have
@@ -1029,7 +1136,7 @@ public:
* @par Example
* Waiting for an acceptor to become readable.
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read);
* @endcode
@@ -1037,7 +1144,7 @@ public:
void wait(wait_type w)
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -1054,7 +1161,7 @@ public:
* @par Example
* Waiting for an acceptor to become readable.
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::system::error_code ec;
* acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec);
@@ -1062,7 +1169,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1081,9 +1188,9 @@ public:
* const boost::system::error_code& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1097,7 +1204,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* acceptor.async_wait(
* boost::asio::ip::tcp::acceptor::wait_read,
@@ -1109,22 +1216,8 @@ public:
void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_wait(this->get_implementation(),
- w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- w, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -1140,24 +1233,20 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* acceptor.accept(socket);
* @endcode
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1, typename SocketService>
- void accept(basic_socket<Protocol1, SocketService>& peer,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1>
- void accept(basic_socket<Protocol1>& peer,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ template <typename Protocol1, typename Executor1>
+ void accept(basic_socket<Protocol1, Executor1>& peer,
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
{
boost::system::error_code ec;
- this->get_service().accept(this->get_implementation(),
+ impl_.get_service().accept(impl_.get_implementation(),
peer, static_cast<endpoint_type*>(0), ec);
boost::asio::detail::throw_error(ec, "accept");
}
@@ -1174,9 +1263,9 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::system::error_code ec;
* acceptor.accept(socket, ec);
* if (ec)
@@ -1185,20 +1274,14 @@ public:
* }
* @endcode
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1, typename SocketService>
+ template <typename Protocol1, typename Executor1>
BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket<Protocol1, SocketService>& peer,
- boost::system::error_code& ec,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket<Protocol1>& peer, boost::system::error_code& ec,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ basic_socket<Protocol1, Executor1>& peer, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
{
- this->get_service().accept(this->get_implementation(),
+ impl_.get_service().accept(impl_.get_implementation(),
peer, static_cast<endpoint_type*>(0), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1219,9 +1302,9 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1235,45 +1318,24 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* acceptor.async_accept(socket, accept_handler);
* @endcode
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1, typename SocketService, typename AcceptHandler>
+ template <typename Protocol1, typename Executor1, typename AcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code))
- async_accept(basic_socket<Protocol1, SocketService>& peer,
+ async_accept(basic_socket<Protocol1, Executor1>& peer,
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename Protocol1, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket<Protocol1>& peer,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ typename enable_if<
+ is_convertible<Protocol, Protocol1>::value
+ >::type* = 0)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a AcceptHandler.
- BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(this->get_implementation(),
- peer, static_cast<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<AcceptHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- peer, static_cast<endpoint_type*>(0), init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<AcceptHandler, void (boost::system::error_code)>(
+ initiate_async_accept(), handler, this,
+ &peer, static_cast<endpoint_type*>(0));
}
/// Accept a new connection and obtain the endpoint of the peer
@@ -1292,23 +1354,19 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::asio::ip::tcp::endpoint endpoint;
* acceptor.accept(socket, endpoint);
* @endcode
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename SocketService>
- void accept(basic_socket<protocol_type, SocketService>& peer,
+ template <typename Executor1>
+ void accept(basic_socket<protocol_type, Executor1>& peer,
endpoint_type& peer_endpoint)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- void accept(basic_socket<protocol_type>& peer, endpoint_type& peer_endpoint)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
boost::system::error_code ec;
- this->get_service().accept(this->get_implementation(),
+ impl_.get_service().accept(impl_.get_implementation(),
peer, &peer_endpoint, ec);
boost::asio::detail::throw_error(ec, "accept");
}
@@ -1329,9 +1387,9 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* boost::asio::ip::tcp::endpoint endpoint;
* boost::system::error_code ec;
* acceptor.accept(socket, endpoint, ec);
@@ -1341,18 +1399,12 @@ public:
* }
* @endcode
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename SocketService>
- BOOST_ASIO_SYNC_OP_VOID accept(
- basic_socket<protocol_type, SocketService>& peer,
- endpoint_type& peer_endpoint, boost::system::error_code& ec)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type>& peer,
+ template <typename Executor1>
+ BOOST_ASIO_SYNC_OP_VOID accept(basic_socket<protocol_type, Executor1>& peer,
endpoint_type& peer_endpoint, boost::system::error_code& ec)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
- this->get_service().accept(
- this->get_implementation(), peer, &peer_endpoint, ec);
+ impl_.get_service().accept(
+ impl_.get_implementation(), peer, &peer_endpoint, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -1378,40 +1430,18 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename SocketService, typename AcceptHandler>
+ template <typename Executor1, typename AcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
void (boost::system::error_code))
- async_accept(basic_socket<protocol_type, SocketService>& peer,
+ async_accept(basic_socket<protocol_type, Executor1>& peer,
endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- template <typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(basic_socket<protocol_type>& peer,
- endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a AcceptHandler.
- BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(this->get_implementation(), peer,
- &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<AcceptHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- peer, &peer_endpoint, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<AcceptHandler, void (boost::system::error_code)>(
+ initiate_async_accept(), handler, this, &peer, &peer_endpoint);
}
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -1431,7 +1461,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::socket socket(acceptor.accept());
* @endcode
@@ -1439,9 +1469,8 @@ public:
typename Protocol::socket accept()
{
boost::system::error_code ec;
- typename Protocol::socket peer(
- this->get_service().accept(
- this->get_implementation(), 0, 0, ec));
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
boost::asio::detail::throw_error(ec, "accept");
return peer;
}
@@ -1462,7 +1491,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::socket socket(acceptor.accept(ec));
* if (ec)
@@ -1473,7 +1502,9 @@ public:
*/
typename Protocol::socket accept(boost::system::error_code& ec)
{
- return this->get_service().accept(this->get_implementation(), 0, 0, ec);
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
}
/// Start an asynchronous accept.
@@ -1492,9 +1523,9 @@ public:
* typename Protocol::socket peer // On success, the newly accepted socket.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1509,7 +1540,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* acceptor.async_accept(accept_handler);
* @endcode
@@ -1519,27 +1550,49 @@ public:
void (boost::system::error_code, typename Protocol::socket))
async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a MoveAcceptHandler.
- BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
- handler, typename Protocol::socket) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(
- this->get_implementation(), static_cast<boost::asio::io_context*>(0),
- static_cast<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(
- this->get_implementation(), static_cast<boost::asio::io_context*>(0),
- static_cast<endpoint_type*>(0), init.completion_handler);
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket)>(
+ initiate_async_move_accept(), handler, this,
+ impl_.get_executor(), static_cast<endpoint_type*>(0),
+ static_cast<typename Protocol::socket*>(0));
+ }
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly
+ * accepted socket.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept());
+ * @endcode
+ */
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
}
/// Accept a new connection.
@@ -1551,8 +1604,8 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
- * socket.
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
*
* @returns A socket object representing the newly accepted connection.
*
@@ -1560,17 +1613,23 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::socket socket(acceptor.accept());
* @endcode
*/
- typename Protocol::socket accept(boost::asio::io_context& io_context)
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
{
boost::system::error_code ec;
- typename Protocol::socket peer(
- this->get_service().accept(this->get_implementation(),
- &io_context, static_cast<endpoint_type*>(0), ec));
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
boost::asio::detail::throw_error(ec, "accept");
return peer;
}
@@ -1584,7 +1643,7 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
+ * @param ex The I/O executor object to be used for the newly accepted
* socket.
*
* @param ec Set to indicate what error occurred, if any.
@@ -1594,20 +1653,68 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * boost::asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec));
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
* if (ec)
* {
* // An error occurred.
* }
* @endcode
*/
- typename Protocol::socket accept(
- boost::asio::io_context& io_context, boost::system::error_code& ec)
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex, boost::system::error_code& ec,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
{
- return this->get_service().accept(this->get_implementation(),
- &io_context, static_cast<endpoint_type*>(0), ec);
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec);
+ return peer;
}
/// Start an asynchronous accept.
@@ -1618,7 +1725,7 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
+ * @param ex The I/O executor object to be used for the newly accepted
* socket.
*
* @param handler The handler to be called when the accept operation
@@ -1626,12 +1733,13 @@ public:
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
- * typename Protocol::socket peer // On success, the newly accepted socket.
+ * typename Protocol::socket::template rebind_executor<
+ * Executor1>::other peer // On success, the newly accepted socket.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1646,36 +1754,94 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
- * acceptor.async_accept(io_context2, accept_handler);
+ * acceptor.async_accept(my_context2, accept_handler);
* @endcode
*/
- template <typename MoveAcceptHandler>
+ template <typename Executor1, typename MoveAcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket))
- async_accept(boost::asio::io_context& io_context,
- BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a MoveAcceptHandler.
- BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
- handler, typename Protocol::socket) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(this->get_implementation(),
- &io_context, static_cast<endpoint_type*>(0),
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- &io_context, static_cast<endpoint_type*>(0), init.completion_handler);
+ typename Protocol::socket::template rebind_executor<
+ Executor1>::other))
+ async_accept(const Executor1& ex,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ Executor1>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ ex, static_cast<endpoint_type*>(0),
+ static_cast<other_socket_type*>(0));
+ }
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * typename ExecutionContext::executor_type>::other peer
+ * // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * acceptor.async_accept(my_context2, accept_handler);
+ * @endcode
+ */
+ template <typename ExecutionContext, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other))
+ async_accept(ExecutionContext& context,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ context.get_executor(), static_cast<endpoint_type*>(0),
+ static_cast<other_socket_type*>(0));
}
/// Accept a new connection.
@@ -1696,7 +1862,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
* boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint));
@@ -1705,9 +1871,9 @@ public:
typename Protocol::socket accept(endpoint_type& peer_endpoint)
{
boost::system::error_code ec;
- typename Protocol::socket peer(
- this->get_service().accept(this->get_implementation(),
- static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec));
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
boost::asio::detail::throw_error(ec, "accept");
return peer;
}
@@ -1731,7 +1897,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
* boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec));
@@ -1744,8 +1910,10 @@ public:
typename Protocol::socket accept(
endpoint_type& peer_endpoint, boost::system::error_code& ec)
{
- return this->get_service().accept(this->get_implementation(),
- static_cast<boost::asio::io_context*>(0), &peer_endpoint, ec);
+ typename Protocol::socket peer(impl_.get_executor());
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
}
/// Start an asynchronous accept.
@@ -1769,9 +1937,9 @@ public:
* typename Protocol::socket peer // On success, the newly accepted socket.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1786,7 +1954,7 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
* acceptor.async_accept(endpoint, accept_handler);
@@ -1798,26 +1966,11 @@ public:
async_accept(endpoint_type& peer_endpoint,
BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a MoveAcceptHandler.
- BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
- handler, typename Protocol::socket) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(this->get_implementation(),
- static_cast<boost::asio::io_context*>(0), &peer_endpoint,
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- static_cast<boost::asio::io_context*>(0), &peer_endpoint,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, typename Protocol::socket)>(
+ initiate_async_move_accept(), handler, this,
+ impl_.get_executor(), &peer_endpoint,
+ static_cast<typename Protocol::socket*>(0));
}
/// Accept a new connection.
@@ -1829,7 +1982,7 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
+ * @param ex The I/O executor object to be used for the newly accepted
* socket.
*
* @param peer_endpoint An endpoint object into which the endpoint of the
@@ -1841,20 +1994,25 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
* boost::asio::ip::tcp::socket socket(
- * acceptor.accept(io_context2, endpoint));
+ * acceptor.accept(my_context2, endpoint));
* @endcode
*/
- typename Protocol::socket accept(
- boost::asio::io_context& io_context, endpoint_type& peer_endpoint)
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const Executor1& ex, endpoint_type& peer_endpoint,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
{
boost::system::error_code ec;
- typename Protocol::socket peer(
- this->get_service().accept(this->get_implementation(),
- &io_context, &peer_endpoint, ec));
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
boost::asio::detail::throw_error(ec, "accept");
return peer;
}
@@ -1868,7 +2026,52 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @returns A socket object representing the newly accepted connection.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint));
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context, endpoint_type& peer_endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ boost::system::error_code ec;
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ boost::asio::detail::throw_error(ec, "accept");
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param ex The I/O executor object to be used for the newly accepted
* socket.
*
* @param peer_endpoint An endpoint object into which the endpoint of the
@@ -1881,22 +2084,79 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
* boost::asio::ip::tcp::socket socket(
- * acceptor.accept(io_context2, endpoint, ec));
+ * acceptor.accept(my_context2, endpoint, ec));
* if (ec)
* {
* // An error occurred.
* }
* @endcode
*/
- typename Protocol::socket accept(boost::asio::io_context& io_context,
- endpoint_type& peer_endpoint, boost::system::error_code& ec)
+ template <typename Executor1>
+ typename Protocol::socket::template rebind_executor<Executor1>::other
+ accept(const executor_type& ex,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
{
- return this->get_service().accept(this->get_implementation(),
- &io_context, &peer_endpoint, ec);
+ typename Protocol::socket::template
+ rebind_executor<Executor1>::other peer(ex);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
+ }
+
+ /// Accept a new connection.
+ /**
+ * This function is used to accept a new connection from a peer. The function
+ * call will block until a new connection has been accepted successfully or
+ * an error occurs.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns On success, a socket object representing the newly accepted
+ * connection. On error, a socket object where is_open() is false.
+ *
+ * @par Example
+ * @code
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * boost::asio::ip::tcp::socket socket(
+ * acceptor.accept(my_context2, endpoint, ec));
+ * if (ec)
+ * {
+ * // An error occurred.
+ * }
+ * @endcode
+ */
+ template <typename ExecutionContext>
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other
+ accept(ExecutionContext& context,
+ endpoint_type& peer_endpoint, boost::system::error_code& ec,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other peer(context);
+ impl_.get_service().accept(impl_.get_implementation(),
+ peer, &peer_endpoint, ec);
+ return peer;
}
/// Start an asynchronous accept.
@@ -1907,7 +2167,7 @@ public:
* This overload requires that the Protocol template parameter satisfy the
* AcceptableProtocol type requirements.
*
- * @param io_context The io_context object to be used for the newly accepted
+ * @param ex The I/O executor object to be used for the newly accepted
* socket.
*
* @param peer_endpoint An endpoint object into which the endpoint of the
@@ -1920,12 +2180,13 @@ public:
* signature of the handler must be:
* @code void handler(
* const boost::system::error_code& error, // Result of operation.
- * typename Protocol::socket peer // On success, the newly accepted socket.
+ * typename Protocol::socket::template rebind_executor<
+ * Executor1>::other peer // On success, the newly accepted socket.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -1940,40 +2201,175 @@ public:
*
* ...
*
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::ip::tcp::endpoint endpoint;
- * acceptor.async_accept(io_context2, endpoint, accept_handler);
+ * acceptor.async_accept(my_context2, endpoint, accept_handler);
* @endcode
*/
- template <typename MoveAcceptHandler>
+ template <typename Executor1, typename MoveAcceptHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket))
- async_accept(boost::asio::io_context& io_context,
- endpoint_type& peer_endpoint,
- BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a MoveAcceptHandler.
- BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler,
- handler, typename Protocol::socket) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_accept(
- this->get_implementation(), &io_context, &peer_endpoint,
- BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<MoveAcceptHandler,
void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- this->get_service().async_accept(this->get_implementation(),
- &io_context, &peer_endpoint, init.completion_handler);
+ typename Protocol::socket::template rebind_executor<
+ Executor1>::other))
+ async_accept(const Executor1& ex, endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_executor<Executor1>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ Executor1>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ ex, &peer_endpoint,
+ static_cast<other_socket_type*>(0));
+ }
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ /// Start an asynchronous accept.
+ /**
+ * This function is used to asynchronously accept a new connection. The
+ * function call always returns immediately.
+ *
+ * This overload requires that the Protocol template parameter satisfy the
+ * AcceptableProtocol type requirements.
+ *
+ * @param context The I/O execution context object to be used for the newly
+ * accepted socket.
+ *
+ * @param peer_endpoint An endpoint object into which the endpoint of the
+ * remote peer will be written. Ownership of the peer_endpoint object is
+ * retained by the caller, which must guarantee that it is valid until the
+ * handler is called.
+ *
+ * @param handler The handler to be called when the accept operation
+ * completes. Copies will be made of the handler as required. The function
+ * signature of the handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ * typename Protocol::socket::template rebind_executor<
+ * typename ExecutionContext::executor_type>::other peer
+ * // On success, the newly accepted socket.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @par Example
+ * @code
+ * void accept_handler(const boost::system::error_code& error,
+ * boost::asio::ip::tcp::socket peer)
+ * {
+ * if (!error)
+ * {
+ * // Accept succeeded.
+ * }
+ * }
+ *
+ * ...
+ *
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
+ * ...
+ * boost::asio::ip::tcp::endpoint endpoint;
+ * acceptor.async_accept(my_context2, endpoint, accept_handler);
+ * @endcode
+ */
+ template <typename ExecutionContext, typename MoveAcceptHandler>
+ BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
+ void (boost::system::error_code,
+ typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other))
+ async_accept(ExecutionContext& context,
+ endpoint_type& peer_endpoint,
+ BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ typedef typename Protocol::socket::template rebind_executor<
+ typename ExecutionContext::executor_type>::other other_socket_type;
+
+ return async_initiate<MoveAcceptHandler,
+ void (boost::system::error_code, other_socket_type)>(
+ initiate_async_move_accept(), handler, this,
+ context.get_executor(), &peer_endpoint,
+ static_cast<other_socket_type*>(0));
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+private:
+ // Disallow copying and assignment.
+ basic_socket_acceptor(const basic_socket_acceptor&) BOOST_ASIO_DELETED;
+ basic_socket_acceptor& operator=(
+ const basic_socket_acceptor&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_socket_acceptor* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_accept
+ {
+ template <typename AcceptHandler, typename Protocol1, typename Executor1>
+ void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
+ basic_socket_acceptor* self, basic_socket<Protocol1, Executor1>* peer,
+ endpoint_type* peer_endpoint) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a AcceptHandler.
+ BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check;
+
+ detail::non_const_lvalue<AcceptHandler> handler2(handler);
+ self->impl_.get_service().async_accept(
+ self->impl_.get_implementation(), *peer, peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_move_accept
+ {
+ template <typename MoveAcceptHandler, typename Executor1, typename Socket>
+ void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler,
+ basic_socket_acceptor* self, const Executor1& peer_ex,
+ endpoint_type* peer_endpoint, Socket*) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a MoveAcceptHandler.
+ BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(
+ MoveAcceptHandler, handler, Socket) type_check;
+
+ detail::non_const_lvalue<MoveAcceptHandler> handler2(handler);
+ self->impl_.get_service().async_move_accept(
+ self->impl_.get_implementation(), peer_ex, peer_endpoint,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ detail::io_object_impl<
+ detail::null_socket_service<Protocol>, Executor> impl_;
+#elif defined(BOOST_ASIO_HAS_IOCP)
+ detail::io_object_impl<
+ detail::win_iocp_socket_service<Protocol>, Executor> impl_;
+#else
+ detail::io_object_impl<
+ detail::reactive_socket_service<Protocol>, Executor> impl_;
+#endif
};
} // namespace asio
@@ -1981,8 +2377,4 @@ public:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_HPP
diff --git a/boost/asio/basic_socket_iostream.hpp b/boost/asio/basic_socket_iostream.hpp
index 7a7cab9c93..b6d449d669 100644
--- a/boost/asio/basic_socket_iostream.hpp
+++ b/boost/asio/basic_socket_iostream.hpp
@@ -2,7 +2,7 @@
// basic_socket_iostream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,10 +23,6 @@
#include <ostream>
#include <boost/asio/basic_socket_streambuf.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/stream_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# include <boost/asio/detail/variadic_templates.hpp>
@@ -36,8 +32,7 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>(
// &this->detail::socket_iostream_base<
-// Protocol BOOST_ASIO_SVC_TARG, Clock,
-// WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+// Protocol, Clock, WaitTraits>::streambuf_)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit);
@@ -49,8 +44,7 @@
explicit basic_socket_iostream(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \
- Protocol BOOST_ASIO_SVC_TARG, Clock, \
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_) \
+ Protocol, Clock, WaitTraits>::streambuf_) \
{ \
this->setf(std::ios_base::unitbuf); \
if (rdbuf()->connect(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
@@ -86,8 +80,7 @@ namespace detail {
// A separate base class is used to ensure that the streambuf is initialised
// prior to the basic_socket_iostream's basic_iostream base class.
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+template <typename Protocol, typename Clock, typename WaitTraits>
class socket_iostream_base
{
protected:
@@ -113,8 +106,7 @@ protected:
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
- basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
- Clock, WaitTraits BOOST_ASIO_SVC_TARG1> streambuf_;
+ basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
};
} // namespace detail
@@ -123,18 +115,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments.
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
- typename WaitTraits = time_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = time_traits<Clock> >
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
- typename WaitTraits = wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+ typename WaitTraits = wait_traits<Clock> >
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_iostream;
@@ -147,12 +136,10 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream
- : private detail::socket_iostream_base<Protocol
- BOOST_ASIO_SVC_TARG, Clock, WaitTraits BOOST_ASIO_SVC_TARG1>,
+ : private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
public std::basic_iostream<char>
{
private:
@@ -202,8 +189,7 @@ public:
basic_socket_iostream()
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+ Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@@ -212,12 +198,10 @@ public:
/// Construct a basic_socket_iostream from the supplied socket.
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
: detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(s)),
+ Protocol, Clock, WaitTraits>(std::move(s)),
std::basic_iostream<char>(
&this->detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+ Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@@ -227,13 +211,11 @@ public:
/// Move-construct a basic_socket_iostream from another.
basic_socket_iostream(basic_socket_iostream&& other)
: detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>(std::move(other)),
+ Protocol, Clock, WaitTraits>(std::move(other)),
std::basic_iostream<char>(std::move(other))
{
this->set_rdbuf(&this->detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+ Protocol, Clock, WaitTraits>::streambuf_);
}
/// Move-assign a basic_socket_iostream from another.
@@ -241,8 +223,7 @@ public:
{
std::basic_iostream<char>::operator=(std::move(other));
detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::operator=(std::move(other));
+ Protocol, Clock, WaitTraits>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_STD_IOSTREAM_MOVE)
@@ -263,8 +244,7 @@ public:
explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_)
+ Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0)
@@ -302,18 +282,15 @@ public:
}
/// Return a pointer to the underlying streambuf.
- basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
- Clock, WaitTraits BOOST_ASIO_SVC_TARG1>* rdbuf() const
+ basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
{
- return const_cast<basic_socket_streambuf<Protocol BOOST_ASIO_SVC_TARG,
- Clock, WaitTraits BOOST_ASIO_SVC_TARG1>*>(
+ return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
&this->detail::socket_iostream_base<
- Protocol BOOST_ASIO_SVC_TARG, Clock,
- WaitTraits BOOST_ASIO_SVC_TARG1>::streambuf_);
+ Protocol, Clock, WaitTraits>::streambuf_);
}
/// Get a reference to the underlying socket.
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+ basic_socket<Protocol>& socket()
{
return rdbuf()->socket();
}
diff --git a/boost/asio/basic_socket_streambuf.hpp b/boost/asio/basic_socket_streambuf.hpp
index 0a2bbe56a6..99106020e7 100644
--- a/boost/asio/basic_socket_streambuf.hpp
+++ b/boost/asio/basic_socket_streambuf.hpp
@@ -2,7 +2,7 @@
// basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,17 +28,9 @@
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/io_context.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/stream_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
-# if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/deadline_timer_service.hpp>
-# else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/detail/deadline_timer_service.hpp>
-# endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+# include <boost/asio/detail/deadline_timer_service.hpp>
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# include <boost/asio/steady_timer.hpp>
@@ -55,7 +47,7 @@
// {
// init_buffers();
// typedef typename Protocol::resolver resolver_type;
-// resolver_type resolver(socket().get_executor().context());
+// resolver_type resolver(socket().get_executor());
// connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
@@ -68,7 +60,7 @@
{ \
init_buffers(); \
typedef typename Protocol::resolver resolver_type; \
- resolver_type resolver(socket().get_executor().context()); \
+ resolver_type resolver(socket().get_executor()); \
connect_to_endpoints( \
resolver.resolve(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
@@ -77,10 +69,6 @@
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# define BOOST_ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -125,18 +113,15 @@ protected:
#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments.
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
&& defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
- typename WaitTraits = time_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = time_traits<Clock> >
#else // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
- typename WaitTraits = wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+ typename WaitTraits = wait_traits<Clock> >
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
// && defined(BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_streambuf;
@@ -149,17 +134,16 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM1>
+template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf
: public std::streambuf,
private detail::socket_streambuf_io_context,
private detail::socket_streambuf_buffers,
#if defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- private basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ private basic_socket<Protocol>
#else // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
- public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ public basic_socket<Protocol>
#endif // defined(BOOST_ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
private:
@@ -208,7 +192,7 @@ public:
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: detail::socket_streambuf_io_context(new io_context),
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>(*default_io_context_),
+ basic_socket<Protocol>(*default_io_context_),
expiry_time_(max_expiry_time())
{
init_buffers();
@@ -218,7 +202,7 @@ public:
/// Construct a basic_socket_streambuf from the supplied socket.
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
: detail::socket_streambuf_io_context(0),
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(s)),
+ basic_socket<Protocol>(std::move(s)),
expiry_time_(max_expiry_time())
{
init_buffers();
@@ -227,7 +211,7 @@ public:
/// Move-construct a basic_socket_streambuf from another.
basic_socket_streambuf(basic_socket_streambuf&& other)
: detail::socket_streambuf_io_context(other),
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other.socket())),
+ basic_socket<Protocol>(std::move(other.socket())),
ec_(other.ec_),
expiry_time_(other.expiry_time_)
{
@@ -300,7 +284,7 @@ public:
{
init_buffers();
typedef typename Protocol::resolver resolver_type;
- resolver_type resolver(socket().get_executor().context());
+ resolver_type resolver(socket().get_executor());
connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0;
}
@@ -323,7 +307,7 @@ public:
}
/// Get a reference to the underlying socket.
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket()
+ basic_socket<Protocol>& socket()
{
return *this;
}
@@ -696,10 +680,6 @@ private:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T1
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
# undef BOOST_ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
diff --git a/boost/asio/basic_stream_socket.hpp b/boost/asio/basic_stream_socket.hpp
index 9732c3c303..18d9daca50 100644
--- a/boost/asio/basic_stream_socket.hpp
+++ b/boost/asio/basic_stream_socket.hpp
@@ -2,7 +2,7 @@
// basic_stream_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -20,18 +20,24 @@
#include <boost/asio/async_result.hpp>
#include <boost/asio/basic_socket.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/stream_socket_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
+#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
+class basic_stream_socket;
+
+#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
+
/// Provides stream-oriented socket functionality.
/**
* The basic_stream_socket class template provides asynchronous and blocking
@@ -44,18 +50,28 @@ namespace asio {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
+template <typename Protocol, typename Executor>
class basic_stream_socket
- : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
+ : public basic_socket<Protocol, Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// Rebinds the socket type to another executor.
+ template <typename Executor1>
+ struct rebind_executor
+ {
+ /// The socket type when rebound to the specified executor.
+ typedef basic_stream_socket<Protocol, Executor1> other;
+ };
+
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
- typedef typename basic_socket<
- Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
+ typedef typename basic_socket<Protocol,
+ Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -70,11 +86,30 @@ public:
* needs to be opened and then connected or accepted before data can be sent
* or received on it.
*
- * @param io_context The io_context object that the stream socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
- explicit basic_stream_socket(boost::asio::io_context& io_context)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
+ explicit basic_stream_socket(const executor_type& ex)
+ : basic_socket<Protocol, Executor>(ex)
+ {
+ }
+
+ /// Construct a basic_stream_socket without opening it.
+ /**
+ * This constructor creates a stream socket without opening it. The socket
+ * needs to be opened and then connected or accepted before data can be sent
+ * or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ */
+ template <typename ExecutionContext>
+ explicit basic_stream_socket(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context)
{
}
@@ -83,16 +118,37 @@ public:
* This constructor creates and opens a stream socket. The socket needs to be
* connected or accepted before data can be sent or received on it.
*
- * @param io_context The io_context object that the stream socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_context& io_context,
- const protocol_type& protocol)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
+ basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
+ : basic_socket<Protocol, Executor>(ex, protocol)
+ {
+ }
+
+ /// Construct and open a basic_stream_socket.
+ /**
+ * This constructor creates and opens a stream socket. The socket needs to be
+ * connected or accepted before data can be sent or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -103,7 +159,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
- * @param io_context The io_context object that the stream socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the stream
@@ -111,9 +167,33 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_context& io_context,
- const endpoint_type& endpoint)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
+ basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
+ : basic_socket<Protocol, Executor>(ex, endpoint)
+ {
+ }
+
+ /// Construct a basic_stream_socket, opening it and binding it to the given
+ /// local endpoint.
+ /**
+ * This constructor creates a stream socket and automatically opens it bound
+ * to the specified endpoint on the local machine. The protocol used is the
+ * protocol associated with the given endpoint.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param endpoint An endpoint on the local machine to which the stream
+ * socket will be bound.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -122,7 +202,7 @@ public:
* This constructor creates a stream socket object to hold an existing native
* socket.
*
- * @param io_context The io_context object that the stream socket will use to
+ * @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
@@ -131,10 +211,34 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_socket(boost::asio::io_context& io_context,
+ basic_stream_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
- io_context, protocol, native_socket)
+ : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
+ {
+ }
+
+ /// Construct a basic_stream_socket on an existing native socket.
+ /**
+ * This constructor creates a stream socket object to hold an existing native
+ * socket.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the socket will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the socket.
+ *
+ * @param protocol An object specifying protocol parameters to be used.
+ *
+ * @param native_socket The new underlying socket implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_socket(ExecutionContext& context,
+ const protocol_type& protocol, const native_handle_type& native_socket,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -147,10 +251,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_context&) constructor.
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
*/
basic_stream_socket(basic_stream_socket&& other)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -162,11 +267,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_context&) constructor.
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
*/
basic_stream_socket& operator=(basic_stream_socket&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -179,13 +285,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_context&) constructor.
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- basic_stream_socket(
- basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
- typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
- : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
+ template <typename Protocol1, typename Executor1>
+ basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value
+ >::type* = 0)
+ : basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -197,14 +306,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_socket(io_context&) constructor.
+ * constructed using the @c basic_stream_socket(const executor_type&)
+ * constructor.
*/
- template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
- typename enable_if<is_convertible<Protocol1, Protocol>::value,
- basic_stream_socket>::type& operator=(
- basic_stream_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
+ template <typename Protocol1, typename Executor1>
+ typename enable_if<
+ is_convertible<Protocol1, Protocol>::value
+ && is_convertible<Executor1, Executor>::value,
+ basic_stream_socket&
+ >::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)
{
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
+ basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -247,8 +359,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -285,8 +397,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "send");
return s;
}
@@ -313,8 +425,8 @@ public:
std::size_t send(const ConstBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().send(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous send.
@@ -335,9 +447,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -358,24 +470,10 @@ public:
async_send(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(
- this->get_implementation(), buffers, 0,
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(
- this->get_implementation(), buffers, 0,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -398,9 +496,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -422,24 +520,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(
- this->get_implementation(), buffers, flags,
- BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(
- this->get_implementation(), buffers, flags,
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@@ -474,8 +557,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -515,8 +598,8 @@ public:
socket_base::message_flags flags)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
boost::asio::detail::throw_error(ec, "receive");
return s;
}
@@ -543,8 +626,8 @@ public:
std::size_t receive(const MutableBufferSequence& buffers,
socket_base::message_flags flags, boost::system::error_code& ec)
{
- return this->get_service().receive(
- this->get_implementation(), buffers, flags, ec);
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, flags, ec);
}
/// Start an asynchronous receive.
@@ -565,9 +648,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -590,22 +673,10 @@ public:
async_receive(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -628,9 +699,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -654,22 +725,9 @@ public:
socket_base::message_flags flags,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, flags, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this, buffers, flags);
}
/// Write some data to the socket.
@@ -703,8 +761,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().send(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@@ -729,7 +787,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().send(this->get_implementation(), buffers, 0, ec);
+ return this->impl_.get_service().send(
+ this->impl_.get_implementation(), buffers, 0, ec);
}
/// Start an asynchronous write.
@@ -750,9 +809,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -773,22 +832,10 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_send(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_send(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_send(), handler, this,
+ buffers, socket_base::message_flags(0));
}
/// Read some data from the socket.
@@ -823,8 +870,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().receive(
- this->get_implementation(), buffers, 0, ec);
+ std::size_t s = this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@@ -850,8 +897,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().receive(
- this->get_implementation(), buffers, 0, ec);
+ return this->impl_.get_service().receive(
+ this->impl_.get_implementation(), buffers, 0, ec);
}
/// Start an asynchronous read.
@@ -872,9 +919,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -896,23 +943,48 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_receive(this->get_implementation(),
- buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_receive(this->get_implementation(),
- buffers, 0, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_receive(), handler, this,
+ buffers, socket_base::message_flags(0));
}
+
+private:
+ struct initiate_async_send
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_stream_socket* self, const ConstBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_send(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_receive
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_stream_socket* self, const MutableBufferSequence& buffers,
+ socket_base::message_flags flags) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_receive(
+ self->impl_.get_implementation(), buffers, flags,
+ handler2.value, self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace asio
diff --git a/boost/asio/basic_streambuf.hpp b/boost/asio/basic_streambuf.hpp
index e6f8f33f6b..e2e9bf9071 100644
--- a/boost/asio/basic_streambuf.hpp
+++ b/boost/asio/basic_streambuf.hpp
@@ -2,7 +2,7 @@
// basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/basic_streambuf_fwd.hpp b/boost/asio/basic_streambuf_fwd.hpp
index f2ef522d9b..68907ef282 100644
--- a/boost/asio/basic_streambuf_fwd.hpp
+++ b/boost/asio/basic_streambuf_fwd.hpp
@@ -2,7 +2,7 @@
// basic_streambuf_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/basic_waitable_timer.hpp b/boost/asio/basic_waitable_timer.hpp
index 6dc4bded98..45373f7caf 100644
--- a/boost/asio/basic_waitable_timer.hpp
+++ b/boost/asio/basic_waitable_timer.hpp
@@ -2,7 +2,7 @@
// basic_waitable_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,26 +17,20 @@
#include <boost/asio/detail/config.hpp>
#include <cstddef>
-#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/detail/chrono_time_traits.hpp>
+#include <boost/asio/detail/deadline_timer_service.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/wait_traits.hpp>
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/waitable_timer_service.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/detail/chrono_time_traits.hpp>
-# include <boost/asio/detail/deadline_timer_service.hpp>
-# define BOOST_ASIO_SVC_T \
- detail::deadline_timer_service< \
- detail::chrono_time_traits<Clock, WaitTraits> >
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -47,8 +41,8 @@ namespace asio {
// Forward declaration with defaulted arguments.
template <typename Clock,
- typename WaitTraits = boost::asio::wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = boost::asio::wait_traits<Clock>,
+ typename Executor = executor>
class basic_waitable_timer;
#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@@ -76,7 +70,7 @@ class basic_waitable_timer;
* Performing a blocking wait (C++11):
* @code
* // Construct a timer without setting an expiry time.
- * boost::asio::steady_timer timer(io_context);
+ * boost::asio::steady_timer timer(my_context);
*
* // Set an expiry time relative to now.
* timer.expires_after(std::chrono::seconds(5));
@@ -99,7 +93,7 @@ class basic_waitable_timer;
* ...
*
* // Construct a timer with an absolute expiry time.
- * boost::asio::steady_timer timer(io_context,
+ * boost::asio::steady_timer timer(my_context,
* std::chrono::steady_clock::now() + std::chrono::seconds(60));
*
* // Start an asynchronous wait.
@@ -145,13 +139,12 @@ class basic_waitable_timer;
* @li If a wait handler is cancelled, the boost::system::error_code passed to
* it contains the value boost::asio::error::operation_aborted.
*/
-template <typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM>
+template <typename Clock, typename WaitTraits, typename Executor>
class basic_waitable_timer
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
+ typedef Executor executor_type;
/// The clock type.
typedef Clock clock_type;
@@ -171,11 +164,30 @@ public:
* expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param ex The I/O executor that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
+ */
+ explicit basic_waitable_timer(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Constructor.
+ /**
+ * This constructor creates a timer without setting an expiry time. The
+ * expires_at() or expires_after() functions must be called to set an expiry
+ * time before the timer can be waited on.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
*/
- explicit basic_waitable_timer(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_waitable_timer(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -183,38 +195,85 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param ex The I/O executor object that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
- basic_waitable_timer(boost::asio::io_context& io_context,
- const time_point& expiry_time)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
+ : impl_(ex)
{
boost::system::error_code ec;
- this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
+ impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
}
+ /// Constructor to set a particular expiry time as an absolute time.
+ /**
+ * This constructor creates a timer and sets the expiry time.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
+ *
+ * @param expiry_time The expiry time to be used for the timer, expressed
+ * as an absolute time.
+ */
+ template <typename ExecutionContext>
+ explicit basic_waitable_timer(ExecutionContext& context,
+ const time_point& expiry_time,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_at");
+ }
+
+ /// Constructor to set a particular expiry time relative to now.
+ /**
+ * This constructor creates a timer and sets the expiry time.
+ *
+ * @param ex The I/O executor that the timer will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the timer.
+ *
+ * @param expiry_time The expiry time to be used for the timer, relative to
+ * now.
+ */
+ basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().expires_after(
+ impl_.get_implementation(), expiry_time, ec);
+ boost::asio::detail::throw_error(ec, "expires_after");
+ }
+
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
- * @param io_context The io_context object that the timer will use to dispatch
- * handlers for any asynchronous operations performed on the timer.
+ * @param context An execution context which provides the I/O executor that
+ * the timer will use, by default, to dispatch handlers for any asynchronous
+ * operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
- basic_waitable_timer(boost::asio::io_context& io_context,
- const duration& expiry_time)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_waitable_timer(ExecutionContext& context,
+ const duration& expiry_time,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().expires_after(
- this->get_implementation(), expiry_time, ec);
+ impl_.get_service().expires_after(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after");
}
@@ -227,10 +286,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_waitable_timer(io_context&) constructor.
+ * constructed using the @c basic_waitable_timer(const executor_type&)
+ * constructor.
*/
basic_waitable_timer(basic_waitable_timer&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -243,11 +303,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_waitable_timer(io_context&) constructor.
+ * constructed using the @c basic_waitable_timer(const executor_type&)
+ * constructor.
*/
basic_waitable_timer& operator=(basic_waitable_timer&& other)
{
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -261,45 +322,11 @@ public:
{
}
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ return impl_.get_executor();
}
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer.
/**
@@ -326,7 +353,7 @@ public:
std::size_t cancel()
{
boost::system::error_code ec;
- std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
+ std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
return s;
}
@@ -357,7 +384,7 @@ public:
*/
std::size_t cancel(boost::system::error_code& ec)
{
- return this->get_service().cancel(this->get_implementation(), ec);
+ return impl_.get_service().cancel(impl_.get_implementation(), ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -388,8 +415,8 @@ public:
std::size_t cancel_one()
{
boost::system::error_code ec;
- std::size_t s = this->get_service().cancel_one(
- this->get_implementation(), ec);
+ std::size_t s = impl_.get_service().cancel_one(
+ impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel_one");
return s;
}
@@ -422,7 +449,7 @@ public:
*/
std::size_t cancel_one(boost::system::error_code& ec)
{
- return this->get_service().cancel_one(this->get_implementation(), ec);
+ return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
}
/// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
@@ -433,7 +460,7 @@ public:
*/
time_point expires_at() const
{
- return this->get_service().expires_at(this->get_implementation());
+ return impl_.get_service().expires_at(impl_.get_implementation());
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -444,7 +471,7 @@ public:
*/
time_point expiry() const
{
- return this->get_service().expiry(this->get_implementation());
+ return impl_.get_service().expiry(impl_.get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -472,8 +499,8 @@ public:
std::size_t expires_at(const time_point& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().expires_at(
- this->get_implementation(), expiry_time, ec);
+ std::size_t s = impl_.get_service().expires_at(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_at");
return s;
}
@@ -505,8 +532,8 @@ public:
std::size_t expires_at(const time_point& expiry_time,
boost::system::error_code& ec)
{
- return this->get_service().expires_at(
- this->get_implementation(), expiry_time, ec);
+ return impl_.get_service().expires_at(
+ impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -535,8 +562,8 @@ public:
std::size_t expires_after(const duration& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().expires_after(
- this->get_implementation(), expiry_time, ec);
+ std::size_t s = impl_.get_service().expires_after(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_after");
return s;
}
@@ -549,7 +576,7 @@ public:
*/
duration expires_from_now() const
{
- return this->get_service().expires_from_now(this->get_implementation());
+ return impl_.get_service().expires_from_now(impl_.get_implementation());
}
/// (Deprecated: Use expires_after().) Set the timer's expiry time relative
@@ -578,8 +605,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().expires_from_now(
- this->get_implementation(), expiry_time, ec);
+ std::size_t s = impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
boost::asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@@ -610,8 +637,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time,
boost::system::error_code& ec)
{
- return this->get_service().expires_from_now(
- this->get_implementation(), expiry_time, ec);
+ return impl_.get_service().expires_from_now(
+ impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -625,7 +652,7 @@ public:
void wait()
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -638,7 +665,7 @@ public:
*/
void wait(boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -661,31 +688,17 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_wait(this->get_implementation(),
- BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this);
}
private:
@@ -693,6 +706,28 @@ private:
basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED;
basic_waitable_timer& operator=(
const basic_waitable_timer&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_waitable_timer* self) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ detail::io_object_impl<
+ detail::deadline_timer_service<
+ detail::chrono_time_traits<Clock, WaitTraits> >,
+ executor_type > impl_;
};
} // namespace asio
@@ -700,8 +735,4 @@ private:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
diff --git a/boost/asio/bind_executor.hpp b/boost/asio/bind_executor.hpp
index c4086b6135..cd1498098c 100644
--- a/boost/asio/bind_executor.hpp
+++ b/boost/asio/bind_executor.hpp
@@ -2,7 +2,7 @@
// bind_executor.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -548,37 +548,6 @@ private:
async_result<T, Signature> target_;
};
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-
-template <typename T, typename Executor, typename Signature>
-struct handler_type<executor_binder<T, Executor>, Signature>
-{
- typedef executor_binder<
- typename handler_type<T, Signature>::type, Executor> type;
-};
-
-template <typename T, typename Executor>
-class async_result<executor_binder<T, Executor> >
-{
-public:
- typedef typename async_result<T>::type type;
-
- explicit async_result(executor_binder<T, Executor>& b)
- : target_(b.get())
- {
- }
-
- type get()
- {
- return target_.get();
- }
-
-private:
- async_result<T> target_;
-};
-
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
template <typename T, typename Executor, typename Allocator>
struct associated_allocator<executor_binder<T, Executor>, Allocator>
{
diff --git a/boost/asio/buffer.hpp b/boost/asio/buffer.hpp
index 29352f6481..6958b2e84a 100644
--- a/boost/asio/buffer.hpp
+++ b/boost/asio/buffer.hpp
@@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,6 +23,7 @@
#include <string>
#include <vector>
#include <boost/asio/detail/array_fwd.hpp>
+#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/throw_exception.hpp>
#include <boost/asio/detail/type_traits.hpp>
@@ -382,29 +383,45 @@ private:
/*@{*/
/// Get an iterator to the first element in a buffer sequence.
-inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b)
+template <typename MutableBuffer>
+inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
+ typename enable_if<
+ is_convertible<const MutableBuffer*, const mutable_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
- return &b;
+ return static_cast<const mutable_buffer*>(detail::addressof(b));
}
/// Get an iterator to the first element in a buffer sequence.
-inline const const_buffer* buffer_sequence_begin(const const_buffer& b)
+template <typename ConstBuffer>
+inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
+ typename enable_if<
+ is_convertible<const ConstBuffer*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
- return &b;
+ return static_cast<const const_buffer*>(detail::addressof(b));
}
#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to the first element in a buffer sequence.
template <typename C>
-inline auto buffer_sequence_begin(C& c) -> decltype(c.begin())
+inline auto buffer_sequence_begin(C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
{
return c.begin();
}
/// Get an iterator to the first element in a buffer sequence.
template <typename C>
-inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
+inline auto buffer_sequence_begin(const C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.begin())
{
return c.begin();
}
@@ -412,13 +429,21 @@ inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C>
-inline typename C::iterator buffer_sequence_begin(C& c)
+inline typename C::iterator buffer_sequence_begin(C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
return c.begin();
}
template <typename C>
-inline typename C::const_iterator buffer_sequence_begin(const C& c)
+inline typename C::const_iterator buffer_sequence_begin(const C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
return c.begin();
}
@@ -435,29 +460,45 @@ inline typename C::const_iterator buffer_sequence_begin(const C& c)
/*@{*/
/// Get an iterator to one past the end element in a buffer sequence.
-inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b)
+template <typename MutableBuffer>
+inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
+ typename enable_if<
+ is_convertible<const MutableBuffer*, const mutable_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
- return &b + 1;
+ return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
}
/// Get an iterator to one past the end element in a buffer sequence.
-inline const const_buffer* buffer_sequence_end(const const_buffer& b)
+template <typename ConstBuffer>
+inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
+ typename enable_if<
+ is_convertible<const ConstBuffer*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
- return &b + 1;
+ return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
}
#if defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
-inline auto buffer_sequence_end(C& c) -> decltype(c.end())
+inline auto buffer_sequence_end(C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
{
return c.end();
}
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
-inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
+inline auto buffer_sequence_end(const C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT -> decltype(c.end())
{
return c.end();
}
@@ -465,13 +506,21 @@ inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
#else // defined(BOOST_ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C>
-inline typename C::iterator buffer_sequence_end(C& c)
+inline typename C::iterator buffer_sequence_end(C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
return c.end();
}
template <typename C>
-inline typename C::const_iterator buffer_sequence_end(const C& c)
+inline typename C::const_iterator buffer_sequence_end(const C& c,
+ typename enable_if<
+ !is_convertible<const C*, const mutable_buffer*>::value
+ && !is_convertible<const C*, const const_buffer*>::value
+ >::type* = 0) BOOST_ASIO_NOEXCEPT
{
return c.end();
}
@@ -1498,19 +1547,23 @@ template <typename Elem, typename Traits, typename Allocator>
class dynamic_string_buffer
{
public:
- /// The type used to represent the input sequence as a list of buffers.
+ /// The type used to represent a sequence of constant buffers that refers to
+ /// the underlying memory.
typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
- /// The type used to represent the output sequence as a list of buffers.
+ /// The type used to represent a sequence of mutable buffers that refers to
+ /// the underlying memory.
typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
/// Construct a dynamic buffer from a string.
/**
* @param s The string to be used as backing storage for the dynamic buffer.
- * Any existing data in the string is treated as the dynamic buffer's input
- * sequence. The object stores a reference to the string and the user is
- * responsible for ensuring that the string object remains valid until the
- * dynamic_string_buffer object is destroyed.
+ * The object stores a reference to the string and the user is responsible
+ * for ensuring that the string object remains valid while the
+ * dynamic_string_buffer object, and copies of the object, are in use.
+ *
+ * @b DynamicBuffer_v1: Any existing data in the string is treated as the
+ * dynamic buffer's input sequence.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@@ -1518,64 +1571,131 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: string_(s),
- size_(string_.size()),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ size_((std::numeric_limits<std::size_t>::max)()),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size)
{
}
+ /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
+ dynamic_string_buffer(const dynamic_string_buffer& other) BOOST_ASIO_NOEXCEPT
+ : string_(other.string_),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ size_(other.size_),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ max_size_(other.max_size_)
+ {
+ }
+
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer.
dynamic_string_buffer(dynamic_string_buffer&& other) BOOST_ASIO_NOEXCEPT
: string_(other.string_),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Get the size of the input sequence.
+ /// @b DynamicBuffer_v1: Get the size of the input sequence.
+ /// @b DynamicBuffer_v2: Get the current size of the underlying memory.
+ /**
+ * @returns @b DynamicBuffer_v1 The current size of the input sequence.
+ * @b DynamicBuffer_v2: The current size of the underlying string if less than
+ * max_size(). Otherwise returns max_size().
+ */
std::size_t size() const BOOST_ASIO_NOEXCEPT
{
- return size_;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ if (size_ != (std::numeric_limits<std::size_t>::max)())
+ return size_;
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ return (std::min)(string_.size(), max_size());
}
/// Get the maximum size of the dynamic buffer.
/**
- * @returns The allowed maximum of the sum of the sizes of the input sequence
- * and output sequence.
+ * @returns The allowed maximum size of the underlying memory.
*/
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
return max_size_;
}
- /// Get the current capacity of the dynamic buffer.
+ /// Get the maximum size that the buffer may grow to without triggering
+ /// reallocation.
/**
- * @returns The current total capacity of the buffer, i.e. for both the input
- * sequence and output sequence.
+ * @returns The current capacity of the underlying string if less than
+ * max_size(). Otherwise returns max_size().
*/
std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{
- return string_.capacity();
+ return (std::min)(string_.capacity(), max_size());
}
- /// Get a list of buffers that represents the input sequence.
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ /// @b DynamicBuffer_v1: Get a list of buffers that represents the input
+ /// sequence.
/**
* @returns An object of type @c const_buffers_type that satisfies
* ConstBufferSequence requirements, representing the basic_string memory in
- * input sequence.
+ * the input sequence.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
- * or @c basic_string member function that modifies the input sequence or
- * output sequence.
+ * or @c basic_string member function that resizes or erases the string.
*/
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{
return const_buffers_type(boost::asio::buffer(string_, size_));
}
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
- /// Get a list of buffers that represents the output sequence, with the given
- /// size.
+ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
+ /// underlying memory.
+ /**
+ * @param pos Position of the first byte to represent in the buffer sequence
+ *
+ * @param n The number of bytes to return in the buffer sequence. If the
+ * underlying memory is shorter, the buffer sequence represents as many bytes
+ * as are available.
+ *
+ * @returns An object of type @c mutable_buffers_type that satisfies
+ * MutableBufferSequence requirements, representing the basic_string memory.
+ *
+ * @note The returned object is invalidated by any @c dynamic_string_buffer
+ * or @c basic_string member function that resizes or erases the string.
+ */
+ mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT
+ {
+ return mutable_buffers_type(boost::asio::buffer(
+ boost::asio::buffer(string_, max_size_) + pos, n));
+ }
+
+ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
+ /// underlying memory.
+ /**
+ * @param pos Position of the first byte to represent in the buffer sequence
+ *
+ * @param n The number of bytes to return in the buffer sequence. If the
+ * underlying memory is shorter, the buffer sequence represents as many bytes
+ * as are available.
+ *
+ * @note The returned object is invalidated by any @c dynamic_string_buffer
+ * or @c basic_string member function that resizes or erases the string.
+ */
+ const_buffers_type data(std::size_t pos,
+ std::size_t n) const BOOST_ASIO_NOEXCEPT
+ {
+ return const_buffers_type(boost::asio::buffer(
+ boost::asio::buffer(string_, max_size_) + pos, n));
+ }
+
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ /// @b DynamicBuffer_v1: Get a list of buffers that represents the output
+ /// sequence, with the given size.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* basic_string object as necessary.
@@ -1592,18 +1712,22 @@ public:
*/
mutable_buffers_type prepare(std::size_t n)
{
- if (size () > max_size() || max_size() - size() < n)
+ if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_string_buffer too long");
boost::asio::detail::throw_exception(ex);
}
+ if (size_ == (std::numeric_limits<std::size_t>::max)())
+ size_ = string_.size(); // Enable v1 behaviour.
+
string_.resize(size_ + n);
return boost::asio::buffer(boost::asio::buffer(string_) + size_, n);
}
- /// Move bytes from the output sequence to the input sequence.
+ /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
+ /// sequence.
/**
* @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output
@@ -1620,24 +1744,69 @@ public:
size_ += (std::min)(n, string_.size() - size_);
string_.resize(size_);
}
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
- /// Remove characters from the input sequence.
+ /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
+ /// bytes.
/**
- * Removes @c n characters from the beginning of the input sequence.
+ * Resizes the string to accommodate an additional @c n bytes at the end.
*
- * @note If @c n is greater than the size of the input sequence, the entire
- * input sequence is consumed and no error is issued.
+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+ */
+ void grow(std::size_t n)
+ {
+ if (size() > max_size() || max_size() - size() < n)
+ {
+ std::length_error ex("dynamic_string_buffer too long");
+ boost::asio::detail::throw_exception(ex);
+ }
+
+ string_.resize(size() + n);
+ }
+
+ /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
+ /// of bytes.
+ /**
+ * Erases @c n bytes from the end of the string by resizing the basic_string
+ * object. If @c n is greater than the current size of the string, the string
+ * is emptied.
+ */
+ void shrink(std::size_t n)
+ {
+ string_.resize(n > size() ? 0 : size() - n);
+ }
+
+ /// @b DynamicBuffer_v1: Remove characters from the input sequence.
+ /// @b DynamicBuffer_v2: Consume the specified number of bytes from the
+ /// beginning of the underlying memory.
+ /**
+ * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
+ * input sequence. @note If @c n is greater than the size of the input
+ * sequence, the entire input sequence is consumed and no error is issued.
+ *
+ * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.
+ * If @c n is greater than the current size of the string, the string is
+ * emptied.
*/
void consume(std::size_t n)
{
- std::size_t consume_length = (std::min)(n, size_);
- string_.erase(0, consume_length);
- size_ -= consume_length;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ if (size_ != (std::numeric_limits<std::size_t>::max)())
+ {
+ std::size_t consume_length = (std::min)(n, size_);
+ string_.erase(0, consume_length);
+ size_ -= consume_length;
+ return;
+ }
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ string_.erase(0, n);
}
private:
std::basic_string<Elem, Traits, Allocator>& string_;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@@ -1649,19 +1818,20 @@ template <typename Elem, typename Allocator>
class dynamic_vector_buffer
{
public:
- /// The type used to represent the input sequence as a list of buffers.
+ /// The type used to represent a sequence of constant buffers that refers to
+ /// the underlying memory.
typedef BOOST_ASIO_CONST_BUFFER const_buffers_type;
- /// The type used to represent the output sequence as a list of buffers.
+ /// The type used to represent a sequence of mutable buffers that refers to
+ /// the underlying memory.
typedef BOOST_ASIO_MUTABLE_BUFFER mutable_buffers_type;
- /// Construct a dynamic buffer from a string.
+ /// Construct a dynamic buffer from a vector.
/**
* @param v The vector to be used as backing storage for the dynamic buffer.
- * Any existing data in the vector is treated as the dynamic buffer's input
- * sequence. The object stores a reference to the vector and the user is
- * responsible for ensuring that the vector object remains valid until the
- * dynamic_vector_buffer object is destroyed.
+ * The object stores a reference to the vector and the user is responsible
+ * for ensuring that the vector object remains valid while the
+ * dynamic_vector_buffer object, and copies of the object, are in use.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@@ -1669,77 +1839,149 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) BOOST_ASIO_NOEXCEPT
: vector_(v),
- size_(vector_.size()),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ size_((std::numeric_limits<std::size_t>::max)()),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size)
{
}
+ /// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
+ dynamic_vector_buffer(const dynamic_vector_buffer& other) BOOST_ASIO_NOEXCEPT
+ : vector_(other.vector_),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ size_(other.size_),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ max_size_(other.max_size_)
+ {
+ }
+
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer.
dynamic_vector_buffer(dynamic_vector_buffer&& other) BOOST_ASIO_NOEXCEPT
: vector_(other.vector_),
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Get the size of the input sequence.
+ /// @b DynamicBuffer_v1: Get the size of the input sequence.
+ /// @b DynamicBuffer_v2: Get the current size of the underlying memory.
+ /**
+ * @returns @b DynamicBuffer_v1 The current size of the input sequence.
+ * @b DynamicBuffer_v2: The current size of the underlying vector if less than
+ * max_size(). Otherwise returns max_size().
+ */
std::size_t size() const BOOST_ASIO_NOEXCEPT
{
- return size_;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ if (size_ != (std::numeric_limits<std::size_t>::max)())
+ return size_;
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ return (std::min)(vector_.size(), max_size());
}
/// Get the maximum size of the dynamic buffer.
/**
- * @returns The allowed maximum of the sum of the sizes of the input sequence
- * and output sequence.
+ * @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes
+ * of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed
+ * maximum size of the underlying memory.
*/
std::size_t max_size() const BOOST_ASIO_NOEXCEPT
{
return max_size_;
}
- /// Get the current capacity of the dynamic buffer.
+ /// Get the maximum size that the buffer may grow to without triggering
+ /// reallocation.
/**
- * @returns The current total capacity of the buffer, i.e. for both the input
- * sequence and output sequence.
+ * @returns @b DynamicBuffer_v1: The current total capacity of the buffer,
+ * i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:
+ * The current capacity of the underlying vector if less than max_size().
+ * Otherwise returns max_size().
*/
std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{
- return vector_.capacity();
+ return (std::min)(vector_.capacity(), max_size());
}
- /// Get a list of buffers that represents the input sequence.
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ /// @b DynamicBuffer_v1: Get a list of buffers that represents the input
+ /// sequence.
/**
* @returns An object of type @c const_buffers_type that satisfies
- * ConstBufferSequence requirements, representing the basic_string memory in
+ * ConstBufferSequence requirements, representing the vector memory in the
* input sequence.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
- * or @c basic_string member function that modifies the input sequence or
- * output sequence.
+ * or @c vector member function that modifies the input sequence or output
+ * sequence.
*/
const_buffers_type data() const BOOST_ASIO_NOEXCEPT
{
return const_buffers_type(boost::asio::buffer(vector_, size_));
}
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
- /// Get a list of buffers that represents the output sequence, with the given
- /// size.
+ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
+ /// underlying memory.
+ /**
+ * @param pos Position of the first byte to represent in the buffer sequence
+ *
+ * @param n The number of bytes to return in the buffer sequence. If the
+ * underlying memory is shorter, the buffer sequence represents as many bytes
+ * as are available.
+ *
+ * @returns An object of type @c mutable_buffers_type that satisfies
+ * MutableBufferSequence requirements, representing the vector memory.
+ *
+ * @note The returned object is invalidated by any @c dynamic_vector_buffer
+ * or @c vector member function that resizes or erases the vector.
+ */
+ mutable_buffers_type data(std::size_t pos, std::size_t n) BOOST_ASIO_NOEXCEPT
+ {
+ return mutable_buffers_type(boost::asio::buffer(
+ boost::asio::buffer(vector_, max_size_) + pos, n));
+ }
+
+ /// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
+ /// underlying memory.
+ /**
+ * @param pos Position of the first byte to represent in the buffer sequence
+ *
+ * @param n The number of bytes to return in the buffer sequence. If the
+ * underlying memory is shorter, the buffer sequence represents as many bytes
+ * as are available.
+ *
+ * @note The returned object is invalidated by any @c dynamic_vector_buffer
+ * or @c vector member function that resizes or erases the vector.
+ */
+ const_buffers_type data(std::size_t pos,
+ std::size_t n) const BOOST_ASIO_NOEXCEPT
+ {
+ return const_buffers_type(boost::asio::buffer(
+ boost::asio::buffer(vector_, max_size_) + pos, n));
+ }
+
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ /// @b DynamicBuffer_v1: Get a list of buffers that represents the output
+ /// sequence, with the given size.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
- * basic_string object as necessary.
+ * vector object as necessary.
*
* @returns An object of type @c mutable_buffers_type that satisfies
- * MutableBufferSequence requirements, representing basic_string memory
- * at the start of the output sequence of size @c n.
+ * MutableBufferSequence requirements, representing vector memory at the
+ * start of the output sequence of size @c n.
*
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
- * or @c basic_string member function that modifies the input sequence or
- * output sequence.
+ * or @c vector member function that modifies the input sequence or output
+ * sequence.
*/
mutable_buffers_type prepare(std::size_t n)
{
@@ -1749,12 +1991,16 @@ public:
boost::asio::detail::throw_exception(ex);
}
+ if (size_ == (std::numeric_limits<std::size_t>::max)())
+ size_ = vector_.size(); // Enable v1 behaviour.
+
vector_.resize(size_ + n);
return boost::asio::buffer(boost::asio::buffer(vector_) + size_, n);
}
- /// Move bytes from the output sequence to the input sequence.
+ /// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
+ /// sequence.
/**
* @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output
@@ -1771,24 +2017,69 @@ public:
size_ += (std::min)(n, vector_.size() - size_);
vector_.resize(size_);
}
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
- /// Remove characters from the input sequence.
+ /// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
+ /// bytes.
/**
- * Removes @c n characters from the beginning of the input sequence.
+ * Resizes the vector to accommodate an additional @c n bytes at the end.
*
- * @note If @c n is greater than the size of the input sequence, the entire
- * input sequence is consumed and no error is issued.
+ * @throws std::length_error If <tt>size() + n > max_size()</tt>.
+ */
+ void grow(std::size_t n)
+ {
+ if (size() > max_size() || max_size() - size() < n)
+ {
+ std::length_error ex("dynamic_vector_buffer too long");
+ boost::asio::detail::throw_exception(ex);
+ }
+
+ vector_.resize(size() + n);
+ }
+
+ /// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
+ /// of bytes.
+ /**
+ * Erases @c n bytes from the end of the vector by resizing the vector
+ * object. If @c n is greater than the current size of the vector, the vector
+ * is emptied.
+ */
+ void shrink(std::size_t n)
+ {
+ vector_.resize(n > size() ? 0 : size() - n);
+ }
+
+ /// @b DynamicBuffer_v1: Remove characters from the input sequence.
+ /// @b DynamicBuffer_v2: Consume the specified number of bytes from the
+ /// beginning of the underlying memory.
+ /**
+ * @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
+ * input sequence. @note If @c n is greater than the size of the input
+ * sequence, the entire input sequence is consumed and no error is issued.
+ *
+ * @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.
+ * If @c n is greater than the current size of the vector, the vector is
+ * emptied.
*/
void consume(std::size_t n)
{
- std::size_t consume_length = (std::min)(n, size_);
- vector_.erase(vector_.begin(), vector_.begin() + consume_length);
- size_ -= consume_length;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ if (size_ != (std::numeric_limits<std::size_t>::max)())
+ {
+ std::size_t consume_length = (std::min)(n, size_);
+ vector_.erase(vector_.begin(), vector_.begin() + consume_length);
+ size_ -= consume_length;
+ return;
+ }
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));
}
private:
std::vector<Elem, Allocator>& vector_;
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@@ -2154,17 +2445,51 @@ struct is_const_buffer_sequence
{
};
-/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+/// Trait to determine whether a type satisfies the DynamicBuffer_v1
+/// requirements.
template <typename T>
-struct is_dynamic_buffer
+struct is_dynamic_buffer_v1
+#if defined(GENERATING_DOCUMENTATION)
+ : integral_constant<bool, automatically_determined>
+#else // defined(GENERATING_DOCUMENTATION)
+ : boost::asio::detail::is_dynamic_buffer_v1<T>
+#endif // defined(GENERATING_DOCUMENTATION)
+{
+};
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Trait to determine whether a type satisfies the DynamicBuffer_v2
+/// requirements.
+template <typename T>
+struct is_dynamic_buffer_v2
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
- : boost::asio::detail::is_dynamic_buffer<T>
+ : boost::asio::detail::is_dynamic_buffer_v2<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
+/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
+/**
+ * If @c BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the
+ * type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c
+ * BOOST_ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type
+ * satisfies the DynamicBuffer_v1 requirements.
+ */
+template <typename T>
+struct is_dynamic_buffer
+#if defined(GENERATING_DOCUMENTATION)
+ : integral_constant<bool, automatically_determined>
+#elif defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ : boost::asio::is_dynamic_buffer_v2<T>
+#else // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+ : boost::asio::is_dynamic_buffer_v1<T>
+#endif // defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+{
+};
+
} // namespace asio
} // namespace boost
diff --git a/boost/asio/buffered_read_stream.hpp b/boost/asio/buffered_read_stream.hpp
index 28df23908d..cd1e0626a5 100644
--- a/boost/asio/buffered_read_stream.hpp
+++ b/boost/asio/buffered_read_stream.hpp
@@ -2,7 +2,7 @@
// buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -26,7 +26,6 @@
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_context()
- {
- return next_layer_.get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_service()
- {
- return next_layer_.get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Close the stream.
void close()
{
diff --git a/boost/asio/buffered_read_stream_fwd.hpp b/boost/asio/buffered_read_stream_fwd.hpp
index d6b0ad14be..f250c92f34 100644
--- a/boost/asio/buffered_read_stream_fwd.hpp
+++ b/boost/asio/buffered_read_stream_fwd.hpp
@@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/buffered_stream.hpp b/boost/asio/buffered_stream.hpp
index ada06e1d9c..d28abf10b6 100644
--- a/boost/asio/buffered_stream.hpp
+++ b/boost/asio/buffered_stream.hpp
@@ -2,7 +2,7 @@
// buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,7 +23,6 @@
#include <boost/asio/buffered_stream_fwd.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -97,22 +96,6 @@ public:
return stream_impl_.lowest_layer().get_executor();
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_context()
- {
- return stream_impl_.get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_service()
- {
- return stream_impl_.get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Close the stream.
void close()
{
diff --git a/boost/asio/buffered_stream_fwd.hpp b/boost/asio/buffered_stream_fwd.hpp
index a477f2be65..ceeac165f5 100644
--- a/boost/asio/buffered_stream_fwd.hpp
+++ b/boost/asio/buffered_stream_fwd.hpp
@@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/buffered_write_stream.hpp b/boost/asio/buffered_write_stream.hpp
index 3eacd5f150..aab02b5176 100644
--- a/boost/asio/buffered_write_stream.hpp
+++ b/boost/asio/buffered_write_stream.hpp
@@ -2,7 +2,7 @@
// buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -25,7 +25,6 @@
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -106,22 +105,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_context()
- {
- return next_layer_.get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_service()
- {
- return next_layer_.get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Close the stream.
void close()
{
diff --git a/boost/asio/buffered_write_stream_fwd.hpp b/boost/asio/buffered_write_stream_fwd.hpp
index 68ab9a4d31..eec5bc2804 100644
--- a/boost/asio/buffered_write_stream_fwd.hpp
+++ b/boost/asio/buffered_write_stream_fwd.hpp
@@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/buffers_iterator.hpp b/boost/asio/buffers_iterator.hpp
index 9de385128f..316c144130 100644
--- a/boost/asio/buffers_iterator.hpp
+++ b/boost/asio/buffers_iterator.hpp
@@ -2,7 +2,7 @@
// buffers_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/co_spawn.hpp b/boost/asio/co_spawn.hpp
new file mode 100644
index 0000000000..67d17e21b5
--- /dev/null
+++ b/boost/asio/co_spawn.hpp
@@ -0,0 +1,90 @@
+//
+// co_spawn.hpp
+// ~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_CO_SPAWN_HPP
+#define BOOST_ASIO_CO_SPAWN_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/awaitable.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/is_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+struct awaitable_signature;
+
+template <typename T, typename Executor>
+struct awaitable_signature<awaitable<T, Executor>>
+{
+ typedef void type(std::exception_ptr, T);
+};
+
+template <typename Executor>
+struct awaitable_signature<awaitable<void, Executor>>
+{
+ typedef void type(std::exception_ptr);
+};
+
+} // namespace detail
+
+/// Spawn a new thread of execution.
+/**
+ * The entry point function object @c f must have the signature:
+ *
+ * @code awaitable<void, E> f(); @endcode
+ *
+ * where @c E is convertible from @c Executor.
+ */
+template <typename Executor, typename F, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ typename detail::awaitable_signature<typename result_of<F()>::type>::type)
+co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
+ typename enable_if<
+ is_executor<Executor>::value
+ >::type* = 0);
+
+/// Spawn a new thread of execution.
+/**
+ * The entry point function object @c f must have the signature:
+ *
+ * @code awaitable<void, E> f(); @endcode
+ *
+ * where @c E is convertible from @c ExecutionContext::executor_type.
+ */
+template <typename ExecutionContext, typename F, typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ typename detail::awaitable_signature<typename result_of<F()>::type>::type)
+co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0);
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/co_spawn.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_CO_SPAWN_HPP
diff --git a/boost/asio/completion_condition.hpp b/boost/asio/completion_condition.hpp
index c49517ba4f..4d0337b3fb 100644
--- a/boost/asio/completion_condition.hpp
+++ b/boost/asio/completion_condition.hpp
@@ -2,7 +2,7 @@
// completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/compose.hpp b/boost/asio/compose.hpp
new file mode 100644
index 0000000000..b38e4faecb
--- /dev/null
+++ b/boost/asio/compose.hpp
@@ -0,0 +1,138 @@
+//
+// compose.hpp
+// ~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_COMPOSE_HPP
+#define BOOST_ASIO_COMPOSE_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/async_result.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES) \
+ || defined(GENERATING_DOCUMENTATION)
+
+/// Launch an asynchronous operation with a stateful implementation.
+/**
+ * The async_compose function simplifies the implementation of composed
+ * asynchronous operations automatically wrapping a stateful function object
+ * with a conforming intermediate completion handler.
+ *
+ * @param implementation A function object that contains the implementation of
+ * the composed asynchronous operation. The first argument to the function
+ * object is a non-const reference to the enclosing intermediate completion
+ * handler. The remaining arguments are any arguments that originate from the
+ * completion handlers of any asynchronous operations performed by the
+ * implementation.
+
+ * @param token The completion token.
+ *
+ * @param io_objects_or_executors Zero or more I/O objects or I/O executors for
+ * which outstanding work must be maintained.
+ *
+ * @par Example:
+ *
+ * @code struct async_echo_implementation
+ * {
+ * tcp::socket& socket_;
+ * boost::asio::mutable_buffer buffer_;
+ * enum { starting, reading, writing } state_;
+ *
+ * template <typename Self>
+ * void operator()(Self& self,
+ * boost::system::error_code error = {},
+ * std::size_t n = 0)
+ * {
+ * switch (state_)
+ * {
+ * case starting:
+ * state_ = reading;
+ * socket_.async_read_some(
+ * buffer_, std::move(self));
+ * break;
+ * case reading:
+ * if (error)
+ * {
+ * self.complete(error, 0);
+ * }
+ * else
+ * {
+ * state_ = writing;
+ * boost::asio::async_write(socket_, buffer_,
+ * boost::asio::transfer_exactly(n),
+ * std::move(self));
+ * }
+ * break;
+ * case writing:
+ * self.complete(error, n);
+ * break;
+ * }
+ * }
+ * };
+ *
+ * template <typename CompletionToken>
+ * auto async_echo(tcp::socket& socket,
+ * boost::asio::mutable_buffer buffer,
+ * CompletionToken&& token) ->
+ * typename boost::asio::async_result<
+ * typename std::decay<CompletionToken>::type,
+ * void(boost::system::error_code, std::size_t)>::return_type
+ * {
+ * return boost::asio::async_compose<CompletionToken,
+ * void(boost::system::error_code, std::size_t)>(
+ * async_echo_implementation{socket, buffer,
+ * async_echo_implementation::starting},
+ * token, socket);
+ * } @endcode
+ */
+template <typename CompletionToken, typename Signature,
+ typename Implementation, typename... IoObjectsOrExecutors>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
+async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors);
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // || defined(GENERATING_DOCUMENTATION)
+
+template <typename CompletionToken, typename Signature, typename Implementation>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
+async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token);
+
+#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
+ template <typename CompletionToken, typename Signature, \
+ typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \
+ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n));
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
+#undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ // || defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/compose.hpp>
+
+#endif // BOOST_ASIO_COMPOSE_HPP
diff --git a/boost/asio/connect.hpp b/boost/asio/connect.hpp
index 03296885dd..a500392d3c 100644
--- a/boost/asio/connect.hpp
+++ b/boost/asio/connect.hpp
@@ -2,7 +2,7 @@
// connect.hpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -83,14 +83,13 @@ struct is_endpoint_sequence
* Otherwise, contains the error from the last connection attempt.
*
* @par Example
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::asio::connect(s, r.resolve(q)); @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename EndpointSequence>
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@@ -115,9 +114,9 @@ typename Protocol::endpoint connect(
* default-constructed endpoint.
*
* @par Example
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::system::error_code ec;
* boost::asio::connect(s, r.resolve(q), ec);
* if (ec)
@@ -125,9 +124,8 @@ typename Protocol::endpoint connect(
* // An error occurred.
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename EndpointSequence>
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@@ -157,8 +155,8 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
@@ -185,8 +183,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -212,14 +210,14 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Otherwise, contains the error from the last connection attempt.
*
* @par Example
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::asio::connect(s, e.begin(), e.end()); @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -244,10 +242,10 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* endpoint. Otherwise, the end iterator.
*
* @par Example
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::system::error_code ec;
* boost::asio::connect(s, e.begin(), e.end(), ec);
* if (ec)
@@ -255,8 +253,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // An error occurred.
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, boost::system::error_code& ec);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -303,17 +301,16 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition());
* std::cout << "Connected to: " << e << std::endl; @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@@ -363,9 +360,9 @@ typename Protocol::endpoint connect(
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::system::error_code ec;
* tcp::endpoint e = boost::asio::connect(s,
* r.resolve(q), my_connect_condition(), ec);
@@ -378,10 +375,9 @@ typename Protocol::endpoint connect(
* std::cout << "Connected to: " << e << std::endl;
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
@@ -423,9 +419,9 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, ConnectCondition connect_condition,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
@@ -464,9 +460,9 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -517,17 +513,17 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* tcp::resolver::results_type::iterator i = boost::asio::connect(
* s, e.begin(), e.end(), my_connect_condition());
* std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -577,10 +573,10 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::system::error_code ec;
* tcp::resolver::results_type::iterator i = boost::asio::connect(
* s, e.begin(), e.end(), my_connect_condition());
@@ -593,9 +589,9 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* std::cout << "Connected to: " << i->endpoint() << std::endl;
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
boost::system::error_code& ec);
@@ -636,14 +632,14 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* const typename Protocol::endpoint& endpoint
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
*
* // ...
*
@@ -670,11 +666,11 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // ...
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
@@ -708,20 +704,20 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -754,13 +750,13 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code std::vector<tcp::endpoint> endpoints = ...;
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
* boost::asio::async_connect(s,
* endpoints.begin(), endpoints.end(),
* connect_handler);
@@ -774,12 +770,11 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* // ...
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/// Asynchronously establishes a socket connection by trying each endpoint in a
@@ -820,9 +815,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* The following connect condition function object can be used to output
@@ -839,9 +834,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
*
* // ...
*
@@ -877,11 +872,11 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* }
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
+template <typename Protocol, typename Executor, typename EndpointSequence,
typename ConnectCondition, typename RangeConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
@@ -926,19 +921,19 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c boost::asio::ip::tcp::resolver::iterator.
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
@@ -984,9 +979,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* The following connect condition function object can be used to output
@@ -1003,9 +998,9 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the boost::asio::connect function as follows:
- * @code tcp::resolver r(io_context);
+ * @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
- * tcp::socket s(io_context);
+ * tcp::socket s(my_context);
*
* // ...
*
@@ -1042,12 +1037,12 @@ async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
* }
* } @endcode
*/
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end, ConnectCondition connect_condition,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ Iterator end, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/*@}*/
diff --git a/boost/asio/coroutine.hpp b/boost/asio/coroutine.hpp
index b195b12ed8..c519295310 100644
--- a/boost/asio/coroutine.hpp
+++ b/boost/asio/coroutine.hpp
@@ -2,7 +2,7 @@
// coroutine.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -206,7 +206,7 @@ class coroutine_ref;
* {
* do
* {
- * socket_.reset(new tcp::socket(io_context_));
+ * socket_.reset(new tcp::socket(my_context_));
* yield acceptor->async_accept(*socket_, *this);
* fork server(*this)();
* } while (is_parent());
@@ -228,7 +228,7 @@ class coroutine_ref;
* Note that @c fork doesn't do the actual forking by itself. It is the
* application's responsibility to create a clone of the coroutine and call it.
* The clone can be called immediately, as above, or scheduled for delayed
- * execution using something like io_context::post().
+ * execution using something like boost::asio::post().
*
* @par Alternate macro names
*
diff --git a/boost/asio/datagram_socket_service.hpp b/boost/asio/datagram_socket_service.hpp
deleted file mode 100644
index 816433ba78..0000000000
--- a/boost/asio/datagram_socket_service.hpp
+++ /dev/null
@@ -1,468 +0,0 @@
-//
-// datagram_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_DATAGRAM_SOCKET_SERVICE_HPP
-#define BOOST_ASIO_DATAGRAM_SOCKET_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_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a datagram socket.
-template <typename Protocol>
-class datagram_socket_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<datagram_socket_service<Protocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef Protocol protocol_type;
-
- /// The endpoint type.
- typedef typename Protocol::endpoint endpoint_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef detail::null_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service<Protocol> service_impl_type;
-#endif
-
-public:
- /// The type of a datagram socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native socket type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new datagram socket service for the specified io_context.
- explicit datagram_socket_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- datagram_socket_service<Protocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new datagram socket implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new datagram socket implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another datagram socket implementation.
- void move_assign(implementation_type& impl,
- datagram_socket_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-
- // All socket services have access to each other's implementations.
- template <typename Protocol1> friend class datagram_socket_service;
-
- /// Move-construct a new datagram socket implementation from another protocol
- /// type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- datagram_socket_service<Protocol1>& other_service,
- typename datagram_socket_service<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a datagram socket implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- // Open a new datagram socket implementation.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const protocol_type& protocol, boost::system::error_code& ec)
- {
- if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM))
- service_impl_.open(impl, protocol, ec);
- else
- ec = boost::asio::error::invalid_argument;
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native socket to a datagram socket.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const protocol_type& protocol, const native_handle_type& native_socket,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, protocol, native_socket, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a datagram socket implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Release ownership of the underlying socket.
- native_handle_type release(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.release(impl, ec);
- }
-
- /// Get the native socket implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the socket.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_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
- {
- return service_impl_.at_mark(impl, ec);
- }
-
- /// Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.available(impl, ec);
- }
-
- // Bind the datagram socket to the specified local endpoint.
- BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- service_impl_.bind(impl, endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Connect the datagram socket to the specified endpoint.
- BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, boost::system::error_code& ec)
- {
- service_impl_.connect(impl, peer_endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Start an asynchronous connect.
- template <typename ConnectHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
- void (boost::system::error_code))
- async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint,
- BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
- {
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSocketOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a socket option.
- template <typename GettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSocketOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the socket.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the socket.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the socket.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native socket implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native socket implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the local endpoint.
- endpoint_type local_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.local_endpoint(impl, ec);
- }
-
- /// Get the remote endpoint.
- endpoint_type remote_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.remote_endpoint(impl, ec);
- }
-
- /// Disable sends or receives on the socket.
- BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- service_impl_.shutdown(impl, what, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the socket to become ready to read, ready to write, or to have
- /// pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- socket_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the socket to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, socket_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send the given data to the peer.
- template <typename ConstBufferSequence>
- std::size_t send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send(implementation_type& impl, const ConstBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send a datagram to the specified endpoint.
- template <typename ConstBufferSequence>
- std::size_t send_to(implementation_type& impl,
- const ConstBufferSequence& buffers, const endpoint_type& destination,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send_to(impl, buffers, destination, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send_to(implementation_type& impl,
- const ConstBufferSequence& buffers, const endpoint_type& destination,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send_to(impl, buffers,
- destination, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive some data from the peer.
- template <typename MutableBufferSequence>
- std::size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.receive(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous receive.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive a datagram with the endpoint of the sender.
- template <typename MutableBufferSequence>
- std::size_t receive_from(implementation_type& impl,
- const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
- ec);
- }
-
- /// Start an asynchronous receive that will get the endpoint of the sender.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive_from(implementation_type& impl,
- const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive_from(impl, buffers,
- sender_endpoint, flags, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP
diff --git a/boost/asio/deadline_timer.hpp b/boost/asio/deadline_timer.hpp
index 3a020e8b9a..1c061fc954 100644
--- a/boost/asio/deadline_timer.hpp
+++ b/boost/asio/deadline_timer.hpp
@@ -2,7 +2,7 @@
// deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/deadline_timer_service.hpp b/boost/asio/deadline_timer_service.hpp
deleted file mode 100644
index 036378f93b..0000000000
--- a/boost/asio/deadline_timer_service.hpp
+++ /dev/null
@@ -1,175 +0,0 @@
-//
-// deadline_timer_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_DEADLINE_TIMER_SERVICE_HPP
-#define BOOST_ASIO_DEADLINE_TIMER_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/deadline_timer_service.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/time_traits.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a timer.
-template <typename TimeType,
- typename TimeTraits = boost::asio::time_traits<TimeType> >
-class deadline_timer_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<
- deadline_timer_service<TimeType, TimeTraits> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The time traits type.
- typedef TimeTraits traits_type;
-
- /// The time type.
- typedef typename traits_type::time_type time_type;
-
- /// The duration type.
- typedef typename traits_type::duration_type duration_type;
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::deadline_timer_service<traits_type> service_impl_type;
-
-public:
- /// The implementation type of the deadline timer.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// Construct a new timer service for the specified io_context.
- explicit deadline_timer_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- deadline_timer_service<TimeType, TimeTraits> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new timer implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
- /// Destroy a timer implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Cancel any asynchronous wait operations associated with the timer.
- std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
- {
- return service_impl_.cancel(impl, ec);
- }
-
- /// Cancels one asynchronous wait operation associated with the timer.
- std::size_t cancel_one(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.cancel_one(impl, ec);
- }
-
- /// Get the expiry time for the timer as an absolute time.
- time_type expires_at(const implementation_type& impl) const
- {
- return service_impl_.expiry(impl);
- }
-
- /// Set the expiry time for the timer as an absolute time.
- std::size_t expires_at(implementation_type& impl,
- const time_type& expiry_time, boost::system::error_code& ec)
- {
- return service_impl_.expires_at(impl, expiry_time, ec);
- }
-
- /// Get the expiry time for the timer relative to now.
- duration_type expires_from_now(const implementation_type& impl) const
- {
- return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
- }
-
- /// Set the expiry time for the timer relative to now.
- std::size_t expires_from_now(implementation_type& impl,
- const duration_type& expiry_time, boost::system::error_code& ec)
- {
- return service_impl_.expires_after(impl, expiry_time, ec);
- }
-
- // Perform a blocking wait on the timer.
- void wait(implementation_type& impl, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, ec);
- }
-
- // Start an asynchronous wait on the timer.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_DEADLINE_TIMER_SERVICE_HPP
diff --git a/boost/asio/defer.hpp b/boost/asio/defer.hpp
index 2eaf2d01c6..319063a718 100644
--- a/boost/asio/defer.hpp
+++ b/boost/asio/defer.hpp
@@ -2,7 +2,7 @@
// defer.hpp
// ~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,6 +32,11 @@ namespace asio {
* executor. The function object is queued for execution, and is never called
* from the current thread prior to returning from <tt>defer()</tt>.
*
+ * The use of @c defer(), rather than @ref post(), indicates the caller's
+ * preference that the executor defer the queueing of the function object. This
+ * may allow the executor to optimise queueing for cases when the function
+ * object represents a continuation of the current call context.
+ *
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized
@@ -60,6 +65,11 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
* The function object is queued for execution, and is never called from the
* current thread prior to returning from <tt>defer()</tt>.
*
+ * The use of @c defer(), rather than @ref post(), indicates the caller's
+ * preference that the executor defer the queueing of the function object. This
+ * may allow the executor to optimise queueing for cases when the function
+ * object represents a continuation of the current call context.
+ *
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized
diff --git a/boost/asio/experimental/detached.hpp b/boost/asio/detached.hpp
index c3e7adafac..54b6bd2063 100644
--- a/boost/asio/experimental/detached.hpp
+++ b/boost/asio/detached.hpp
@@ -1,15 +1,15 @@
//
-// experimental/detached.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
+// detached.hpp
+// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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_EXPERIMENTAL_DETACHED_HPP
-#define BOOST_ASIO_EXPERIMENTAL_DETACHED_HPP
+#ifndef BOOST_ASIO_DETACHED_HPP
+#define BOOST_ASIO_DETACHED_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -22,7 +22,6 @@
namespace boost {
namespace asio {
-namespace experimental {
/// Class used to specify that an asynchronous operation is detached.
/**
@@ -31,9 +30,9 @@ namespace experimental {
* detached. That is, there is no completion handler waiting for the
* operation's result. A detached_t object may be passed as a handler to an
* asynchronous operation, typically using the special value
- * @c boost::asio::experimental::detached. For example:
+ * @c boost::asio::detached. For example:
- * @code my_socket.async_send(my_buffer, boost::asio::experimental::detached);
+ * @code my_socket.async_send(my_buffer, boost::asio::detached);
* @endcode
*/
class detached_t
@@ -47,8 +46,7 @@ public:
/// A special value, similar to std::nothrow.
/**
- * See the documentation for boost::asio::experimental::detached_t for a usage
- * example.
+ * See the documentation for boost::asio::detached_t for a usage example.
*/
#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
constexpr detached_t detached;
@@ -56,12 +54,11 @@ constexpr detached_t detached;
__declspec(selectany) detached_t detached;
#endif
-} // namespace experimental
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
-#include <boost/asio/experimental/impl/detached.hpp>
+#include <boost/asio/impl/detached.hpp>
-#endif // BOOST_ASIO_EXPERIMENTAL_DETACHED_HPP
+#endif // BOOST_ASIO_DETACHED_HPP
diff --git a/boost/asio/detail/array.hpp b/boost/asio/detail/array.hpp
index 238118e3a6..6779e484b9 100644
--- a/boost/asio/detail/array.hpp
+++ b/boost/asio/detail/array.hpp
@@ -2,7 +2,7 @@
// detail/array.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/array_fwd.hpp b/boost/asio/detail/array_fwd.hpp
index 82f357785d..25a0c61496 100644
--- a/boost/asio/detail/array_fwd.hpp
+++ b/boost/asio/detail/array_fwd.hpp
@@ -2,7 +2,7 @@
// detail/array_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/assert.hpp b/boost/asio/detail/assert.hpp
index fe306ce614..927dfce76f 100644
--- a/boost/asio/detail/assert.hpp
+++ b/boost/asio/detail/assert.hpp
@@ -2,7 +2,7 @@
// detail/assert.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/atomic_count.hpp b/boost/asio/detail/atomic_count.hpp
index 78cd0fb333..ba945a9e0f 100644
--- a/boost/asio/detail/atomic_count.hpp
+++ b/boost/asio/detail/atomic_count.hpp
@@ -2,7 +2,7 @@
// detail/atomic_count.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/base_from_completion_cond.hpp b/boost/asio/detail/base_from_completion_cond.hpp
index 88f167f3f4..7904eadc91 100644
--- a/boost/asio/detail/base_from_completion_cond.hpp
+++ b/boost/asio/detail/base_from_completion_cond.hpp
@@ -2,7 +2,7 @@
// detail/base_from_completion_cond.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,8 +28,9 @@ template <typename CompletionCondition>
class base_from_completion_cond
{
protected:
- explicit base_from_completion_cond(CompletionCondition completion_condition)
- : completion_condition_(completion_condition)
+ explicit base_from_completion_cond(CompletionCondition& completion_condition)
+ : completion_condition_(
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition))
{
}
diff --git a/boost/asio/detail/bind_handler.hpp b/boost/asio/detail/bind_handler.hpp
index 39f1b29bcd..ddeb58fadc 100644
--- a/boost/asio/detail/bind_handler.hpp
+++ b/boost/asio/detail/bind_handler.hpp
@@ -2,7 +2,7 @@
// detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/buffer_resize_guard.hpp b/boost/asio/detail/buffer_resize_guard.hpp
index ad07f72c04..198e9c7dc0 100644
--- a/boost/asio/detail/buffer_resize_guard.hpp
+++ b/boost/asio/detail/buffer_resize_guard.hpp
@@ -2,7 +2,7 @@
// detail/buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/buffer_sequence_adapter.hpp b/boost/asio/detail/buffer_sequence_adapter.hpp
index 5ba55d266d..f33d3426ac 100644
--- a/boost/asio/detail/buffer_sequence_adapter.hpp
+++ b/boost/asio/detail/buffer_sequence_adapter.hpp
@@ -2,7 +2,7 @@
// detail/buffer_sequence_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/buffered_stream_storage.hpp b/boost/asio/detail/buffered_stream_storage.hpp
index 3b9ca404c4..2e060ce5f2 100644
--- a/boost/asio/detail/buffered_stream_storage.hpp
+++ b/boost/asio/detail/buffered_stream_storage.hpp
@@ -2,7 +2,7 @@
// detail/buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/call_stack.hpp b/boost/asio/detail/call_stack.hpp
index 34f4de607f..eb63e54729 100644
--- a/boost/asio/detail/call_stack.hpp
+++ b/boost/asio/detail/call_stack.hpp
@@ -2,7 +2,7 @@
// detail/call_stack.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/chrono.hpp b/boost/asio/detail/chrono.hpp
index 044f12c6c3..d5a55ff4e1 100644
--- a/boost/asio/detail/chrono.hpp
+++ b/boost/asio/detail/chrono.hpp
@@ -2,7 +2,7 @@
// detail/chrono.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/chrono_time_traits.hpp b/boost/asio/detail/chrono_time_traits.hpp
index 256389acaf..85e3b8b429 100644
--- a/boost/asio/detail/chrono_time_traits.hpp
+++ b/boost/asio/detail/chrono_time_traits.hpp
@@ -2,7 +2,7 @@
// detail/chrono_time_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/completion_handler.hpp b/boost/asio/detail/completion_handler.hpp
index e856a86f5a..3cd136974e 100644
--- a/boost/asio/detail/completion_handler.hpp
+++ b/boost/asio/detail/completion_handler.hpp
@@ -2,7 +2,7 @@
// detail/completion_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/concurrency_hint.hpp b/boost/asio/detail/concurrency_hint.hpp
index c11b7f6109..99deb78644 100644
--- a/boost/asio/detail/concurrency_hint.hpp
+++ b/boost/asio/detail/concurrency_hint.hpp
@@ -2,7 +2,7 @@
// detail/concurrency_hint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/conditionally_enabled_event.hpp b/boost/asio/detail/conditionally_enabled_event.hpp
index 9319c87538..2d5a45c02e 100644
--- a/boost/asio/detail/conditionally_enabled_event.hpp
+++ b/boost/asio/detail/conditionally_enabled_event.hpp
@@ -2,7 +2,7 @@
// detail/conditionally_enabled_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/conditionally_enabled_mutex.hpp b/boost/asio/detail/conditionally_enabled_mutex.hpp
index ab4ef48afc..5d105e9814 100644
--- a/boost/asio/detail/conditionally_enabled_mutex.hpp
+++ b/boost/asio/detail/conditionally_enabled_mutex.hpp
@@ -2,7 +2,7 @@
// detail/conditionally_enabled_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/config.hpp b/boost/asio/detail/config.hpp
index 2453425315..8fef292b00 100644
--- a/boost/asio/detail/config.hpp
+++ b/boost/asio/detail/config.hpp
@@ -2,7 +2,7 @@
// detail/config.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -120,11 +120,14 @@
#endif // !defined(BOOST_ASIO_HAS_MOVE)
// If BOOST_ASIO_MOVE_CAST isn't defined, and move support is available, define
-// BOOST_ASIO_MOVE_ARG and BOOST_ASIO_MOVE_CAST to take advantage of rvalue
-// references and perfect forwarding.
+// * BOOST_ASIO_MOVE_ARG,
+// * BOOST_ASIO_NONDEDUCED_MOVE_ARG, and
+// * BOOST_ASIO_MOVE_CAST
+// to take advantage of rvalue references and perfect forwarding.
#if defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
# define BOOST_ASIO_MOVE_ARG(type) type&&
# define BOOST_ASIO_MOVE_ARG2(type1, type2) type1, type2&&
+# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) type&
# define BOOST_ASIO_MOVE_CAST(type) static_cast<type&&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
#endif // defined(BOOST_ASIO_HAS_MOVE) && !defined(BOOST_ASIO_MOVE_CAST)
@@ -150,6 +153,7 @@
# else
# define BOOST_ASIO_MOVE_ARG(type) type
# endif
+# define BOOST_ASIO_NONDEDUCED_MOVE_ARG(type) const type&
# define BOOST_ASIO_MOVE_CAST(type) static_cast<const type&>
# define BOOST_ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
#endif // !defined(BOOST_ASIO_MOVE_CAST)
@@ -280,9 +284,9 @@
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_ASIO_MSVC)
-# if (_MSC_VER >= 1700)
+# if (_MSC_VER >= 1800)
# define BOOST_ASIO_HAS_DECLTYPE 1
-# endif // (_MSC_VER >= 1700)
+# endif // (_MSC_VER >= 1800)
# endif // defined(BOOST_ASIO_MSVC)
# endif // !defined(BOOST_ASIO_DISABLE_DECLTYPE)
#endif // !defined(BOOST_ASIO_HAS_DECLTYPE)
@@ -446,7 +450,13 @@
# if __has_include(<atomic>)
# define BOOST_ASIO_HAS_STD_ATOMIC 1
# endif // __has_include(<atomic>)
-# endif // (__cplusplus >= 201103)
+# elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
+# if (__clang_major__ >= 10)
+# if __has_include(<atomic>)
+# define BOOST_ASIO_HAS_STD_ATOMIC 1
+# endif // __has_include(<atomic>)
+# endif // (__clang_major__ >= 10)
+# endif /// defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
# endif // defined(__clang__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
@@ -922,15 +932,15 @@
# 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).")
+ "- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\
+ "- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\
+ "Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 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).
+# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.
+# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
-# define _WIN32_WINNT 0x0501
+# define _WIN32_WINNT 0x0601
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)
@@ -1001,7 +1011,8 @@
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
- || defined(__linux__)
+ || defined(__linux__) \
+ || defined(__HAIKU__)
# define BOOST_ASIO_HAS_UNISTD_H 1
# endif
# endif // !defined(BOOST_ASIO_HAS_BOOST_CONFIG)
@@ -1365,33 +1376,6 @@
// || (defined(__MACH__) && defined(__APPLE__))
#endif // !defined(BOOST_ASIO_DISABLE_SSIZE_T)
-// Helper macros to manage the transition away from the old services-based API.
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# define BOOST_ASIO_SVC_TPARAM , typename Service
-# define BOOST_ASIO_SVC_TPARAM_DEF1(d1) , typename Service d1
-# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2) , typename Service d1, d2
-# define BOOST_ASIO_SVC_TARG , Service
-# define BOOST_ASIO_SVC_T Service
-# define BOOST_ASIO_SVC_TPARAM1 , typename Service1
-# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1) , typename Service1 d1
-# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2) , typename Service1 d1, d2
-# define BOOST_ASIO_SVC_TARG1 , Service1
-# define BOOST_ASIO_SVC_T1 Service1
-# define BOOST_ASIO_SVC_ACCESS public
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# define BOOST_ASIO_SVC_TPARAM
-# define BOOST_ASIO_SVC_TPARAM_DEF1(d1)
-# define BOOST_ASIO_SVC_TPARAM_DEF2(d1, d2)
-# define BOOST_ASIO_SVC_TARG
-// BOOST_ASIO_SVC_T is defined at each point of use.
-# define BOOST_ASIO_SVC_TPARAM1
-# define BOOST_ASIO_SVC_TPARAM1_DEF1(d1)
-# define BOOST_ASIO_SVC_TPARAM1_DEF2(d1, d2)
-# define BOOST_ASIO_SVC_TARG1
-// BOOST_ASIO_SVC_T1 is defined at each point of use.
-# define BOOST_ASIO_SVC_ACCESS protected
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
// Helper macros to manage transition away from error_code return values.
#if defined(BOOST_ASIO_NO_DEPRECATED)
# define BOOST_ASIO_SYNC_OP_VOID void
diff --git a/boost/asio/detail/consuming_buffers.hpp b/boost/asio/detail/consuming_buffers.hpp
index 38eb00576c..f8226a4e8d 100644
--- a/boost/asio/detail/consuming_buffers.hpp
+++ b/boost/asio/detail/consuming_buffers.hpp
@@ -2,7 +2,7 @@
// detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/cstddef.hpp b/boost/asio/detail/cstddef.hpp
index 665ff3b3a3..b77d9aab7f 100644
--- a/boost/asio/detail/cstddef.hpp
+++ b/boost/asio/detail/cstddef.hpp
@@ -2,7 +2,7 @@
// detail/cstddef.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/cstdint.hpp b/boost/asio/detail/cstdint.hpp
index 24e203aa6d..b916f78a74 100644
--- a/boost/asio/detail/cstdint.hpp
+++ b/boost/asio/detail/cstdint.hpp
@@ -2,7 +2,7 @@
// detail/cstdint.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/date_time_fwd.hpp b/boost/asio/detail/date_time_fwd.hpp
index b6c49c75d1..c917be4ffb 100644
--- a/boost/asio/detail/date_time_fwd.hpp
+++ b/boost/asio/detail/date_time_fwd.hpp
@@ -2,7 +2,7 @@
// detail/date_time_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/deadline_timer_service.hpp b/boost/asio/detail/deadline_timer_service.hpp
index ff162493d8..8732990a0f 100644
--- a/boost/asio/detail/deadline_timer_service.hpp
+++ b/boost/asio/detail/deadline_timer_service.hpp
@@ -2,7 +2,7 @@
// detail/deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -18,7 +18,7 @@
#include <boost/asio/detail/config.hpp>
#include <cstddef>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/fenced_block.hpp>
#include <boost/asio/detail/memory.hpp>
@@ -44,7 +44,7 @@ namespace detail {
template <typename Time_Traits>
class deadline_timer_service
- : public service_base<deadline_timer_service<Time_Traits> >
+ : public execution_context_service_base<deadline_timer_service<Time_Traits> >
{
public:
// The time type.
@@ -64,9 +64,10 @@ public:
};
// Constructor.
- deadline_timer_service(boost::asio::io_context& io_context)
- : service_base<deadline_timer_service<Time_Traits> >(io_context),
- scheduler_(boost::asio::use_service<timer_scheduler>(io_context))
+ deadline_timer_service(execution_context& context)
+ : execution_context_service_base<
+ deadline_timer_service<Time_Traits> >(context),
+ scheduler_(boost::asio::use_service<timer_scheduler>(context))
{
scheduler_.init_task();
scheduler_.add_timer_queue(timer_queue_);
@@ -226,14 +227,15 @@ public:
}
// Start an asynchronous wait on the timer.
- template <typename Handler>
- void async_wait(implementation_type& impl, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_wait(implementation_type& impl,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef wait_handler<Handler> op;
+ typedef wait_handler<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
impl.might_have_pending_waits = true;
diff --git a/boost/asio/detail/dependent_type.hpp b/boost/asio/detail/dependent_type.hpp
index 43f87dae7f..53aef3fb5f 100644
--- a/boost/asio/detail/dependent_type.hpp
+++ b/boost/asio/detail/dependent_type.hpp
@@ -2,7 +2,7 @@
// detail/dependent_type.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/descriptor_ops.hpp b/boost/asio/detail/descriptor_ops.hpp
index bfa6ce99fa..bfb0824ffb 100644
--- a/boost/asio/detail/descriptor_ops.hpp
+++ b/boost/asio/detail/descriptor_ops.hpp
@@ -2,7 +2,7 @@
// detail/descriptor_ops.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/descriptor_read_op.hpp b/boost/asio/detail/descriptor_read_op.hpp
index 328e2191c0..3ced62bb26 100644
--- a/boost/asio/detail/descriptor_read_op.hpp
+++ b/boost/asio/detail/descriptor_read_op.hpp
@@ -2,7 +2,7 @@
// detail/descriptor_read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -67,20 +67,21 @@ private:
MutableBufferSequence buffers_;
};
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
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(int descriptor, const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: descriptor_read_op_base<MutableBufferSequence>(
descriptor, buffers, &descriptor_read_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -90,7 +91,7 @@ public:
// Take ownership of the handler object.
descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -117,6 +118,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/descriptor_write_op.hpp b/boost/asio/detail/descriptor_write_op.hpp
index 80ddf37d37..d1eea52789 100644
--- a/boost/asio/detail/descriptor_write_op.hpp
+++ b/boost/asio/detail/descriptor_write_op.hpp
@@ -2,7 +2,7 @@
// detail/descriptor_write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -67,20 +67,21 @@ private:
ConstBufferSequence buffers_;
};
-template <typename ConstBufferSequence, typename Handler>
+template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
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(int descriptor, const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: descriptor_write_op_base<ConstBufferSequence>(
descriptor, buffers, &descriptor_write_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -90,7 +91,7 @@ public:
// Take ownership of the handler object.
descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -117,6 +118,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/dev_poll_reactor.hpp b/boost/asio/detail/dev_poll_reactor.hpp
index cb15a9671b..63a0c3058f 100644
--- a/boost/asio/detail/dev_poll_reactor.hpp
+++ b/boost/asio/detail/dev_poll_reactor.hpp
@@ -2,7 +2,7 @@
// detail/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/epoll_reactor.hpp b/boost/asio/detail/epoll_reactor.hpp
index 31a7b3dff3..c361978853 100644
--- a/boost/asio/detail/epoll_reactor.hpp
+++ b/boost/asio/detail/epoll_reactor.hpp
@@ -2,7 +2,7 @@
// detail/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/event.hpp b/boost/asio/detail/event.hpp
index 8cb097cb24..b55a204059 100644
--- a/boost/asio/detail/event.hpp
+++ b/boost/asio/detail/event.hpp
@@ -2,7 +2,7 @@
// detail/event.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/eventfd_select_interrupter.hpp b/boost/asio/detail/eventfd_select_interrupter.hpp
index 4871c971ed..0bcbcb96db 100644
--- a/boost/asio/detail/eventfd_select_interrupter.hpp
+++ b/boost/asio/detail/eventfd_select_interrupter.hpp
@@ -2,7 +2,7 @@
// detail/eventfd_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
diff --git a/boost/asio/detail/executor_function.hpp b/boost/asio/detail/executor_function.hpp
new file mode 100644
index 0000000000..2b8fb40a12
--- /dev/null
+++ b/boost/asio/detail/executor_function.hpp
@@ -0,0 +1,106 @@
+//
+// detail/executor_function.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_EXECUTOR_FUNCTION_HPP
+#define BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_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/handler_alloc_helpers.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+class executor_function_base
+{
+public:
+ void complete()
+ {
+ func_(this, true);
+ }
+
+ void destroy()
+ {
+ func_(this, false);
+ }
+
+protected:
+ typedef void (*func_type)(executor_function_base*, bool);
+
+ executor_function_base(func_type func)
+ : func_(func)
+ {
+ }
+
+ // Prevents deletion through this type.
+ ~executor_function_base()
+ {
+ }
+
+private:
+ func_type func_;
+};
+
+template <typename Function, typename Alloc>
+class executor_function : public executor_function_base
+{
+public:
+ BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(
+ thread_info_base::executor_function_tag, executor_function);
+
+ template <typename F>
+ executor_function(BOOST_ASIO_MOVE_ARG(F) f, const Alloc& allocator)
+ : executor_function_base(&executor_function::do_complete),
+ function_(BOOST_ASIO_MOVE_CAST(F)(f)),
+ allocator_(allocator)
+ {
+ }
+
+ static void do_complete(executor_function_base* base, bool call)
+ {
+ // Take ownership of the function object.
+ executor_function* o(static_cast<executor_function*>(base));
+ Alloc allocator(o->allocator_);
+ ptr p = { detail::addressof(allocator), o, o };
+
+ // Make a copy of the function 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 function may be the true owner of the memory
+ // associated with the function. Consequently, a local copy of the function
+ // is required to ensure that any owning sub-object remains valid until
+ // after we have deallocated the memory here.
+ Function function(BOOST_ASIO_MOVE_CAST(Function)(o->function_));
+ p.reset();
+
+ // Make the upcall if required.
+ if (call)
+ {
+ function();
+ }
+ }
+
+private:
+ Function function_;
+ Alloc allocator_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
diff --git a/boost/asio/detail/executor_op.hpp b/boost/asio/detail/executor_op.hpp
index 1c8671abc8..b2581201f3 100644
--- a/boost/asio/detail/executor_op.hpp
+++ b/boost/asio/detail/executor_op.hpp
@@ -2,7 +2,7 @@
// detail/executor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/fd_set_adapter.hpp b/boost/asio/detail/fd_set_adapter.hpp
index 26ba12665e..d502910a6f 100644
--- a/boost/asio/detail/fd_set_adapter.hpp
+++ b/boost/asio/detail/fd_set_adapter.hpp
@@ -2,7 +2,7 @@
// detail/fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/fenced_block.hpp b/boost/asio/detail/fenced_block.hpp
index e80ed4073c..479db6daa7 100644
--- a/boost/asio/detail/fenced_block.hpp
+++ b/boost/asio/detail/fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/functional.hpp b/boost/asio/detail/functional.hpp
index 23218bb5df..73f06ece21 100644
--- a/boost/asio/detail/functional.hpp
+++ b/boost/asio/detail/functional.hpp
@@ -2,7 +2,7 @@
// detail/functional.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/future.hpp b/boost/asio/detail/future.hpp
index 38cc7c1e83..67a0c1bde3 100644
--- a/boost/asio/detail/future.hpp
+++ b/boost/asio/detail/future.hpp
@@ -2,7 +2,7 @@
// detail/future.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/gcc_arm_fenced_block.hpp b/boost/asio/detail/gcc_arm_fenced_block.hpp
index 3a5a1dfacf..4051657ed7 100644
--- a/boost/asio/detail/gcc_arm_fenced_block.hpp
+++ b/boost/asio/detail/gcc_arm_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/gcc_arm_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/gcc_hppa_fenced_block.hpp b/boost/asio/detail/gcc_hppa_fenced_block.hpp
index bc0bc8afb4..a3061c0301 100644
--- a/boost/asio/detail/gcc_hppa_fenced_block.hpp
+++ b/boost/asio/detail/gcc_hppa_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/gcc_hppa_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/gcc_sync_fenced_block.hpp b/boost/asio/detail/gcc_sync_fenced_block.hpp
index e464738ee0..a167c52f75 100644
--- a/boost/asio/detail/gcc_sync_fenced_block.hpp
+++ b/boost/asio/detail/gcc_sync_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/gcc_sync_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/gcc_x86_fenced_block.hpp b/boost/asio/detail/gcc_x86_fenced_block.hpp
index f66289fe96..5d5e4eef4a 100644
--- a/boost/asio/detail/gcc_x86_fenced_block.hpp
+++ b/boost/asio/detail/gcc_x86_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/gcc_x86_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/global.hpp b/boost/asio/detail/global.hpp
index 967890408f..383ceb8cd8 100644
--- a/boost/asio/detail/global.hpp
+++ b/boost/asio/detail/global.hpp
@@ -2,7 +2,7 @@
// detail/global.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/handler_alloc_helpers.hpp b/boost/asio/detail/handler_alloc_helpers.hpp
index 6e72051393..85b825dd02 100644
--- a/boost/asio/detail/handler_alloc_helpers.hpp
+++ b/boost/asio/detail/handler_alloc_helpers.hpp
@@ -2,7 +2,7 @@
// detail/handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -194,7 +194,7 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \
/**/
-#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
+#define BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
struct ptr \
{ \
const Alloc* a; \
@@ -207,9 +207,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
static op* allocate(const Alloc& a) \
{ \
typedef typename ::boost::asio::detail::get_recycling_allocator< \
- Alloc>::type recycling_allocator_type; \
+ Alloc, purpose>::type recycling_allocator_type; \
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
- ::boost::asio::detail::get_recycling_allocator<Alloc>::get(a)); \
+ ::boost::asio::detail::get_recycling_allocator< \
+ Alloc, purpose>::get(a)); \
return a1.allocate(1); \
} \
void reset() \
@@ -222,9 +223,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
if (v) \
{ \
typedef typename ::boost::asio::detail::get_recycling_allocator< \
- Alloc>::type recycling_allocator_type; \
+ Alloc, purpose>::type recycling_allocator_type; \
BOOST_ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
- ::boost::asio::detail::get_recycling_allocator<Alloc>::get(*a)); \
+ ::boost::asio::detail::get_recycling_allocator< \
+ Alloc, purpose>::get(*a)); \
a1.deallocate(static_cast<op*>(v), 1); \
v = 0; \
} \
@@ -232,6 +234,11 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \
/**/
+#define BOOST_ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
+ BOOST_ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
+ ::boost::asio::detail::thread_info_base::default_tag, op ) \
+ /**/
+
#include <boost/asio/detail/pop_options.hpp>
#endif // BOOST_ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP
diff --git a/boost/asio/detail/handler_cont_helpers.hpp b/boost/asio/detail/handler_cont_helpers.hpp
index 700505d579..204097e032 100644
--- a/boost/asio/detail/handler_cont_helpers.hpp
+++ b/boost/asio/detail/handler_cont_helpers.hpp
@@ -2,7 +2,7 @@
// detail/handler_cont_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/handler_invoke_helpers.hpp b/boost/asio/detail/handler_invoke_helpers.hpp
index 8ced5f617c..e453b02cf4 100644
--- a/boost/asio/detail/handler_invoke_helpers.hpp
+++ b/boost/asio/detail/handler_invoke_helpers.hpp
@@ -2,7 +2,7 @@
// detail/handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/handler_tracking.hpp b/boost/asio/detail/handler_tracking.hpp
index 0839e09159..35eff023e2 100644
--- a/boost/asio/detail/handler_tracking.hpp
+++ b/boost/asio/detail/handler_tracking.hpp
@@ -2,7 +2,7 @@
// detail/handler_tracking.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/handler_type_requirements.hpp b/boost/asio/detail/handler_type_requirements.hpp
index 3a83c8d154..cf57d67652 100644
--- a/boost/asio/detail/handler_type_requirements.hpp
+++ b/boost/asio/detail/handler_type_requirements.hpp
@@ -2,7 +2,7 @@
// detail/handler_type_requirements.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/handler_work.hpp b/boost/asio/detail/handler_work.hpp
index dbd1bb911a..06da376178 100644
--- a/boost/asio/detail/handler_work.hpp
+++ b/boost/asio/detail/handler_work.hpp
@@ -2,7 +2,7 @@
// detail/handler_work.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,24 +28,41 @@ namespace detail {
// A helper class template to allow completion handlers to be dispatched
// through either the new executors framework or the old invocaton hook. The
// primary template uses the new executors framework.
-template <typename Handler, typename Executor
- = typename associated_executor<Handler>::type>
+template <typename Handler,
+ typename IoExecutor = system_executor, typename HandlerExecutor
+ = typename associated_executor<Handler, IoExecutor>::type>
class handler_work
{
public:
explicit handler_work(Handler& handler) BOOST_ASIO_NOEXCEPT
- : executor_(associated_executor<Handler>::get(handler))
+ : io_executor_(),
+ executor_(boost::asio::get_associated_executor(handler, io_executor_))
+ {
+ }
+
+ handler_work(Handler& handler, const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
+ : io_executor_(io_ex),
+ executor_(boost::asio::get_associated_executor(handler, io_executor_))
{
}
static void start(Handler& handler) BOOST_ASIO_NOEXCEPT
{
- Executor ex(associated_executor<Handler>::get(handler));
+ HandlerExecutor ex(boost::asio::get_associated_executor(handler));
+ ex.on_work_started();
+ }
+
+ static void start(Handler& handler,
+ const IoExecutor& io_ex) BOOST_ASIO_NOEXCEPT
+ {
+ HandlerExecutor ex(boost::asio::get_associated_executor(handler, io_ex));
ex.on_work_started();
+ io_ex.on_work_started();
}
~handler_work()
{
+ io_executor_.on_work_finished();
executor_.on_work_finished();
}
@@ -53,7 +70,7 @@ public:
void complete(Function& function, Handler& handler)
{
executor_.dispatch(BOOST_ASIO_MOVE_CAST(Function)(function),
- associated_allocator<Handler>::get(handler));
+ boost::asio::get_associated_allocator(handler));
}
private:
@@ -61,7 +78,8 @@ private:
handler_work(const handler_work&);
handler_work& operator=(const handler_work&);
- typename associated_executor<Handler>::type executor_;
+ IoExecutor io_executor_;
+ HandlerExecutor executor_;
};
// This specialisation dispatches a handler through the old invocation hook.
@@ -69,7 +87,7 @@ private:
// system_executor will dispatch through the hook anyway. However, by doing
// this we avoid an extra copy of the handler.
template <typename Handler>
-class handler_work<Handler, system_executor>
+class handler_work<Handler, system_executor, system_executor>
{
public:
explicit handler_work(Handler&) BOOST_ASIO_NOEXCEPT {}
diff --git a/boost/asio/detail/hash_map.hpp b/boost/asio/detail/hash_map.hpp
index 6a13620e92..ac80abdc79 100644
--- a/boost/asio/detail/hash_map.hpp
+++ b/boost/asio/detail/hash_map.hpp
@@ -2,7 +2,7 @@
// detail/hash_map.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/buffer_sequence_adapter.ipp b/boost/asio/detail/impl/buffer_sequence_adapter.ipp
index 26708ced33..b3fb59ccc7 100644
--- a/boost/asio/detail/impl/buffer_sequence_adapter.ipp
+++ b/boost/asio/detail/impl/buffer_sequence_adapter.ipp
@@ -2,7 +2,7 @@
// detail/impl/buffer_sequence_adapter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/descriptor_ops.ipp b/boost/asio/detail/impl/descriptor_ops.ipp
index 1bb68be1c0..1a26e6db69 100644
--- a/boost/asio/detail/impl/descriptor_ops.ipp
+++ b/boost/asio/detail/impl/descriptor_ops.ipp
@@ -2,7 +2,7 @@
// detail/impl/descriptor_ops.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/dev_poll_reactor.hpp b/boost/asio/detail/impl/dev_poll_reactor.hpp
index 797937bad8..87dd20ab4b 100644
--- a/boost/asio/detail/impl/dev_poll_reactor.hpp
+++ b/boost/asio/detail/impl/dev_poll_reactor.hpp
@@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/dev_poll_reactor.ipp b/boost/asio/detail/impl/dev_poll_reactor.ipp
index 5cc73ca9c1..807741dc4d 100644
--- a/boost/asio/detail/impl/dev_poll_reactor.ipp
+++ b/boost/asio/detail/impl/dev_poll_reactor.ipp
@@ -2,7 +2,7 @@
// detail/impl/dev_poll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/epoll_reactor.hpp b/boost/asio/detail/impl/epoll_reactor.hpp
index 101b1d6ead..15968a30b3 100644
--- a/boost/asio/detail/impl/epoll_reactor.hpp
+++ b/boost/asio/detail/impl/epoll_reactor.hpp
@@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/epoll_reactor.ipp b/boost/asio/detail/impl/epoll_reactor.ipp
index 1e9babcc14..b1e1b39d05 100644
--- a/boost/asio/detail/impl/epoll_reactor.ipp
+++ b/boost/asio/detail/impl/epoll_reactor.ipp
@@ -2,7 +2,7 @@
// detail/impl/epoll_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/eventfd_select_interrupter.ipp b/boost/asio/detail/impl/eventfd_select_interrupter.ipp
index 8804009442..38d4b2a61d 100644
--- a/boost/asio/detail/impl/eventfd_select_interrupter.ipp
+++ b/boost/asio/detail/impl/eventfd_select_interrupter.ipp
@@ -2,7 +2,7 @@
// detail/impl/eventfd_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
diff --git a/boost/asio/detail/impl/handler_tracking.ipp b/boost/asio/detail/impl/handler_tracking.ipp
index b3abbb513a..c873a50987 100644
--- a/boost/asio/detail/impl/handler_tracking.ipp
+++ b/boost/asio/detail/impl/handler_tracking.ipp
@@ -2,7 +2,7 @@
// detail/impl/handler_tracking.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/kqueue_reactor.hpp b/boost/asio/detail/impl/kqueue_reactor.hpp
index 4d79ba5d7c..f4dd174fdc 100644
--- a/boost/asio/detail/impl/kqueue_reactor.hpp
+++ b/boost/asio/detail/impl/kqueue_reactor.hpp
@@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
diff --git a/boost/asio/detail/impl/kqueue_reactor.ipp b/boost/asio/detail/impl/kqueue_reactor.ipp
index 9069ae4442..02475aaa36 100644
--- a/boost/asio/detail/impl/kqueue_reactor.ipp
+++ b/boost/asio/detail/impl/kqueue_reactor.ipp
@@ -2,7 +2,7 @@
// detail/impl/kqueue_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
diff --git a/boost/asio/detail/impl/null_event.ipp b/boost/asio/detail/impl/null_event.ipp
index 19bab80b33..b7568413fb 100644
--- a/boost/asio/detail/impl/null_event.ipp
+++ b/boost/asio/detail/impl/null_event.ipp
@@ -2,7 +2,7 @@
// detail/impl/null_event.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/pipe_select_interrupter.ipp b/boost/asio/detail/impl/pipe_select_interrupter.ipp
index bfff076747..f7bb7851b2 100644
--- a/boost/asio/detail/impl/pipe_select_interrupter.ipp
+++ b/boost/asio/detail/impl/pipe_select_interrupter.ipp
@@ -2,7 +2,7 @@
// detail/impl/pipe_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/posix_event.ipp b/boost/asio/detail/impl/posix_event.ipp
index 6f096bc08e..1c6d885a63 100644
--- a/boost/asio/detail/impl/posix_event.ipp
+++ b/boost/asio/detail/impl/posix_event.ipp
@@ -2,7 +2,7 @@
// detail/impl/posix_event.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/posix_mutex.ipp b/boost/asio/detail/impl/posix_mutex.ipp
index 57564714a1..fc86d43815 100644
--- a/boost/asio/detail/impl/posix_mutex.ipp
+++ b/boost/asio/detail/impl/posix_mutex.ipp
@@ -2,7 +2,7 @@
// detail/impl/posix_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/posix_thread.ipp b/boost/asio/detail/impl/posix_thread.ipp
index c2ee8efef7..d01922c625 100644
--- a/boost/asio/detail/impl/posix_thread.ipp
+++ b/boost/asio/detail/impl/posix_thread.ipp
@@ -2,7 +2,7 @@
// detail/impl/posix_thread.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/posix_tss_ptr.ipp b/boost/asio/detail/impl/posix_tss_ptr.ipp
index a40f3f81a6..623dc679c5 100644
--- a/boost/asio/detail/impl/posix_tss_ptr.ipp
+++ b/boost/asio/detail/impl/posix_tss_ptr.ipp
@@ -2,7 +2,7 @@
// detail/impl/posix_tss_ptr.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/reactive_descriptor_service.ipp b/boost/asio/detail/impl/reactive_descriptor_service.ipp
index 735239c597..0611a953db 100644
--- a/boost/asio/detail/impl/reactive_descriptor_service.ipp
+++ b/boost/asio/detail/impl/reactive_descriptor_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/reactive_descriptor_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -31,9 +31,9 @@ namespace asio {
namespace detail {
reactive_descriptor_service::reactive_descriptor_service(
- boost::asio::io_context& io_context)
- : service_base<reactive_descriptor_service>(io_context),
- reactor_(boost::asio::use_service<reactor>(io_context))
+ execution_context& context)
+ : execution_context_service_base<reactive_descriptor_service>(context),
+ reactor_(boost::asio::use_service<reactor>(context))
{
reactor_.init_task();
}
diff --git a/boost/asio/detail/impl/reactive_serial_port_service.ipp b/boost/asio/detail/impl/reactive_serial_port_service.ipp
index c1ff461830..62546604b4 100644
--- a/boost/asio/detail/impl/reactive_serial_port_service.ipp
+++ b/boost/asio/detail/impl/reactive_serial_port_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/reactive_serial_port_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -31,9 +31,9 @@ namespace asio {
namespace detail {
reactive_serial_port_service::reactive_serial_port_service(
- boost::asio::io_context& io_context)
- : service_base<reactive_serial_port_service>(io_context),
- descriptor_service_(io_context)
+ execution_context& context)
+ : execution_context_service_base<reactive_serial_port_service>(context),
+ descriptor_service_(context)
{
}
diff --git a/boost/asio/detail/impl/reactive_socket_service_base.ipp b/boost/asio/detail/impl/reactive_socket_service_base.ipp
index 6fdf437c1d..5ae4b64a6d 100644
--- a/boost/asio/detail/impl/reactive_socket_service_base.ipp
+++ b/boost/asio/detail/impl/reactive_socket_service_base.ipp
@@ -2,7 +2,7 @@
// detail/reactive_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -29,9 +29,8 @@ namespace asio {
namespace detail {
reactive_socket_service_base::reactive_socket_service_base(
- boost::asio::io_context& io_context)
- : io_context_(io_context),
- reactor_(use_service<reactor>(io_context))
+ execution_context& context)
+ : reactor_(use_service<reactor>(context))
{
reactor_.init_task();
}
diff --git a/boost/asio/detail/impl/resolver_service_base.ipp b/boost/asio/detail/impl/resolver_service_base.ipp
index 144e2a1753..64b92a89ac 100644
--- a/boost/asio/detail/impl/resolver_service_base.ipp
+++ b/boost/asio/detail/impl/resolver_service_base.ipp
@@ -2,7 +2,7 @@
// detail/impl/resolver_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,25 +24,30 @@ namespace boost {
namespace asio {
namespace detail {
-class resolver_service_base::work_io_context_runner
+class resolver_service_base::work_scheduler_runner
{
public:
- work_io_context_runner(boost::asio::io_context& io_context)
- : io_context_(io_context) {}
- void operator()() { io_context_.run(); }
+ work_scheduler_runner(scheduler_impl& work_scheduler)
+ : work_scheduler_(work_scheduler)
+ {
+ }
+
+ void operator()()
+ {
+ boost::system::error_code ec;
+ work_scheduler_.run(ec);
+ }
+
private:
- boost::asio::io_context& io_context_;
+ scheduler_impl& work_scheduler_;
};
-resolver_service_base::resolver_service_base(
- boost::asio::io_context& io_context)
- : io_context_impl_(boost::asio::use_service<io_context_impl>(io_context)),
- work_io_context_(new boost::asio::io_context(-1)),
- work_io_context_impl_(boost::asio::use_service<
- io_context_impl>(*work_io_context_)),
- work_(boost::asio::make_work_guard(*work_io_context_)),
+resolver_service_base::resolver_service_base(execution_context& context)
+ : scheduler_(boost::asio::use_service<scheduler_impl>(context)),
+ work_scheduler_(new scheduler_impl(context, -1, false)),
work_thread_(0)
{
+ work_scheduler_->work_started();
}
resolver_service_base::~resolver_service_base()
@@ -52,34 +57,35 @@ resolver_service_base::~resolver_service_base()
void resolver_service_base::base_shutdown()
{
- work_.reset();
- if (work_io_context_.get())
+ if (work_scheduler_.get())
{
- work_io_context_->stop();
+ work_scheduler_->work_finished();
+ work_scheduler_->stop();
if (work_thread_.get())
{
work_thread_->join();
work_thread_.reset();
}
- work_io_context_.reset();
+ work_scheduler_.reset();
}
}
void resolver_service_base::base_notify_fork(
- boost::asio::io_context::fork_event fork_ev)
+ execution_context::fork_event fork_ev)
{
if (work_thread_.get())
{
- if (fork_ev == boost::asio::io_context::fork_prepare)
+ if (fork_ev == execution_context::fork_prepare)
{
- work_io_context_->stop();
+ work_scheduler_->stop();
work_thread_->join();
+ work_thread_.reset();
}
else
{
- work_io_context_->restart();
+ work_scheduler_->restart();
work_thread_.reset(new boost::asio::detail::thread(
- work_io_context_runner(*work_io_context_)));
+ work_scheduler_runner(*work_scheduler_)));
}
}
}
@@ -93,7 +99,7 @@ void resolver_service_base::construct(
void resolver_service_base::destroy(
resolver_service_base::implementation_type& impl)
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_impl_.context(),
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
"resolver", &impl, 0, "cancel"));
impl.reset();
@@ -115,7 +121,7 @@ void resolver_service_base::move_assign(implementation_type& impl,
void resolver_service_base::cancel(
resolver_service_base::implementation_type& impl)
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_impl_.context(),
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
"resolver", &impl, 0, "cancel"));
impl.reset(static_cast<void*>(0), socket_ops::noop_deleter());
@@ -124,16 +130,16 @@ void resolver_service_base::cancel(
void resolver_service_base::start_resolve_op(resolve_op* op)
{
if (BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
- io_context_impl_.concurrency_hint()))
+ scheduler_.concurrency_hint()))
{
start_work_thread();
- io_context_impl_.work_started();
- work_io_context_impl_.post_immediate_completion(op, false);
+ scheduler_.work_started();
+ work_scheduler_->post_immediate_completion(op, false);
}
else
{
op->ec_ = boost::asio::error::operation_not_supported;
- io_context_impl_.post_immediate_completion(op, false);
+ scheduler_.post_immediate_completion(op, false);
}
}
@@ -143,7 +149,7 @@ void resolver_service_base::start_work_thread()
if (!work_thread_.get())
{
work_thread_.reset(new boost::asio::detail::thread(
- work_io_context_runner(*work_io_context_)));
+ work_scheduler_runner(*work_scheduler_)));
}
}
diff --git a/boost/asio/detail/impl/scheduler.ipp b/boost/asio/detail/impl/scheduler.ipp
index 9dae6836ce..4ef5c86688 100644
--- a/boost/asio/detail/impl/scheduler.ipp
+++ b/boost/asio/detail/impl/scheduler.ipp
@@ -2,7 +2,7 @@
// detail/impl/scheduler.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,6 +23,7 @@
#include <boost/asio/detail/reactor.hpp>
#include <boost/asio/detail/scheduler.hpp>
#include <boost/asio/detail/scheduler_thread_info.hpp>
+#include <boost/asio/detail/signal_blocker.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -30,6 +31,24 @@ namespace boost {
namespace asio {
namespace detail {
+class scheduler::thread_function
+{
+public:
+ explicit thread_function(scheduler* s)
+ : this_(s)
+ {
+ }
+
+ void operator()()
+ {
+ boost::system::error_code ec;
+ this_->run(ec);
+ }
+
+private:
+ scheduler* this_;
+};
+
struct scheduler::task_cleanup
{
~task_cleanup()
@@ -85,8 +104,8 @@ struct scheduler::work_cleanup
thread_info* this_thread_;
};
-scheduler::scheduler(
- boost::asio::execution_context& ctx, int concurrency_hint)
+scheduler::scheduler(boost::asio::execution_context& ctx,
+ int concurrency_hint, bool own_thread)
: boost::asio::detail::execution_context_service_base<scheduler>(ctx),
one_thread_(concurrency_hint == 1
|| !BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(
@@ -100,17 +119,44 @@ scheduler::scheduler(
outstanding_work_(0),
stopped_(false),
shutdown_(false),
- concurrency_hint_(concurrency_hint)
+ concurrency_hint_(concurrency_hint),
+ thread_(0)
{
BOOST_ASIO_HANDLER_TRACKING_INIT;
+
+ if (own_thread)
+ {
+ ++outstanding_work_;
+ boost::asio::detail::signal_blocker sb;
+ thread_ = new boost::asio::detail::thread(thread_function(this));
+ }
+}
+
+scheduler::~scheduler()
+{
+ if (thread_)
+ {
+ thread_->join();
+ delete thread_;
+ }
}
void scheduler::shutdown()
{
mutex::scoped_lock lock(mutex_);
shutdown_ = true;
+ if (thread_)
+ stop_all_threads(lock);
lock.unlock();
+ // Join thread to ensure task operation is returned to queue.
+ if (thread_)
+ {
+ thread_->join();
+ delete thread_;
+ thread_ = 0;
+ }
+
// Destroy handler objects.
while (!op_queue_.empty())
{
diff --git a/boost/asio/detail/impl/select_reactor.hpp b/boost/asio/detail/impl/select_reactor.hpp
index 0fbaeb9ced..c741492c6a 100644
--- a/boost/asio/detail/impl/select_reactor.hpp
+++ b/boost/asio/detail/impl/select_reactor.hpp
@@ -2,7 +2,7 @@
// detail/impl/select_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/select_reactor.ipp b/boost/asio/detail/impl/select_reactor.ipp
index 4f1f5a8303..34d3d9f031 100644
--- a/boost/asio/detail/impl/select_reactor.ipp
+++ b/boost/asio/detail/impl/select_reactor.ipp
@@ -2,7 +2,7 @@
// detail/impl/select_reactor.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/service_registry.hpp b/boost/asio/detail/impl/service_registry.hpp
index c50614410e..e18473c8c8 100644
--- a/boost/asio/detail/impl/service_registry.hpp
+++ b/boost/asio/detail/impl/service_registry.hpp
@@ -2,7 +2,7 @@
// detail/impl/service_registry.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/service_registry.ipp b/boost/asio/detail/impl/service_registry.ipp
index abdcd6a01a..da920fbc50 100644
--- a/boost/asio/detail/impl/service_registry.ipp
+++ b/boost/asio/detail/impl/service_registry.ipp
@@ -2,7 +2,7 @@
// detail/impl/service_registry.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/signal_set_service.ipp b/boost/asio/detail/impl/signal_set_service.ipp
index abd83b480c..5e23702bb0 100644
--- a/boost/asio/detail/impl/signal_set_service.ipp
+++ b/boost/asio/detail/impl/signal_set_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/signal_set_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -119,14 +119,13 @@ public:
// && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
// && !defined(__CYGWIN__)
-signal_set_service::signal_set_service(
- boost::asio::io_context& io_context)
- : service_base<signal_set_service>(io_context),
- io_context_(boost::asio::use_service<io_context_impl>(io_context)),
+signal_set_service::signal_set_service(execution_context& context)
+ : execution_context_service_base<signal_set_service>(context),
+ scheduler_(boost::asio::use_service<scheduler_impl>(context)),
#if !defined(BOOST_ASIO_WINDOWS) \
&& !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
&& !defined(__CYGWIN__)
- reactor_(boost::asio::use_service<reactor>(io_context)),
+ reactor_(boost::asio::use_service<reactor>(context)),
#endif // !defined(BOOST_ASIO_WINDOWS)
// && !defined(BOOST_ASIO_WINDOWS_RUNTIME)
// && !defined(__CYGWIN__)
@@ -170,11 +169,10 @@ void signal_set_service::shutdown()
}
}
- io_context_.abandon_operations(ops);
+ scheduler_.abandon_operations(ops);
}
-void signal_set_service::notify_fork(
- boost::asio::io_context::fork_event fork_ev)
+void signal_set_service::notify_fork(execution_context::fork_event fork_ev)
{
#if !defined(BOOST_ASIO_WINDOWS) \
&& !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
@@ -184,7 +182,7 @@ void signal_set_service::notify_fork(
switch (fork_ev)
{
- case boost::asio::io_context::fork_prepare:
+ case execution_context::fork_prepare:
{
int read_descriptor = state->read_descriptor_;
state->fork_prepared_ = true;
@@ -193,7 +191,7 @@ void signal_set_service::notify_fork(
reactor_.cleanup_descriptor_data(reactor_data_);
}
break;
- case boost::asio::io_context::fork_parent:
+ case execution_context::fork_parent:
if (state->fork_prepared_)
{
int read_descriptor = state->read_descriptor_;
@@ -203,7 +201,7 @@ void signal_set_service::notify_fork(
read_descriptor, reactor_data_, new pipe_read_op);
}
break;
- case boost::asio::io_context::fork_child:
+ case execution_context::fork_child:
if (state->fork_prepared_)
{
boost::asio::detail::signal_blocker blocker;
@@ -442,7 +440,7 @@ boost::system::error_code signal_set_service::cancel(
signal_set_service::implementation_type& impl,
boost::system::error_code& ec)
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(),
"signal_set", &impl, 0, "cancel"));
op_queue<operation> ops;
@@ -458,7 +456,7 @@ boost::system::error_code signal_set_service::cancel(
}
}
- io_context_.post_deferred_completions(ops);
+ scheduler_.post_deferred_completions(ops);
ec = boost::system::error_code();
return ec;
@@ -494,7 +492,7 @@ void signal_set_service::deliver_signal(int signal_number)
reg = reg->next_in_table_;
}
- service->io_context_.post_deferred_completions(ops);
+ service->scheduler_.post_deferred_completions(ops);
service = service->next_;
}
@@ -511,17 +509,17 @@ void signal_set_service::add_service(signal_set_service* service)
open_descriptors();
#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
- // If an io_context object is thread-unsafe then it must be the only
- // io_context used to create signal_set objects.
+ // If a scheduler_ object is thread-unsafe then it must be the only
+ // scheduler used to create signal_set objects.
if (state->service_list_ != 0)
{
if (!BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
- service->io_context_.concurrency_hint())
+ service->scheduler_.concurrency_hint())
|| !BOOST_ASIO_CONCURRENCY_HINT_IS_LOCKING(SCHEDULER,
- state->service_list_->io_context_.concurrency_hint()))
+ state->service_list_->scheduler_.concurrency_hint()))
{
std::logic_error ex(
- "Thread-unsafe io_context objects require "
+ "Thread-unsafe execution context objects require "
"exclusive access to signal handling.");
boost::asio::detail::throw_exception(ex);
}
@@ -640,7 +638,7 @@ void signal_set_service::close_descriptors()
void signal_set_service::start_wait_op(
signal_set_service::implementation_type& impl, signal_op* op)
{
- io_context_.work_started();
+ scheduler_.work_started();
signal_state* state = get_signal_state();
static_mutex::scoped_lock lock(state->mutex_);
@@ -652,7 +650,7 @@ void signal_set_service::start_wait_op(
{
--reg->undelivered_;
op->signal_number_ = reg->signal_number_;
- io_context_.post_deferred_completion(op);
+ scheduler_.post_deferred_completion(op);
return;
}
diff --git a/boost/asio/detail/impl/socket_ops.ipp b/boost/asio/detail/impl/socket_ops.ipp
index bb60df0a8e..7d7c31fe03 100644
--- a/boost/asio/detail/impl/socket_ops.ipp
+++ b/boost/asio/detail/impl/socket_ops.ipp
@@ -2,7 +2,7 @@
// detail/impl/socket_ops.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -772,7 +772,7 @@ signed_size_type recv(socket_type s, buf* bufs, size_t count,
else if (ec.value() == ERROR_PORT_UNREACHABLE)
ec = boost::asio::error::connection_refused;
else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA)
- ec.assign(0, ec.category());
+ result = 0;
if (result != 0)
return socket_error_retval;
ec = boost::system::error_code();
@@ -926,7 +926,7 @@ signed_size_type recvfrom(socket_type s, buf* bufs, size_t count,
else if (ec.value() == ERROR_PORT_UNREACHABLE)
ec = boost::asio::error::connection_refused;
else if (ec.value() == WSAEMSGSIZE || ec.value() == ERROR_MORE_DATA)
- ec.assign(0, ec.category());
+ result = 0;
if (result != 0)
return socket_error_retval;
ec = boost::system::error_code();
@@ -1503,7 +1503,8 @@ int setsockopt(socket_type s, state_type& state, int level, int optname,
ec = boost::system::error_code();
#if defined(__MACH__) && defined(__APPLE__) \
- || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ || defined(__NetBSD__) || defined(__FreeBSD__) \
+ || defined(__OpenBSD__) || defined(__QNX__)
// 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)
diff --git a/boost/asio/detail/impl/socket_select_interrupter.ipp b/boost/asio/detail/impl/socket_select_interrupter.ipp
index 3d9e5289d3..e09c5fbeb0 100644
--- a/boost/asio/detail/impl/socket_select_interrupter.ipp
+++ b/boost/asio/detail/impl/socket_select_interrupter.ipp
@@ -2,7 +2,7 @@
// detail/impl/socket_select_interrupter.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/strand_executor_service.hpp b/boost/asio/detail/impl/strand_executor_service.hpp
index 6452b949f4..67eb8361dd 100644
--- a/boost/asio/detail/impl/strand_executor_service.hpp
+++ b/boost/asio/detail/impl/strand_executor_service.hpp
@@ -2,7 +2,7 @@
// detail/impl/strand_executor_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/strand_executor_service.ipp b/boost/asio/detail/impl/strand_executor_service.ipp
index aed4d3cf6a..60681ea2f2 100644
--- a/boost/asio/detail/impl/strand_executor_service.ipp
+++ b/boost/asio/detail/impl/strand_executor_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/strand_executor_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/strand_service.hpp b/boost/asio/detail/impl/strand_service.hpp
index d47708bb98..7e82876ea2 100644
--- a/boost/asio/detail/impl/strand_service.hpp
+++ b/boost/asio/detail/impl/strand_service.hpp
@@ -2,7 +2,7 @@
// detail/impl/strand_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/strand_service.ipp b/boost/asio/detail/impl/strand_service.ipp
index 9926f9abf3..340f310bf6 100644
--- a/boost/asio/detail/impl/strand_service.ipp
+++ b/boost/asio/detail/impl/strand_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/strand_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/throw_error.ipp b/boost/asio/detail/impl/throw_error.ipp
index ffcacf47ae..9483bd0f59 100644
--- a/boost/asio/detail/impl/throw_error.ipp
+++ b/boost/asio/detail/impl/throw_error.ipp
@@ -2,7 +2,7 @@
// detail/impl/throw_error.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/timer_queue_ptime.ipp b/boost/asio/detail/impl/timer_queue_ptime.ipp
index 8a6d5af815..2566c9c2ca 100644
--- a/boost/asio/detail/impl/timer_queue_ptime.ipp
+++ b/boost/asio/detail/impl/timer_queue_ptime.ipp
@@ -2,7 +2,7 @@
// detail/impl/timer_queue_ptime.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/timer_queue_set.ipp b/boost/asio/detail/impl/timer_queue_set.ipp
index 71f83216aa..b738142f28 100644
--- a/boost/asio/detail/impl/timer_queue_set.ipp
+++ b/boost/asio/detail/impl/timer_queue_set.ipp
@@ -2,7 +2,7 @@
// detail/impl/timer_queue_set.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_event.ipp b/boost/asio/detail/impl/win_event.ipp
index 3e7dfdcf21..c6e1e3582f 100644
--- a/boost/asio/detail/impl/win_event.ipp
+++ b/boost/asio/detail/impl/win_event.ipp
@@ -2,7 +2,7 @@
// detail/win_event.ipp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_iocp_handle_service.ipp b/boost/asio/detail/impl/win_iocp_handle_service.ipp
index 0cd7dd1719..1256c358ac 100644
--- a/boost/asio/detail/impl/win_iocp_handle_service.ipp
+++ b/boost/asio/detail/impl/win_iocp_handle_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_handle_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -66,10 +66,9 @@ public:
}
};
-win_iocp_handle_service::win_iocp_handle_service(
- boost::asio::io_context& io_context)
- : service_base<win_iocp_handle_service>(io_context),
- iocp_service_(boost::asio::use_service<win_iocp_io_context>(io_context)),
+win_iocp_handle_service::win_iocp_handle_service(execution_context& context)
+ : execution_context_service_base<win_iocp_handle_service>(context),
+ iocp_service_(boost::asio::use_service<win_iocp_io_context>(context)),
mutex_(),
impl_list_(0)
{
diff --git a/boost/asio/detail/impl/win_iocp_io_context.hpp b/boost/asio/detail/impl/win_iocp_io_context.hpp
index 771c1f3c3a..830a07dcd9 100644
--- a/boost/asio/detail/impl/win_iocp_io_context.hpp
+++ b/boost/asio/detail/impl/win_iocp_io_context.hpp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_io_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_iocp_io_context.ipp b/boost/asio/detail/impl/win_iocp_io_context.ipp
index 87637f0b5c..5bdc540972 100644
--- a/boost/asio/detail/impl/win_iocp_io_context.ipp
+++ b/boost/asio/detail/impl/win_iocp_io_context.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_io_context.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,6 +24,7 @@
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/limits.hpp>
+#include <boost/asio/detail/thread.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/win_iocp_io_context.hpp>
@@ -33,6 +34,22 @@ namespace boost {
namespace asio {
namespace detail {
+struct win_iocp_io_context::thread_function
+{
+ explicit thread_function(win_iocp_io_context* s)
+ : this_(s)
+ {
+ }
+
+ void operator()()
+ {
+ boost::system::error_code ec;
+ this_->run(ec);
+ }
+
+ win_iocp_io_context* this_;
+};
+
struct win_iocp_io_context::work_finished_on_block_exit
{
~work_finished_on_block_exit()
@@ -63,7 +80,7 @@ struct win_iocp_io_context::timer_thread_function
};
win_iocp_io_context::win_iocp_io_context(
- boost::asio::execution_context& ctx, int concurrency_hint)
+ boost::asio::execution_context& ctx, int concurrency_hint, bool own_thread)
: execution_context_service_base<win_iocp_io_context>(ctx),
iocp_(),
outstanding_work_(0),
@@ -85,6 +102,21 @@ win_iocp_io_context::win_iocp_io_context(
boost::asio::error::get_system_category());
boost::asio::detail::throw_error(ec, "iocp");
}
+
+ if (own_thread)
+ {
+ ::InterlockedIncrement(&outstanding_work_);
+ thread_.reset(new boost::asio::detail::thread(thread_function(this)));
+ }
+}
+
+win_iocp_io_context::~win_iocp_io_context()
+{
+ if (thread_.get())
+ {
+ thread_->join();
+ thread_.reset();
+ }
}
void win_iocp_io_context::shutdown()
@@ -98,6 +130,13 @@ void win_iocp_io_context::shutdown()
::SetWaitableTimer(waitable_timer_.handle, &timeout, 1, 0, 0, FALSE);
}
+ if (thread_.get())
+ {
+ thread_->join();
+ thread_.reset();
+ ::InterlockedDecrement(&outstanding_work_);
+ }
+
while (::InterlockedExchangeAdd(&outstanding_work_, 0) > 0)
{
op_queue<win_iocp_operation> ops;
diff --git a/boost/asio/detail/impl/win_iocp_serial_port_service.ipp b/boost/asio/detail/impl/win_iocp_serial_port_service.ipp
index 7dbf9353ee..4e30b0f678 100644
--- a/boost/asio/detail/impl/win_iocp_serial_port_service.ipp
+++ b/boost/asio/detail/impl/win_iocp_serial_port_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_serial_port_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -30,9 +30,9 @@ namespace asio {
namespace detail {
win_iocp_serial_port_service::win_iocp_serial_port_service(
- boost::asio::io_context& io_context)
- : service_base<win_iocp_serial_port_service>(io_context),
- handle_service_(io_context)
+ execution_context& context)
+ : execution_context_service_base<win_iocp_serial_port_service>(context),
+ handle_service_(context)
{
}
diff --git a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
index 3b7e7066f5..f95c74ff58 100644
--- a/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
+++ b/boost/asio/detail/impl/win_iocp_socket_service_base.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_iocp_socket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,9 +28,9 @@ namespace asio {
namespace detail {
win_iocp_socket_service_base::win_iocp_socket_service_base(
- boost::asio::io_context& io_context)
- : io_context_(io_context),
- iocp_service_(use_service<win_iocp_io_context>(io_context)),
+ execution_context& context)
+ : context_(context),
+ iocp_service_(use_service<win_iocp_io_context>(context)),
reactor_(0),
connect_ex_(0),
nt_set_info_(0),
@@ -708,7 +708,7 @@ select_reactor& win_iocp_socket_service_base::get_reactor()
reinterpret_cast<void**>(&reactor_), 0, 0));
if (!r)
{
- r = &(use_service<select_reactor>(io_context_));
+ r = &(use_service<select_reactor>(context_));
interlocked_exchange_pointer(reinterpret_cast<void**>(&reactor_), r);
}
return *r;
diff --git a/boost/asio/detail/impl/win_mutex.ipp b/boost/asio/detail/impl/win_mutex.ipp
index 12922263f2..809d40f159 100644
--- a/boost/asio/detail/impl/win_mutex.ipp
+++ b/boost/asio/detail/impl/win_mutex.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_object_handle_service.ipp b/boost/asio/detail/impl/win_object_handle_service.ipp
index db56f722f2..f356a00613 100644
--- a/boost/asio/detail/impl/win_object_handle_service.ipp
+++ b/boost/asio/detail/impl/win_object_handle_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_object_handle_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -28,10 +28,9 @@ namespace boost {
namespace asio {
namespace detail {
-win_object_handle_service::win_object_handle_service(
- boost::asio::io_context& io_context)
- : service_base<win_object_handle_service>(io_context),
- io_context_(boost::asio::use_service<io_context_impl>(io_context)),
+win_object_handle_service::win_object_handle_service(execution_context& context)
+ : execution_context_service_base<win_object_handle_service>(context),
+ scheduler_(boost::asio::use_service<scheduler_impl>(context)),
mutex_(),
impl_list_(0),
shutdown_(false)
@@ -53,7 +52,7 @@ void win_object_handle_service::shutdown()
lock.unlock();
- io_context_.abandon_operations(ops);
+ scheduler_.abandon_operations(ops);
}
void win_object_handle_service::construct(
@@ -179,7 +178,7 @@ void win_object_handle_service::destroy(
if (is_open(impl))
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_.context(), "object_handle",
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle",
&impl, reinterpret_cast<uintmax_t>(impl.wait_handle_), "close"));
HANDLE wait_handle = impl.wait_handle_;
@@ -204,7 +203,7 @@ void win_object_handle_service::destroy(
::CloseHandle(impl.handle_);
impl.handle_ = INVALID_HANDLE_VALUE;
- io_context_.post_deferred_completions(ops);
+ scheduler_.post_deferred_completions(ops);
}
}
@@ -229,7 +228,7 @@ boost::system::error_code win_object_handle_service::close(
{
if (is_open(impl))
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_.context(), "object_handle",
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle",
&impl, reinterpret_cast<uintmax_t>(impl.wait_handle_), "close"));
mutex::scoped_lock lock(mutex_);
@@ -265,7 +264,7 @@ boost::system::error_code win_object_handle_service::close(
boost::asio::error::get_system_category());
}
- io_context_.post_deferred_completions(completed_ops);
+ scheduler_.post_deferred_completions(completed_ops);
}
else
{
@@ -281,7 +280,7 @@ boost::system::error_code win_object_handle_service::cancel(
{
if (is_open(impl))
{
- BOOST_ASIO_HANDLER_OPERATION((io_context_.context(), "object_handle",
+ BOOST_ASIO_HANDLER_OPERATION((scheduler_.context(), "object_handle",
&impl, reinterpret_cast<uintmax_t>(impl.wait_handle_), "cancel"));
mutex::scoped_lock lock(mutex_);
@@ -307,7 +306,7 @@ boost::system::error_code win_object_handle_service::cancel(
ec = boost::system::error_code();
- io_context_.post_deferred_completions(completed_ops);
+ scheduler_.post_deferred_completions(completed_ops);
}
else
{
@@ -341,7 +340,7 @@ void win_object_handle_service::wait(
void win_object_handle_service::start_wait_op(
win_object_handle_service::implementation_type& impl, wait_op* op)
{
- io_context_.work_started();
+ scheduler_.work_started();
if (is_open(impl))
{
@@ -359,13 +358,13 @@ void win_object_handle_service::start_wait_op(
else
{
lock.unlock();
- io_context_.post_deferred_completion(op);
+ scheduler_.post_deferred_completion(op);
}
}
else
{
op->ec_ = boost::asio::error::bad_descriptor;
- io_context_.post_deferred_completion(op);
+ scheduler_.post_deferred_completion(op);
}
}
@@ -392,7 +391,7 @@ void win_object_handle_service::register_wait_callback(
}
lock.unlock();
- io_context_.post_deferred_completions(completed_ops);
+ scheduler_.post_deferred_completions(completed_ops);
}
}
@@ -434,9 +433,9 @@ void win_object_handle_service::wait_callback(PVOID param, BOOLEAN)
}
}
- io_context_impl& ioc = impl->owner_->io_context_;
+ scheduler_impl& sched = impl->owner_->scheduler_;
lock.unlock();
- ioc.post_deferred_completions(completed_ops);
+ sched.post_deferred_completions(completed_ops);
}
}
diff --git a/boost/asio/detail/impl/win_static_mutex.ipp b/boost/asio/detail/impl/win_static_mutex.ipp
index 10e8622e37..ae53dbe105 100644
--- a/boost/asio/detail/impl/win_static_mutex.ipp
+++ b/boost/asio/detail/impl/win_static_mutex.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_static_mutex.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_thread.ipp b/boost/asio/detail/impl/win_thread.ipp
index 710c9b9f9b..13faa0753e 100644
--- a/boost/asio/detail/impl/win_thread.ipp
+++ b/boost/asio/detail/impl/win_thread.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_thread.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/win_tss_ptr.ipp b/boost/asio/detail/impl/win_tss_ptr.ipp
index 755d020703..8c6c5c60d7 100644
--- a/boost/asio/detail/impl/win_tss_ptr.ipp
+++ b/boost/asio/detail/impl/win_tss_ptr.ipp
@@ -2,7 +2,7 @@
// detail/impl/win_tss_ptr.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/impl/winrt_ssocket_service_base.ipp b/boost/asio/detail/impl/winrt_ssocket_service_base.ipp
index e6254aed93..1728281091 100644
--- a/boost/asio/detail/impl/winrt_ssocket_service_base.ipp
+++ b/boost/asio/detail/impl/winrt_ssocket_service_base.ipp
@@ -2,7 +2,7 @@
// detail/impl/winrt_ssocket_service_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -31,9 +31,9 @@ namespace asio {
namespace detail {
winrt_ssocket_service_base::winrt_ssocket_service_base(
- boost::asio::io_context& io_context)
- : io_context_(use_service<io_context_impl>(io_context)),
- async_manager_(use_service<winrt_async_manager>(io_context)),
+ execution_context& context)
+ : scheduler_(use_service<scheduler_impl>(context)),
+ async_manager_(use_service<winrt_async_manager>(context)),
mutex_(),
impl_list_(0)
{
@@ -399,7 +399,7 @@ void winrt_ssocket_service_base::start_connect_op(
if (!is_open(impl))
{
op->ec_ = boost::asio::error::bad_descriptor;
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -428,7 +428,7 @@ void winrt_ssocket_service_base::start_connect_op(
if (op->ec_)
{
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -443,7 +443,7 @@ void winrt_ssocket_service_base::start_connect_op(
{
op->ec_ = boost::system::error_code(
e->HResult, boost::system::system_category());
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
}
}
@@ -494,14 +494,14 @@ void winrt_ssocket_service_base::start_send_op(
if (flags)
{
op->ec_ = boost::asio::error::operation_not_supported;
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
if (!is_open(impl))
{
op->ec_ = boost::asio::error::bad_descriptor;
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -512,7 +512,7 @@ void winrt_ssocket_service_base::start_send_op(
if (bufs.all_empty())
{
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -523,7 +523,7 @@ void winrt_ssocket_service_base::start_send_op(
{
op->ec_ = boost::system::error_code(e->HResult,
boost::system::system_category());
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
}
}
@@ -585,14 +585,14 @@ void winrt_ssocket_service_base::start_receive_op(
if (flags)
{
op->ec_ = boost::asio::error::operation_not_supported;
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
if (!is_open(impl))
{
op->ec_ = boost::asio::error::bad_descriptor;
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -603,7 +603,7 @@ void winrt_ssocket_service_base::start_receive_op(
if (bufs.all_empty())
{
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
return;
}
@@ -616,7 +616,7 @@ void winrt_ssocket_service_base::start_receive_op(
{
op->ec_ = boost::system::error_code(e->HResult,
boost::system::system_category());
- io_context_.post_immediate_completion(op, is_continuation);
+ scheduler_.post_immediate_completion(op, is_continuation);
}
}
diff --git a/boost/asio/detail/impl/winrt_timer_scheduler.hpp b/boost/asio/detail/impl/winrt_timer_scheduler.hpp
index a475f66640..89ac7a123c 100644
--- a/boost/asio/detail/impl/winrt_timer_scheduler.hpp
+++ b/boost/asio/detail/impl/winrt_timer_scheduler.hpp
@@ -2,7 +2,7 @@
// detail/impl/winrt_timer_scheduler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -47,12 +47,12 @@ void winrt_timer_scheduler::schedule_timer(timer_queue<Time_Traits>& queue,
if (shutdown_)
{
- io_context_.post_immediate_completion(op, false);
+ scheduler_.post_immediate_completion(op, false);
return;
}
bool earliest = queue.enqueue_timer(time, timer, op);
- io_context_.work_started();
+ scheduler_.work_started();
if (earliest)
event_.signal(lock);
}
@@ -66,7 +66,7 @@ std::size_t winrt_timer_scheduler::cancel_timer(timer_queue<Time_Traits>& queue,
op_queue<operation> ops;
std::size_t n = queue.cancel_timer(timer, ops, max_cancelled);
lock.unlock();
- io_context_.post_deferred_completions(ops);
+ scheduler_.post_deferred_completions(ops);
return n;
}
diff --git a/boost/asio/detail/impl/winrt_timer_scheduler.ipp b/boost/asio/detail/impl/winrt_timer_scheduler.ipp
index c8b77349cd..48cb29c42e 100644
--- a/boost/asio/detail/impl/winrt_timer_scheduler.ipp
+++ b/boost/asio/detail/impl/winrt_timer_scheduler.ipp
@@ -2,7 +2,7 @@
// detail/impl/winrt_timer_scheduler.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,10 +28,9 @@ namespace boost {
namespace asio {
namespace detail {
-winrt_timer_scheduler::winrt_timer_scheduler(
- boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<winrt_timer_scheduler>(io_context),
- io_context_(use_service<io_context_impl>(io_context)),
+winrt_timer_scheduler::winrt_timer_scheduler(execution_context& context)
+ : execution_context_service_base<winrt_timer_scheduler>(context),
+ scheduler_(use_service<scheduler_impl>(context)),
mutex_(),
event_(),
timer_queues_(),
@@ -65,10 +64,10 @@ void winrt_timer_scheduler::shutdown()
op_queue<operation> ops;
timer_queues_.get_all_timers(ops);
- io_context_.abandon_operations(ops);
+ scheduler_.abandon_operations(ops);
}
-void winrt_timer_scheduler::notify_fork(boost::asio::io_context::fork_event)
+void winrt_timer_scheduler::notify_fork(execution_context::fork_event)
{
}
@@ -90,7 +89,7 @@ void winrt_timer_scheduler::run_thread()
if (!ops.empty())
{
lock.unlock();
- io_context_.post_deferred_completions(ops);
+ scheduler_.post_deferred_completions(ops);
lock.lock();
}
}
diff --git a/boost/asio/detail/impl/winsock_init.ipp b/boost/asio/detail/impl/winsock_init.ipp
index 5d31a03b06..85b50df5d0 100644
--- a/boost/asio/detail/impl/winsock_init.ipp
+++ b/boost/asio/detail/impl/winsock_init.ipp
@@ -2,7 +2,7 @@
// detail/impl/winsock_init.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/io_control.hpp b/boost/asio/detail/io_control.hpp
index 112b0ad751..4f091dba08 100644
--- a/boost/asio/detail/io_control.hpp
+++ b/boost/asio/detail/io_control.hpp
@@ -2,7 +2,7 @@
// detail/io_control.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/io_object_executor.hpp b/boost/asio/detail/io_object_executor.hpp
new file mode 100644
index 0000000000..70b026b476
--- /dev/null
+++ b/boost/asio/detail/io_object_executor.hpp
@@ -0,0 +1,162 @@
+//
+// io_object_executor.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_IO_OBJECT_EXECUTOR_HPP
+#define BOOST_ASIO_DETAIL_IO_OBJECT_EXECUTOR_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/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// Wrap the (potentially polymorphic) executor so that we can bypass it when
+// dispatching on a target executor that has a native I/O implementation.
+template <typename Executor>
+class io_object_executor
+{
+public:
+ io_object_executor(const Executor& ex,
+ bool native_implementation) BOOST_ASIO_NOEXCEPT
+ : executor_(ex),
+ has_native_impl_(native_implementation)
+ {
+ }
+
+ io_object_executor(const io_object_executor& other) BOOST_ASIO_NOEXCEPT
+ : executor_(other.executor_),
+ has_native_impl_(other.has_native_impl_)
+ {
+ }
+
+ template <typename Executor1>
+ io_object_executor(
+ const io_object_executor<Executor1>& other) BOOST_ASIO_NOEXCEPT
+ : executor_(other.inner_executor()),
+ has_native_impl_(other.has_native_implementation())
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ io_object_executor(io_object_executor&& other) BOOST_ASIO_NOEXCEPT
+ : executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
+ has_native_impl_(other.has_native_impl_)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ const Executor& inner_executor() const BOOST_ASIO_NOEXCEPT
+ {
+ return executor_;
+ }
+
+ bool has_native_implementation() const BOOST_ASIO_NOEXCEPT
+ {
+ return has_native_impl_;
+ }
+
+ execution_context& context() const BOOST_ASIO_NOEXCEPT
+ {
+ return executor_.context();
+ }
+
+ void on_work_started() const BOOST_ASIO_NOEXCEPT
+ {
+ if (is_same<Executor, io_context::executor_type>::value
+ || has_native_impl_)
+ {
+ // When using a native implementation, work is already counted by the
+ // execution context.
+ }
+ else
+ {
+ executor_.on_work_started();
+ }
+ }
+
+ void on_work_finished() const BOOST_ASIO_NOEXCEPT
+ {
+ if (is_same<Executor, io_context::executor_type>::value
+ || has_native_impl_)
+ {
+ // When using a native implementation, work is already counted by the
+ // execution context.
+ }
+ else
+ {
+ executor_.on_work_finished();
+ }
+ }
+
+ template <typename F, typename A>
+ void dispatch(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
+ {
+ if (is_same<Executor, io_context::executor_type>::value
+ || has_native_impl_)
+ {
+ // When using a native implementation, I/O completion handlers are
+ // already dispatched according to the execution context's executor's
+ // rules. We can call the function directly.
+ typename decay<F>::type function(BOOST_ASIO_MOVE_CAST(F)(f));
+ boost_asio_handler_invoke_helpers::invoke(function, function);
+ }
+ else
+ {
+ executor_.dispatch(BOOST_ASIO_MOVE_CAST(F)(f), a);
+ }
+ }
+
+ template <typename F, typename A>
+ void post(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
+ {
+ executor_.post(BOOST_ASIO_MOVE_CAST(F)(f), a);
+ }
+
+ template <typename F, typename A>
+ void defer(BOOST_ASIO_MOVE_ARG(F) f, const A& a) const
+ {
+ executor_.defer(BOOST_ASIO_MOVE_CAST(F)(f), a);
+ }
+
+ friend bool operator==(const io_object_executor& a,
+ const io_object_executor& b) BOOST_ASIO_NOEXCEPT
+ {
+ return a.executor_ == b.executor_
+ && a.has_native_impl_ == b.has_native_impl_;
+ }
+
+ friend bool operator!=(const io_object_executor& a,
+ const io_object_executor& b) BOOST_ASIO_NOEXCEPT
+ {
+ return a.executor_ != b.executor_
+ || a.has_native_impl_ != b.has_native_impl_;
+ }
+
+private:
+ Executor executor_;
+ const bool has_native_impl_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IO_OBJECT_EXECUTOR_HPP
diff --git a/boost/asio/detail/io_object_impl.hpp b/boost/asio/detail/io_object_impl.hpp
new file mode 100644
index 0000000000..be1a5e2ac2
--- /dev/null
+++ b/boost/asio/detail/io_object_impl.hpp
@@ -0,0 +1,195 @@
+//
+// io_object_impl.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_IO_OBJECT_IMPL_HPP
+#define BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <new>
+#include <boost/asio/detail/config.hpp>
+#include <boost/asio/detail/io_object_executor.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/io_context.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+class executor;
+
+namespace detail {
+
+inline bool is_native_io_executor(const io_context::executor_type&)
+{
+ return true;
+}
+
+template <typename Executor>
+inline bool is_native_io_executor(const Executor&,
+ typename enable_if<!is_same<Executor, executor>::value>::type* = 0)
+{
+ return false;
+}
+
+template <typename Executor>
+inline bool is_native_io_executor(const Executor& ex,
+ typename enable_if<is_same<Executor, executor>::value>::type* = 0)
+{
+#if !defined (BOOST_ASIO_NO_TYPEID)
+ return ex.target_type() == typeid(io_context::executor_type);
+#else // !defined (BOOST_ASIO_NO_TYPEID)
+ return false;
+#endif // !defined (BOOST_ASIO_NO_TYPEID)
+}
+
+template <typename IoObjectService,
+ typename Executor = io_context::executor_type>
+class io_object_impl
+{
+public:
+ // The type of the service that will be used to provide I/O operations.
+ typedef IoObjectService service_type;
+
+ // The underlying implementation type of I/O object.
+ typedef typename service_type::implementation_type implementation_type;
+
+ // The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ // The type of executor to be used when implementing asynchronous operations.
+ typedef io_object_executor<Executor> implementation_executor_type;
+
+ // Construct an I/O object using an executor.
+ explicit io_object_impl(const executor_type& ex)
+ : service_(&boost::asio::use_service<IoObjectService>(ex.context())),
+ implementation_executor_(ex, (is_native_io_executor)(ex))
+ {
+ service_->construct(implementation_);
+ }
+
+ // Construct an I/O object using an execution context.
+ template <typename ExecutionContext>
+ explicit io_object_impl(ExecutionContext& context,
+ typename enable_if<is_convertible<
+ ExecutionContext&, execution_context&>::value>::type* = 0)
+ : service_(&boost::asio::use_service<IoObjectService>(context)),
+ implementation_executor_(context.get_executor(),
+ is_same<ExecutionContext, io_context>::value)
+ {
+ service_->construct(implementation_);
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ // Move-construct an I/O object.
+ io_object_impl(io_object_impl&& other)
+ : service_(&other.get_service()),
+ implementation_executor_(other.get_implementation_executor())
+ {
+ service_->move_construct(implementation_, other.implementation_);
+ }
+
+ // Perform a converting move-construction of an I/O object.
+ template <typename IoObjectService1, typename Executor1>
+ io_object_impl(io_object_impl<IoObjectService1, Executor1>&& other)
+ : service_(&boost::asio::use_service<IoObjectService>(
+ other.get_implementation_executor().context())),
+ implementation_executor_(other.get_implementation_executor())
+ {
+ service_->converting_move_construct(implementation_,
+ other.get_service(), other.get_implementation());
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ // Destructor.
+ ~io_object_impl()
+ {
+ service_->destroy(implementation_);
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ // Move-assign an I/O object.
+ io_object_impl& operator=(io_object_impl&& other)
+ {
+ if (this != &other)
+ {
+ service_->move_assign(implementation_,
+ *other.service_, other.implementation_);
+ implementation_executor_.~implementation_executor_type();
+ new (&implementation_executor_) implementation_executor_type(
+ std::move(other.implementation_executor_));
+ service_ = other.service_;
+ }
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ // Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return implementation_executor_.inner_executor();
+ }
+
+ // Get the executor to be used when implementing asynchronous operations.
+ const implementation_executor_type& get_implementation_executor()
+ BOOST_ASIO_NOEXCEPT
+ {
+ return implementation_executor_;
+ }
+
+ // Get the service associated with the I/O object.
+ service_type& get_service()
+ {
+ return *service_;
+ }
+
+ // Get the service associated with the I/O object.
+ const service_type& get_service() const
+ {
+ return *service_;
+ }
+
+ // Get the underlying implementation of the I/O object.
+ implementation_type& get_implementation()
+ {
+ return implementation_;
+ }
+
+ // Get the underlying implementation of the I/O object.
+ const implementation_type& get_implementation() const
+ {
+ return implementation_;
+ }
+
+private:
+ // Disallow copying and copy assignment.
+ io_object_impl(const io_object_impl&);
+ io_object_impl& operator=(const io_object_impl&);
+
+ // The service associated with the I/O object.
+ service_type* service_;
+
+ // The underlying implementation of the I/O object.
+ implementation_type implementation_;
+
+ // The associated executor.
+ implementation_executor_type implementation_executor_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_IO_OBJECT_IMPL_HPP
diff --git a/boost/asio/detail/is_buffer_sequence.hpp b/boost/asio/detail/is_buffer_sequence.hpp
index a3fb9931d2..89b8df762d 100644
--- a/boost/asio/detail/is_buffer_sequence.hpp
+++ b/boost/asio/detail/is_buffer_sequence.hpp
@@ -2,7 +2,7 @@
// detail/is_buffer_sequence.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -39,6 +39,8 @@ struct buffer_sequence_memfns_base
void prepare();
void commit();
void consume();
+ void grow();
+ void shrink();
};
template <typename T>
@@ -157,6 +159,24 @@ char consume_memfn_helper(
void (buffer_sequence_memfns_base::*)(),
&buffer_sequence_memfns_derived<T>::consume>*);
+template <typename>
+char (&grow_memfn_helper(...))[2];
+
+template <typename T>
+char grow_memfn_helper(
+ buffer_sequence_memfns_check<
+ void (buffer_sequence_memfns_base::*)(),
+ &buffer_sequence_memfns_derived<T>::grow>*);
+
+template <typename>
+char (&shrink_memfn_helper(...))[2];
+
+template <typename T>
+char shrink_memfn_helper(
+ buffer_sequence_memfns_check<
+ void (buffer_sequence_memfns_base::*)(),
+ &buffer_sequence_memfns_derived<T>::shrink>*);
+
template <typename, typename>
char (&buffer_sequence_element_type_helper(...))[2];
@@ -234,7 +254,7 @@ struct is_buffer_sequence<const_buffer, mutable_buffer>
};
template <typename T>
-struct is_dynamic_buffer_class
+struct is_dynamic_buffer_class_v1
: integral_constant<bool,
sizeof(size_memfn_helper<T>(0)) != 1 &&
sizeof(max_size_memfn_helper<T>(0)) != 1 &&
@@ -249,9 +269,32 @@ struct is_dynamic_buffer_class
};
template <typename T>
-struct is_dynamic_buffer
+struct is_dynamic_buffer_v1
+ : conditional<is_class<T>::value,
+ is_dynamic_buffer_class_v1<T>,
+ false_type>::type
+{
+};
+
+template <typename T>
+struct is_dynamic_buffer_class_v2
+ : integral_constant<bool,
+ sizeof(size_memfn_helper<T>(0)) != 1 &&
+ sizeof(max_size_memfn_helper<T>(0)) != 1 &&
+ sizeof(capacity_memfn_helper<T>(0)) != 1 &&
+ sizeof(data_memfn_helper<T>(0)) != 1 &&
+ sizeof(consume_memfn_helper<T>(0)) != 1 &&
+ sizeof(grow_memfn_helper<T>(0)) != 1 &&
+ sizeof(shrink_memfn_helper<T>(0)) != 1 &&
+ sizeof(const_buffers_type_typedef_helper<T>(0)) == 1 &&
+ sizeof(mutable_buffers_type_typedef_helper<T>(0)) == 1>
+{
+};
+
+template <typename T>
+struct is_dynamic_buffer_v2
: conditional<is_class<T>::value,
- is_dynamic_buffer_class<T>,
+ is_dynamic_buffer_class_v2<T>,
false_type>::type
{
};
diff --git a/boost/asio/detail/is_executor.hpp b/boost/asio/detail/is_executor.hpp
index bc52ee87ce..ffcbb973f1 100644
--- a/boost/asio/detail/is_executor.hpp
+++ b/boost/asio/detail/is_executor.hpp
@@ -2,7 +2,7 @@
// detail/is_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/keyword_tss_ptr.hpp b/boost/asio/detail/keyword_tss_ptr.hpp
index 8451b17510..b8770040a9 100644
--- a/boost/asio/detail/keyword_tss_ptr.hpp
+++ b/boost/asio/detail/keyword_tss_ptr.hpp
@@ -2,7 +2,7 @@
// detail/keyword_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/kqueue_reactor.hpp b/boost/asio/detail/kqueue_reactor.hpp
index 31d79ca6a4..a5de8fa901 100644
--- a/boost/asio/detail/kqueue_reactor.hpp
+++ b/boost/asio/detail/kqueue_reactor.hpp
@@ -2,7 +2,7 @@
// detail/kqueue_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
diff --git a/boost/asio/detail/local_free_on_block_exit.hpp b/boost/asio/detail/local_free_on_block_exit.hpp
index 0f1a84108c..bcf65bed14 100644
--- a/boost/asio/detail/local_free_on_block_exit.hpp
+++ b/boost/asio/detail/local_free_on_block_exit.hpp
@@ -2,7 +2,7 @@
// detail/local_free_on_block_exit.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/macos_fenced_block.hpp b/boost/asio/detail/macos_fenced_block.hpp
index 20196a78f6..639fc65a63 100644
--- a/boost/asio/detail/macos_fenced_block.hpp
+++ b/boost/asio/detail/macos_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/macos_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/memory.hpp b/boost/asio/detail/memory.hpp
index 21a68e456f..a18b4d9acc 100644
--- a/boost/asio/detail/memory.hpp
+++ b/boost/asio/detail/memory.hpp
@@ -2,7 +2,7 @@
// detail/memory.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/mutex.hpp b/boost/asio/detail/mutex.hpp
index 9fe4ad333e..e5e75263b5 100644
--- a/boost/asio/detail/mutex.hpp
+++ b/boost/asio/detail/mutex.hpp
@@ -2,7 +2,7 @@
// detail/mutex.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/non_const_lvalue.hpp b/boost/asio/detail/non_const_lvalue.hpp
new file mode 100644
index 0000000000..28e2a52bbe
--- /dev/null
+++ b/boost/asio/detail/non_const_lvalue.hpp
@@ -0,0 +1,56 @@
+//
+// detail/non_const_lvalue.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_NON_CONST_LVALUE_HPP
+#define BOOST_ASIO_DETAIL_NON_CONST_LVALUE_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/type_traits.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T>
+struct non_const_lvalue
+{
+#if defined(BOOST_ASIO_HAS_MOVE)
+ explicit non_const_lvalue(T& t)
+ : value(static_cast<typename conditional<
+ is_same<T, typename decay<T>::type>::value,
+ typename decay<T>::type&, T&&>::type>(t))
+ {
+ }
+
+ typename conditional<is_same<T, typename decay<T>::type>::value,
+ typename decay<T>::type&, typename decay<T>::type>::type value;
+#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ explicit non_const_lvalue(const typename decay<T>::type& t)
+ : value(t)
+ {
+ }
+
+ typename decay<T>::type value;
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_DETAIL_NON_CONST_LVALUE_HPP
diff --git a/boost/asio/detail/noncopyable.hpp b/boost/asio/detail/noncopyable.hpp
index 36b30c074d..77cc71cb4d 100644
--- a/boost/asio/detail/noncopyable.hpp
+++ b/boost/asio/detail/noncopyable.hpp
@@ -2,7 +2,7 @@
// detail/noncopyable.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_event.hpp b/boost/asio/detail/null_event.hpp
index 8394028e41..8ffc17c86c 100644
--- a/boost/asio/detail/null_event.hpp
+++ b/boost/asio/detail/null_event.hpp
@@ -2,7 +2,7 @@
// detail/null_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_fenced_block.hpp b/boost/asio/detail/null_fenced_block.hpp
index f9f59af3a9..8fadff6906 100644
--- a/boost/asio/detail/null_fenced_block.hpp
+++ b/boost/asio/detail/null_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/null_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_global.hpp b/boost/asio/detail/null_global.hpp
index 3a4d516889..12303c295b 100644
--- a/boost/asio/detail/null_global.hpp
+++ b/boost/asio/detail/null_global.hpp
@@ -2,7 +2,7 @@
// detail/null_global.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_mutex.hpp b/boost/asio/detail/null_mutex.hpp
index 90b92fe77b..7373675a03 100644
--- a/boost/asio/detail/null_mutex.hpp
+++ b/boost/asio/detail/null_mutex.hpp
@@ -2,7 +2,7 @@
// detail/null_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_reactor.hpp b/boost/asio/detail/null_reactor.hpp
index 028f0f3535..4552e1cd89 100644
--- a/boost/asio/detail/null_reactor.hpp
+++ b/boost/asio/detail/null_reactor.hpp
@@ -2,7 +2,7 @@
// detail/null_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_signal_blocker.hpp b/boost/asio/detail/null_signal_blocker.hpp
index b2285c1f45..74f5b75a54 100644
--- a/boost/asio/detail/null_signal_blocker.hpp
+++ b/boost/asio/detail/null_signal_blocker.hpp
@@ -2,7 +2,7 @@
// detail/null_signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_socket_service.hpp b/boost/asio/detail/null_socket_service.hpp
index 2c5b784125..552d993308 100644
--- a/boost/asio/detail/null_socket_service.hpp
+++ b/boost/asio/detail/null_socket_service.hpp
@@ -2,7 +2,7 @@
// detail/null_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,7 +21,8 @@
#include <boost/asio/buffer.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/post.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/bind_handler.hpp>
@@ -33,7 +34,7 @@ namespace detail {
template <typename Protocol>
class null_socket_service :
- public service_base<null_socket_service<Protocol> >
+ public execution_context_service_base<null_socket_service<Protocol> >
{
public:
// The protocol type.
@@ -51,9 +52,8 @@ public:
};
// Constructor.
- null_socket_service(boost::asio::io_context& io_context)
- : service_base<null_socket_service<Protocol> >(io_context),
- io_context_(io_context)
+ null_socket_service(execution_context& context)
+ : execution_context_service_base<null_socket_service<Protocol> >(context)
{
}
@@ -273,23 +273,25 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send(implementation_type&, const ConstBufferSequence&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send(implementation_type&, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Receive some data from the peer. Returns the number of bytes received.
@@ -311,23 +313,26 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive(implementation_type&, const MutableBufferSequence&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Wait until data can be received without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_receive(implementation_type&, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Receive some data with associated flags. Returns the number of bytes
@@ -352,25 +357,28 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive_with_flags(implementation_type&,
const MutableBufferSequence&, socket_base::message_flags,
- socket_base::message_flags&, Handler& handler)
+ socket_base::message_flags&, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Wait until data can be received without blocking.
- template <typename Handler>
- void async_receive_with_flags(implementation_type&,
- const null_buffers&, socket_base::message_flags,
- socket_base::message_flags&, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_receive_with_flags(implementation_type&, const null_buffers&,
+ socket_base::message_flags, socket_base::message_flags&,
+ Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Send a datagram to the specified endpoint. Returns the number of bytes
@@ -395,24 +403,27 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send_to(implementation_type&, const ConstBufferSequence&,
const endpoint_type&, socket_base::message_flags,
Handler& handler)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send_to(implementation_type&, const null_buffers&,
- const endpoint_type&, socket_base::message_flags, Handler& handler)
+ const endpoint_type&, socket_base::message_flags,
+ Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Receive a datagram with the endpoint of the sender. Returns the number of
@@ -438,25 +449,28 @@ public:
// 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.
- template <typename MutableBufferSequence, typename Handler>
- void async_receive_from(implementation_type&,
- const MutableBufferSequence&, endpoint_type&,
- socket_base::message_flags, Handler& handler)
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type&, const MutableBufferSequence&,
+ endpoint_type&, socket_base::message_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Wait until data can be received without blocking.
- template <typename Handler>
- void async_receive_from(implementation_type&,
- const null_buffers&, endpoint_type&,
- socket_base::message_flags, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type&, const null_buffers&,
+ endpoint_type&, socket_base::message_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.post(detail::bind_handler(handler, ec, bytes_transferred));
+ boost::asio::post(io_ex, detail::bind_handler(
+ handler, ec, bytes_transferred));
}
// Accept a new connection.
@@ -470,12 +484,12 @@ public:
// Start an asynchronous accept. The peer and peer_endpoint objects
// must be valid until the accept's handler is invoked.
- template <typename Socket, typename Handler>
- void async_accept(implementation_type&, Socket&,
- endpoint_type*, Handler& handler)
+ template <typename Socket, typename Handler, typename IoExecutor>
+ void async_accept(implementation_type&, Socket&, endpoint_type*,
+ Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
- io_context_.post(detail::bind_handler(handler, ec));
+ boost::asio::post(io_ex, detail::bind_handler(handler, ec));
}
// Connect the socket to the specified endpoint.
@@ -487,16 +501,13 @@ public:
}
// Start an asynchronous connect.
- template <typename Handler>
- void async_connect(implementation_type&,
- const endpoint_type&, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_connect(implementation_type&, const endpoint_type&,
+ Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
- io_context_.post(detail::bind_handler(handler, ec));
+ boost::asio::post(io_ex, detail::bind_handler(handler, ec));
}
-
-private:
- boost::asio::io_context& io_context_;
};
} // namespace detail
diff --git a/boost/asio/detail/null_static_mutex.hpp b/boost/asio/detail/null_static_mutex.hpp
index 7e2c0b522c..f8f9ab4e04 100644
--- a/boost/asio/detail/null_static_mutex.hpp
+++ b/boost/asio/detail/null_static_mutex.hpp
@@ -2,7 +2,7 @@
// detail/null_static_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_thread.hpp b/boost/asio/detail/null_thread.hpp
index 56ad8bf806..bd1360c09f 100644
--- a/boost/asio/detail/null_thread.hpp
+++ b/boost/asio/detail/null_thread.hpp
@@ -2,7 +2,7 @@
// detail/null_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/null_tss_ptr.hpp b/boost/asio/detail/null_tss_ptr.hpp
index 06d5a4d522..eacf4ff4a8 100644
--- a/boost/asio/detail/null_tss_ptr.hpp
+++ b/boost/asio/detail/null_tss_ptr.hpp
@@ -2,7 +2,7 @@
// detail/null_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/object_pool.hpp b/boost/asio/detail/object_pool.hpp
index 7e454a7138..0eadf7ab97 100644
--- a/boost/asio/detail/object_pool.hpp
+++ b/boost/asio/detail/object_pool.hpp
@@ -2,7 +2,7 @@
// detail/object_pool.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/old_win_sdk_compat.hpp b/boost/asio/detail/old_win_sdk_compat.hpp
index f1b63cba0e..f5cb9d74b9 100644
--- a/boost/asio/detail/old_win_sdk_compat.hpp
+++ b/boost/asio/detail/old_win_sdk_compat.hpp
@@ -2,7 +2,7 @@
// detail/old_win_sdk_compat.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/op_queue.hpp b/boost/asio/detail/op_queue.hpp
index 935e45920f..b2cd608cb0 100644
--- a/boost/asio/detail/op_queue.hpp
+++ b/boost/asio/detail/op_queue.hpp
@@ -2,7 +2,7 @@
// detail/op_queue.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/operation.hpp b/boost/asio/detail/operation.hpp
index 13220231ab..4baed817f4 100644
--- a/boost/asio/detail/operation.hpp
+++ b/boost/asio/detail/operation.hpp
@@ -2,7 +2,7 @@
// detail/operation.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/pipe_select_interrupter.hpp b/boost/asio/detail/pipe_select_interrupter.hpp
index 696d565729..01a467a415 100644
--- a/boost/asio/detail/pipe_select_interrupter.hpp
+++ b/boost/asio/detail/pipe_select_interrupter.hpp
@@ -2,7 +2,7 @@
// detail/pipe_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/pop_options.hpp b/boost/asio/detail/pop_options.hpp
index 10450eacb5..3346b96fa4 100644
--- a/boost/asio/detail/pop_options.hpp
+++ b/boost/asio/detail/pop_options.hpp
@@ -2,7 +2,7 @@
// detail/pop_options.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,7 +24,9 @@
// Intel C++
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
-# pragma GCC visibility pop
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility pop
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
#elif defined(__clang__)
@@ -42,7 +44,9 @@
# endif
# if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
-# pragma GCC visibility pop
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility pop
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
#elif defined(__GNUC__)
@@ -64,7 +68,9 @@
# endif
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
-# pragma GCC visibility pop
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility pop
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
# if (__GNUC__ >= 7)
diff --git a/boost/asio/detail/posix_event.hpp b/boost/asio/detail/posix_event.hpp
index 98529eaf26..98a796c9df 100644
--- a/boost/asio/detail/posix_event.hpp
+++ b/boost/asio/detail/posix_event.hpp
@@ -2,7 +2,7 @@
// detail/posix_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -130,7 +130,7 @@ public:
if (::clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
{
ts.tv_sec += usec / 1000000;
- ts.tv_nsec = (usec % 1000000) * 1000;
+ ts.tv_nsec += (usec % 1000000) * 1000;
ts.tv_sec += ts.tv_nsec / 1000000000;
ts.tv_nsec = ts.tv_nsec % 1000000000;
::pthread_cond_timedwait(&cond_,
diff --git a/boost/asio/detail/posix_fd_set_adapter.hpp b/boost/asio/detail/posix_fd_set_adapter.hpp
index f68f2aa1c4..17faa564a8 100644
--- a/boost/asio/detail/posix_fd_set_adapter.hpp
+++ b/boost/asio/detail/posix_fd_set_adapter.hpp
@@ -2,7 +2,7 @@
// detail/posix_fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_global.hpp b/boost/asio/detail/posix_global.hpp
index c2c2996f88..357fe150cb 100644
--- a/boost/asio/detail/posix_global.hpp
+++ b/boost/asio/detail/posix_global.hpp
@@ -2,7 +2,7 @@
// detail/posix_global.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_mutex.hpp b/boost/asio/detail/posix_mutex.hpp
index 5e1d42c530..1418ab5759 100644
--- a/boost/asio/detail/posix_mutex.hpp
+++ b/boost/asio/detail/posix_mutex.hpp
@@ -2,7 +2,7 @@
// detail/posix_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_signal_blocker.hpp b/boost/asio/detail/posix_signal_blocker.hpp
index ea5758fb2c..729da819f6 100644
--- a/boost/asio/detail/posix_signal_blocker.hpp
+++ b/boost/asio/detail/posix_signal_blocker.hpp
@@ -2,7 +2,7 @@
// detail/posix_signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_static_mutex.hpp b/boost/asio/detail/posix_static_mutex.hpp
index cbf7013c2d..331868f0d4 100644
--- a/boost/asio/detail/posix_static_mutex.hpp
+++ b/boost/asio/detail/posix_static_mutex.hpp
@@ -2,7 +2,7 @@
// detail/posix_static_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_thread.hpp b/boost/asio/detail/posix_thread.hpp
index b2821f5356..b9cd59424f 100644
--- a/boost/asio/detail/posix_thread.hpp
+++ b/boost/asio/detail/posix_thread.hpp
@@ -2,7 +2,7 @@
// detail/posix_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/posix_tss_ptr.hpp b/boost/asio/detail/posix_tss_ptr.hpp
index 93d06744a7..126c148d3b 100644
--- a/boost/asio/detail/posix_tss_ptr.hpp
+++ b/boost/asio/detail/posix_tss_ptr.hpp
@@ -2,7 +2,7 @@
// detail/posix_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/push_options.hpp b/boost/asio/detail/push_options.hpp
index 4927df93a2..679ac273c2 100644
--- a/boost/asio/detail/push_options.hpp
+++ b/boost/asio/detail/push_options.hpp
@@ -2,7 +2,7 @@
// detail/push_options.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,7 +24,9 @@
// Intel C++
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
-# pragma GCC visibility push (default)
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility push (default)
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
#elif defined(__clang__)
@@ -44,7 +46,9 @@
# endif
# if !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
-# pragma GCC visibility push (default)
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility push (default)
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // !defined(_WIN32) && !defined(__WIN32__) && !defined(WIN32)
#elif defined(__GNUC__)
@@ -68,7 +72,9 @@
# endif
# if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
-# pragma GCC visibility push (default)
+# if !defined(BOOST_ASIO_DISABLE_VISIBILITY)
+# pragma GCC visibility push (default)
+# endif // !defined(BOOST_ASIO_DISABLE_VISIBILITY)
# endif // (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
# if (__GNUC__ >= 7)
diff --git a/boost/asio/detail/reactive_descriptor_service.hpp b/boost/asio/detail/reactive_descriptor_service.hpp
index ac50a8ccb9..beed44a0ab 100644
--- a/boost/asio/detail/reactive_descriptor_service.hpp
+++ b/boost/asio/detail/reactive_descriptor_service.hpp
@@ -2,7 +2,7 @@
// detail/reactive_descriptor_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -22,7 +22,7 @@
&& !defined(__CYGWIN__)
#include <boost/asio/buffer.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/descriptor_ops.hpp>
@@ -43,7 +43,7 @@ namespace asio {
namespace detail {
class reactive_descriptor_service :
- public service_base<reactive_descriptor_service>
+ public execution_context_service_base<reactive_descriptor_service>
{
public:
// The native type of a descriptor.
@@ -76,8 +76,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL reactive_descriptor_service(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL reactive_descriptor_service(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -191,18 +190,19 @@ public:
// Asynchronously wait for the descriptor to become ready to read, ready to
// write, or to have pending error conditions.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_wait(implementation_type& impl,
- posix::descriptor_base::wait_type w, Handler& handler)
+ posix::descriptor_base::wait_type w,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_wait_op<Handler> op;
+ typedef reactive_wait_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor",
&impl, impl.descriptor_, "async_wait"));
@@ -254,18 +254,19 @@ public:
// Start an asynchronous write. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, Handler& handler)
+ const ConstBufferSequence& buffers, Handler& handler,
+ const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef descriptor_write_op<ConstBufferSequence, Handler> op;
+ typedef descriptor_write_op<ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.descriptor_, buffers, handler);
+ p.p = new (p.v) op(impl.descriptor_, buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor",
&impl, impl.descriptor_, "async_write_some"));
@@ -277,18 +278,18 @@ public:
}
// Start an asynchronous wait until data can be written without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const null_buffers&, Handler& handler)
+ const null_buffers&, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor",
&impl, impl.descriptor_, "async_write_some(null_buffers)"));
@@ -321,18 +322,20 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef descriptor_read_op<MutableBufferSequence, Handler> op;
+ typedef descriptor_read_op<MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.descriptor_, buffers, handler);
+ p.p = new (p.v) op(impl.descriptor_, buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor",
&impl, impl.descriptor_, "async_read_some"));
@@ -344,18 +347,18 @@ public:
}
// Wait until data can be read without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const null_buffers&, Handler& handler)
+ const null_buffers&, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "descriptor",
&impl, impl.descriptor_, "async_read_some(null_buffers)"));
diff --git a/boost/asio/detail/reactive_null_buffers_op.hpp b/boost/asio/detail/reactive_null_buffers_op.hpp
index dca3a3285f..fb25be335f 100644
--- a/boost/asio/detail/reactive_null_buffers_op.hpp
+++ b/boost/asio/detail/reactive_null_buffers_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_null_buffers_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,18 +28,19 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class reactive_null_buffers_op : public reactor_op
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_null_buffers_op);
- reactive_null_buffers_op(Handler& handler)
+ reactive_null_buffers_op(Handler& handler, const IoExecutor& io_ex)
: reactor_op(&reactive_null_buffers_op::do_perform,
&reactive_null_buffers_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static status do_perform(reactor_op*)
@@ -54,7 +55,7 @@ public:
// Take ownership of the handler object.
reactive_null_buffers_op* o(static_cast<reactive_null_buffers_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -81,6 +82,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_serial_port_service.hpp b/boost/asio/detail/reactive_serial_port_service.hpp
index 42ff500d2c..ae752d06da 100644
--- a/boost/asio/detail/reactive_serial_port_service.hpp
+++ b/boost/asio/detail/reactive_serial_port_service.hpp
@@ -2,7 +2,7 @@
// detail/reactive_serial_port_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -23,7 +23,7 @@
#include <string>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/serial_port_base.hpp>
#include <boost/asio/detail/descriptor_ops.hpp>
#include <boost/asio/detail/reactive_descriptor_service.hpp>
@@ -36,7 +36,7 @@ namespace detail {
// Extend reactive_descriptor_service to provide serial port support.
class reactive_serial_port_service :
- public service_base<reactive_serial_port_service>
+ public execution_context_service_base<reactive_serial_port_service>
{
public:
// The native type of a serial port.
@@ -45,8 +45,7 @@ public:
// The implementation type of the serial port.
typedef reactive_descriptor_service::implementation_type implementation_type;
- BOOST_ASIO_DECL reactive_serial_port_service(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL reactive_serial_port_service(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -157,11 +156,12 @@ public:
// Start an asynchronous write. The data being written must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, Handler& handler)
+ const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
- descriptor_service_.async_write_some(impl, buffers, handler);
+ descriptor_service_.async_write_some(impl, buffers, handler, io_ex);
}
// Read some data. Returns the number of bytes received.
@@ -174,11 +174,13 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
- descriptor_service_.async_read_some(impl, buffers, handler);
+ descriptor_service_.async_read_some(impl, buffers, handler, io_ex);
}
private:
diff --git a/boost/asio/detail/reactive_socket_accept_op.hpp b/boost/asio/detail/reactive_socket_accept_op.hpp
index 292f3bdf25..972e01618c 100644
--- a/boost/asio/detail/reactive_socket_accept_op.hpp
+++ b/boost/asio/detail/reactive_socket_accept_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_accept_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -86,7 +86,8 @@ private:
std::size_t addrlen_;
};
-template <typename Socket, typename Protocol, typename Handler>
+template <typename Socket, typename Protocol,
+ typename Handler, typename IoExecutor>
class reactive_socket_accept_op :
public reactive_socket_accept_op_base<Socket, Protocol>
{
@@ -95,12 +96,14 @@ public:
reactive_socket_accept_op(socket_type socket,
socket_ops::state_type state, Socket& peer, const Protocol& protocol,
- typename Protocol::endpoint* peer_endpoint, Handler& handler)
+ typename Protocol::endpoint* peer_endpoint, Handler& handler,
+ const IoExecutor& io_ex)
: reactive_socket_accept_op_base<Socket, Protocol>(socket, state, peer,
protocol, peer_endpoint, &reactive_socket_accept_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -110,7 +113,7 @@ public:
// Take ownership of the handler object.
reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
// On success, assign new connection to peer socket object.
if (owner)
@@ -141,28 +144,34 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename Protocol, typename Handler>
+template <typename Protocol, typename PeerIoExecutor,
+ typename Handler, typename IoExecutor>
class reactive_socket_move_accept_op :
- private Protocol::socket,
- public reactive_socket_accept_op_base<typename Protocol::socket, Protocol>
+ private Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
+ public reactive_socket_accept_op_base<
+ typename Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
+ Protocol>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_move_accept_op);
- reactive_socket_move_accept_op(io_context& ioc, socket_type socket,
- socket_ops::state_type state, const Protocol& protocol,
- typename Protocol::endpoint* peer_endpoint, Handler& handler)
- : Protocol::socket(ioc),
- reactive_socket_accept_op_base<typename Protocol::socket, Protocol>(
+ reactive_socket_move_accept_op(const PeerIoExecutor& peer_io_ex,
+ socket_type socket, socket_ops::state_type state,
+ const Protocol& protocol, typename Protocol::endpoint* peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
+ : peer_socket_type(peer_io_ex),
+ reactive_socket_accept_op_base<peer_socket_type, Protocol>(
socket, state, *this, protocol, peer_endpoint,
&reactive_socket_move_accept_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -173,7 +182,7 @@ public:
reactive_socket_move_accept_op* o(
static_cast<reactive_socket_move_accept_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
// On success, assign new connection to peer socket object.
if (owner)
@@ -188,9 +197,9 @@ public:
// to ensure that any owning sub-object remains valid until after we have
// deallocated the memory here.
detail::move_binder2<Handler,
- boost::system::error_code, typename Protocol::socket>
+ boost::system::error_code, peer_socket_type>
handler(0, BOOST_ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,
- BOOST_ASIO_MOVE_CAST(typename Protocol::socket)(*o));
+ BOOST_ASIO_MOVE_CAST(peer_socket_type)(*o));
p.h = boost::asio::detail::addressof(handler.handler_);
p.reset();
@@ -205,7 +214,11 @@ public:
}
private:
+ typedef typename Protocol::socket::template
+ rebind_executor<PeerIoExecutor>::other peer_socket_type;
+
Handler handler_;
+ IoExecutor io_executor_;
};
#endif // defined(BOOST_ASIO_HAS_MOVE)
diff --git a/boost/asio/detail/reactive_socket_connect_op.hpp b/boost/asio/detail/reactive_socket_connect_op.hpp
index bbb5020501..e8701da312 100644
--- a/boost/asio/detail/reactive_socket_connect_op.hpp
+++ b/boost/asio/detail/reactive_socket_connect_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_connect_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -55,18 +55,20 @@ private:
socket_type socket_;
};
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
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(socket_type socket,
+ Handler& handler, const IoExecutor& io_ex)
: reactive_socket_connect_op_base(socket,
&reactive_socket_connect_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -77,7 +79,7 @@ public:
reactive_socket_connect_op* o
(static_cast<reactive_socket_connect_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -104,6 +106,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_recv_op.hpp b/boost/asio/detail/reactive_socket_recv_op.hpp
index 0f124627bd..1d6889dcce 100644
--- a/boost/asio/detail/reactive_socket_recv_op.hpp
+++ b/boost/asio/detail/reactive_socket_recv_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_recv_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -75,21 +75,22 @@ private:
socket_base::message_flags flags_;
};
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
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(socket_type socket, socket_ops::state_type state,
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
: reactive_socket_recv_op_base<MutableBufferSequence>(socket, state,
buffers, flags, &reactive_socket_recv_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -99,7 +100,7 @@ public:
// Take ownership of the handler object.
reactive_socket_recv_op* o(static_cast<reactive_socket_recv_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -126,6 +127,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_recvfrom_op.hpp b/boost/asio/detail/reactive_socket_recvfrom_op.hpp
index b96a01327a..09aceba82f 100644
--- a/boost/asio/detail/reactive_socket_recvfrom_op.hpp
+++ b/boost/asio/detail/reactive_socket_recvfrom_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_recvfrom_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -76,7 +76,8 @@ private:
socket_base::message_flags flags_;
};
-template <typename MutableBufferSequence, typename Endpoint, typename Handler>
+template <typename MutableBufferSequence, typename Endpoint,
+ typename Handler, typename IoExecutor>
class reactive_socket_recvfrom_op :
public reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>
{
@@ -85,13 +86,15 @@ public:
reactive_socket_recvfrom_op(socket_type socket, int protocol_type,
const MutableBufferSequence& buffers, Endpoint& endpoint,
- socket_base::message_flags flags, Handler& handler)
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
: reactive_socket_recvfrom_op_base<MutableBufferSequence, Endpoint>(
socket, protocol_type, buffers, endpoint, flags,
&reactive_socket_recvfrom_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -102,7 +105,7 @@ public:
reactive_socket_recvfrom_op* o(
static_cast<reactive_socket_recvfrom_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -129,6 +132,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_recvmsg_op.hpp b/boost/asio/detail/reactive_socket_recvmsg_op.hpp
index 6ae324947c..bb65a19cf4 100644
--- a/boost/asio/detail/reactive_socket_recvmsg_op.hpp
+++ b/boost/asio/detail/reactive_socket_recvmsg_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_recvmsg_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -71,7 +71,7 @@ private:
socket_base::message_flags& out_flags_;
};
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class reactive_socket_recvmsg_op :
public reactive_socket_recvmsg_op_base<MutableBufferSequence>
{
@@ -80,12 +80,14 @@ public:
reactive_socket_recvmsg_op(socket_type socket,
const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
: reactive_socket_recvmsg_op_base<MutableBufferSequence>(socket, buffers,
in_flags, out_flags, &reactive_socket_recvmsg_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -96,7 +98,7 @@ public:
reactive_socket_recvmsg_op* o(
static_cast<reactive_socket_recvmsg_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -123,6 +125,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_send_op.hpp b/boost/asio/detail/reactive_socket_send_op.hpp
index 11f3ad80af..6be6081cc9 100644
--- a/boost/asio/detail/reactive_socket_send_op.hpp
+++ b/boost/asio/detail/reactive_socket_send_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_send_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -74,21 +74,22 @@ private:
socket_base::message_flags flags_;
};
-template <typename ConstBufferSequence, typename Handler>
+template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
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,
- socket_ops::state_type state, const ConstBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ reactive_socket_send_op(socket_type socket, socket_ops::state_type state,
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
: reactive_socket_send_op_base<ConstBufferSequence>(socket,
state, buffers, flags, &reactive_socket_send_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -98,7 +99,7 @@ public:
// Take ownership of the handler object.
reactive_socket_send_op* o(static_cast<reactive_socket_send_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -125,6 +126,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_sendto_op.hpp b/boost/asio/detail/reactive_socket_sendto_op.hpp
index a73934bfc1..3429a7585e 100644
--- a/boost/asio/detail/reactive_socket_sendto_op.hpp
+++ b/boost/asio/detail/reactive_socket_sendto_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_sendto_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -70,7 +70,8 @@ private:
socket_base::message_flags flags_;
};
-template <typename ConstBufferSequence, typename Endpoint, typename Handler>
+template <typename ConstBufferSequence, typename Endpoint,
+ typename Handler, typename IoExecutor>
class reactive_socket_sendto_op :
public reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>
{
@@ -79,12 +80,14 @@ public:
reactive_socket_sendto_op(socket_type socket,
const ConstBufferSequence& buffers, const Endpoint& endpoint,
- socket_base::message_flags flags, Handler& handler)
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
: reactive_socket_sendto_op_base<ConstBufferSequence, Endpoint>(socket,
buffers, endpoint, flags, &reactive_socket_sendto_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -94,7 +97,7 @@ public:
// Take ownership of the handler object.
reactive_socket_sendto_op* o(static_cast<reactive_socket_sendto_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -121,6 +124,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactive_socket_service.hpp b/boost/asio/detail/reactive_socket_service.hpp
index 89940d9af0..fb3a0e4660 100644
--- a/boost/asio/detail/reactive_socket_service.hpp
+++ b/boost/asio/detail/reactive_socket_service.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,7 +21,7 @@
#include <boost/asio/buffer.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/memory.hpp>
@@ -46,7 +46,7 @@ namespace detail {
template <typename Protocol>
class reactive_socket_service :
- public service_base<reactive_socket_service<Protocol> >,
+ public execution_context_service_base<reactive_socket_service<Protocol> >,
public reactive_socket_service_base
{
public:
@@ -74,9 +74,10 @@ public:
};
// Constructor.
- reactive_socket_service(boost::asio::io_context& io_context)
- : service_base<reactive_socket_service<Protocol> >(io_context),
- reactive_socket_service_base(io_context)
+ reactive_socket_service(execution_context& context)
+ : execution_context_service_base<
+ reactive_socket_service<Protocol> >(context),
+ reactive_socket_service_base(context)
{
}
@@ -240,21 +241,22 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send_to(implementation_type& impl,
const ConstBufferSequence& buffers,
const endpoint_type& destination, socket_base::message_flags flags,
- Handler& handler)
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
typedef reactive_socket_sendto_op<ConstBufferSequence,
- endpoint_type, Handler> op;
+ endpoint_type, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler);
+ p.p = new (p.v) op(impl.socket_, buffers,
+ destination, flags, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_send_to"));
@@ -264,18 +266,19 @@ public:
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send_to(implementation_type& impl, const null_buffers&,
- const endpoint_type&, socket_base::message_flags, Handler& handler)
+ const endpoint_type&, socket_base::message_flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_send_to(null_buffers)"));
@@ -323,22 +326,24 @@ public:
// 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.
- template <typename MutableBufferSequence, typename Handler>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags flags, Handler& handler)
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
typedef reactive_socket_recvfrom_op<MutableBufferSequence,
- endpoint_type, Handler> op;
+ endpoint_type, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
int protocol = impl.protocol_.type();
- p.p = new (p.v) op(impl.socket_, protocol,
- buffers, sender_endpoint, flags, handler);
+ p.p = new (p.v) op(impl.socket_, protocol, buffers,
+ sender_endpoint, flags, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive_from"));
@@ -351,19 +356,19 @@ public:
}
// Wait until data can be received without blocking.
- template <typename Handler>
- void async_receive_from(implementation_type& impl,
- const null_buffers&, endpoint_type& sender_endpoint,
- socket_base::message_flags flags, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive_from(null_buffers)"));
@@ -408,49 +413,21 @@ public:
return ec;
}
-#if defined(BOOST_ASIO_HAS_MOVE)
- // Accept a new connection.
- typename Protocol::socket accept(implementation_type& impl,
- io_context* peer_io_context, endpoint_type* peer_endpoint,
- boost::system::error_code& ec)
- {
- typename Protocol::socket peer(
- peer_io_context ? *peer_io_context : io_context_);
-
- 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() != invalid_socket)
- {
- if (peer_endpoint)
- peer_endpoint->resize(addr_len);
- peer.assign(impl.protocol_, new_socket.get(), ec);
- if (!ec)
- new_socket.release();
- }
-
- return peer;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
// Start an asynchronous accept. The peer and peer_endpoint objects must be
// valid until the accept's handler is invoked.
- template <typename Socket, typename Handler>
+ template <typename Socket, typename Handler, typename IoExecutor>
void async_accept(implementation_type& impl, Socket& peer,
- endpoint_type* peer_endpoint, Handler& handler)
+ endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_accept_op<Socket, Protocol, Handler> op;
+ typedef reactive_socket_accept_op<Socket, Protocol, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
p.p = new (p.v) op(impl.socket_, impl.state_, peer,
- impl.protocol_, peer_endpoint, handler);
+ impl.protocol_, peer_endpoint, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_accept"));
@@ -462,20 +439,21 @@ public:
#if defined(BOOST_ASIO_HAS_MOVE)
// Start an asynchronous accept. The peer_endpoint object must be valid until
// the accept's handler is invoked.
- template <typename Handler>
- void async_accept(implementation_type& impl,
- boost::asio::io_context* peer_io_context,
- endpoint_type* peer_endpoint, Handler& handler)
+ template <typename PeerIoExecutor, typename Handler, typename IoExecutor>
+ void async_move_accept(implementation_type& impl,
+ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_move_accept_op<Protocol, Handler> op;
+ typedef reactive_socket_move_accept_op<Protocol,
+ PeerIoExecutor, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_,
- impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler);
+ p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_,
+ impl.protocol_, peer_endpoint, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_accept"));
@@ -495,18 +473,19 @@ public:
}
// Start an asynchronous connect.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, Handler& handler)
+ const endpoint_type& peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_connect_op<Handler> op;
+ typedef reactive_socket_connect_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, handler);
+ p.p = new (p.v) op(impl.socket_, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_connect"));
diff --git a/boost/asio/detail/reactive_socket_service_base.hpp b/boost/asio/detail/reactive_socket_service_base.hpp
index 9d3d54cc11..26fb828b01 100644
--- a/boost/asio/detail/reactive_socket_service_base.hpp
+++ b/boost/asio/detail/reactive_socket_service_base.hpp
@@ -2,7 +2,7 @@
// detail/reactive_socket_service_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -22,7 +22,7 @@
#include <boost/asio/buffer.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/memory.hpp>
@@ -63,8 +63,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL reactive_socket_service_base(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL reactive_socket_service_base(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void base_shutdown();
@@ -194,18 +193,18 @@ public:
// Asynchronously wait for the socket to become ready to read, ready to
// write, or to have pending error conditions.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_wait(base_implementation_type& impl,
- socket_base::wait_type w, Handler& handler)
+ socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_wait_op<Handler> op;
+ typedef reactive_wait_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_wait"));
@@ -258,19 +257,21 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_send_op<ConstBufferSequence, Handler> op;
+ typedef reactive_socket_send_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
+ p.p = new (p.v) op(impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_send"));
@@ -283,18 +284,18 @@ public:
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send(base_implementation_type& impl, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_send(null_buffers)"));
@@ -328,19 +329,22 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_recv_op<MutableBufferSequence, Handler> op;
+ typedef reactive_socket_recv_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
+ p.p = new (p.v) op(impl.socket_, impl.state_,
+ buffers, flags, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive"));
@@ -357,18 +361,19 @@ public:
}
// 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)
+ template <typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive(null_buffers)"));
@@ -412,19 +417,23 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive_with_flags(base_implementation_type& impl,
const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_socket_recvmsg_op<MutableBufferSequence, Handler> op;
+ typedef reactive_socket_recvmsg_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler);
+ p.p = new (p.v) op(impl.socket_, buffers,
+ in_flags, out_flags, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive_with_flags"));
@@ -438,19 +447,20 @@ public:
}
// Wait until data can be received without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_receive_with_flags(base_implementation_type& impl,
const null_buffers&, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef reactive_null_buffers_op<Handler> op;
+ typedef reactive_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket",
&impl, impl.socket_, "async_receive_with_flags(null_buffers)"));
@@ -490,9 +500,6 @@ protected:
reactor_op* op, bool is_continuation,
const socket_addr_type* addr, size_t addrlen);
- // The io_context that owns this socket service.
- io_context& io_context_;
-
// The selector that performs event demultiplexing for the service.
reactor& reactor_;
};
diff --git a/boost/asio/detail/reactive_wait_op.hpp b/boost/asio/detail/reactive_wait_op.hpp
index ee32502482..021059dcd5 100644
--- a/boost/asio/detail/reactive_wait_op.hpp
+++ b/boost/asio/detail/reactive_wait_op.hpp
@@ -2,7 +2,7 @@
// detail/reactive_wait_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,18 +28,19 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class reactive_wait_op : public reactor_op
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_wait_op);
- reactive_wait_op(Handler& handler)
+ reactive_wait_op(Handler& handler, const IoExecutor& io_ex)
: reactor_op(&reactive_wait_op::do_perform,
&reactive_wait_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static status do_perform(reactor_op*)
@@ -54,7 +55,7 @@ public:
// Take ownership of the handler object.
reactive_wait_op* o(static_cast<reactive_wait_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -81,6 +82,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/reactor.hpp b/boost/asio/detail/reactor.hpp
index f1e5d95864..bfe999bed3 100644
--- a/boost/asio/detail/reactor.hpp
+++ b/boost/asio/detail/reactor.hpp
@@ -2,7 +2,7 @@
// detail/reactor.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/reactor_fwd.hpp b/boost/asio/detail/reactor_fwd.hpp
index b222b134e6..2ea1eec99e 100644
--- a/boost/asio/detail/reactor_fwd.hpp
+++ b/boost/asio/detail/reactor_fwd.hpp
@@ -2,7 +2,7 @@
// detail/reactor_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/reactor_op.hpp b/boost/asio/detail/reactor_op.hpp
index beb443eb69..4c399a5036 100644
--- a/boost/asio/detail/reactor_op.hpp
+++ b/boost/asio/detail/reactor_op.hpp
@@ -2,7 +2,7 @@
// detail/reactor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/reactor_op_queue.hpp b/boost/asio/detail/reactor_op_queue.hpp
index fec0dd7d37..dd28b6dc98 100644
--- a/boost/asio/detail/reactor_op_queue.hpp
+++ b/boost/asio/detail/reactor_op_queue.hpp
@@ -2,7 +2,7 @@
// detail/reactor_op_queue.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/recycling_allocator.hpp b/boost/asio/detail/recycling_allocator.hpp
index adab0a7a61..74003bfdd6 100644
--- a/boost/asio/detail/recycling_allocator.hpp
+++ b/boost/asio/detail/recycling_allocator.hpp
@@ -2,7 +2,7 @@
// detail/recycling_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -26,7 +26,7 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename T>
+template <typename T, typename Purpose = thread_info_base::default_tag>
class recycling_allocator
{
public:
@@ -35,7 +35,7 @@ public:
template <typename U>
struct rebind
{
- typedef recycling_allocator<U> other;
+ typedef recycling_allocator<U, Purpose> other;
};
recycling_allocator()
@@ -43,26 +43,28 @@ public:
}
template <typename U>
- recycling_allocator(const recycling_allocator<U>&)
+ recycling_allocator(const recycling_allocator<U, Purpose>&)
{
}
T* allocate(std::size_t n)
{
typedef thread_context::thread_call_stack call_stack;
- void* p = thread_info_base::allocate(call_stack::top(), sizeof(T) * n);
+ void* p = thread_info_base::allocate(Purpose(),
+ call_stack::top(), sizeof(T) * n);
return static_cast<T*>(p);
}
void deallocate(T* p, std::size_t n)
{
typedef thread_context::thread_call_stack call_stack;
- thread_info_base::deallocate(call_stack::top(), p, sizeof(T) * n);
+ thread_info_base::deallocate(Purpose(),
+ call_stack::top(), p, sizeof(T) * n);
}
};
-template <>
-class recycling_allocator<void>
+template <typename Purpose>
+class recycling_allocator<void, Purpose>
{
public:
typedef void value_type;
@@ -70,7 +72,7 @@ public:
template <typename U>
struct rebind
{
- typedef recycling_allocator<U> other;
+ typedef recycling_allocator<U, Purpose> other;
};
recycling_allocator()
@@ -78,22 +80,22 @@ public:
}
template <typename U>
- recycling_allocator(const recycling_allocator<U>&)
+ recycling_allocator(const recycling_allocator<U, Purpose>&)
{
}
};
-template <typename Allocator>
+template <typename Allocator, typename Purpose>
struct get_recycling_allocator
{
typedef Allocator type;
static type get(const Allocator& a) { return a; }
};
-template <typename T>
-struct get_recycling_allocator<std::allocator<T> >
+template <typename T, typename Purpose>
+struct get_recycling_allocator<std::allocator<T>, Purpose>
{
- typedef recycling_allocator<T> type;
+ typedef recycling_allocator<T, Purpose> type;
static type get(const std::allocator<T>&) { return type(); }
};
diff --git a/boost/asio/detail/regex_fwd.hpp b/boost/asio/detail/regex_fwd.hpp
index 4d35a68ab9..a2dd26dff4 100644
--- a/boost/asio/detail/regex_fwd.hpp
+++ b/boost/asio/detail/regex_fwd.hpp
@@ -2,7 +2,7 @@
// detail/regex_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/resolve_endpoint_op.hpp b/boost/asio/detail/resolve_endpoint_op.hpp
index 970544c783..72df8d94ac 100644
--- a/boost/asio/detail/resolve_endpoint_op.hpp
+++ b/boost/asio/detail/resolve_endpoint_op.hpp
@@ -2,7 +2,7 @@
// detail/resolve_endpoint_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,7 +17,6 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/basic_resolver_results.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/fenced_block.hpp>
@@ -27,13 +26,19 @@
#include <boost/asio/detail/resolve_op.hpp>
#include <boost/asio/detail/socket_ops.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
-template <typename Protocol, typename Handler>
+template <typename Protocol, typename Handler, typename IoExecutor>
class resolve_endpoint_op : public resolve_op
{
public:
@@ -42,15 +47,23 @@ public:
typedef typename Protocol::endpoint endpoint_type;
typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+
resolve_endpoint_op(socket_ops::weak_cancel_token_type cancel_token,
- const endpoint_type& endpoint, io_context_impl& ioc, Handler& handler)
+ const endpoint_type& endpoint, scheduler_impl& sched,
+ Handler& handler, const IoExecutor& io_ex)
: resolve_op(&resolve_endpoint_op::do_complete),
cancel_token_(cancel_token),
endpoint_(endpoint),
- io_context_impl_(ioc),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ scheduler_(sched),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -60,9 +73,9 @@ public:
// Take ownership of the operation object.
resolve_endpoint_op* o(static_cast<resolve_endpoint_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
- if (owner && owner != &o->io_context_impl_)
+ if (owner && owner != &o->scheduler_)
{
// The operation is being run on the worker io_context. Time to perform
// the resolver operation.
@@ -76,7 +89,7 @@ public:
o->results_ = results_type::create(o->endpoint_, host_name, service_name);
// Pass operation back to main io_context for completion.
- o->io_context_impl_.post_deferred_completion(o);
+ o->scheduler_.post_deferred_completion(o);
p.v = p.p = 0;
}
else
@@ -110,8 +123,9 @@ public:
private:
socket_ops::weak_cancel_token_type cancel_token_;
endpoint_type endpoint_;
- io_context_impl& io_context_impl_;
+ scheduler_impl& scheduler_;
Handler handler_;
+ IoExecutor io_executor_;
results_type results_;
};
diff --git a/boost/asio/detail/resolve_op.hpp b/boost/asio/detail/resolve_op.hpp
index fd72994fc5..2be7b196ec 100644
--- a/boost/asio/detail/resolve_op.hpp
+++ b/boost/asio/detail/resolve_op.hpp
@@ -2,7 +2,7 @@
// detail/resolve_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/resolve_query_op.hpp b/boost/asio/detail/resolve_query_op.hpp
index 91bdd79654..11d5989671 100644
--- a/boost/asio/detail/resolve_query_op.hpp
+++ b/boost/asio/detail/resolve_query_op.hpp
@@ -2,7 +2,7 @@
// detail/resolve_query_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,7 +17,6 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/basic_resolver_query.hpp>
#include <boost/asio/ip/basic_resolver_results.hpp>
#include <boost/asio/detail/bind_handler.hpp>
@@ -28,13 +27,19 @@
#include <boost/asio/detail/resolve_op.hpp>
#include <boost/asio/detail/socket_ops.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace detail {
-template <typename Protocol, typename Handler>
+template <typename Protocol, typename Handler, typename IoExecutor>
class resolve_query_op : public resolve_op
{
public:
@@ -43,16 +48,24 @@ public:
typedef boost::asio::ip::basic_resolver_query<Protocol> query_type;
typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+
resolve_query_op(socket_ops::weak_cancel_token_type cancel_token,
- const query_type& query, io_context_impl& ioc, Handler& handler)
+ const query_type& query, scheduler_impl& sched,
+ Handler& handler, const IoExecutor& io_ex)
: resolve_op(&resolve_query_op::do_complete),
cancel_token_(cancel_token),
query_(query),
- io_context_impl_(ioc),
+ scheduler_(sched),
handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex),
addrinfo_(0)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
~resolve_query_op()
@@ -69,7 +82,7 @@ public:
resolve_query_op* o(static_cast<resolve_query_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- if (owner && owner != &o->io_context_impl_)
+ if (owner && owner != &o->scheduler_)
{
// The operation is being run on the worker io_context. Time to perform
// the resolver operation.
@@ -80,7 +93,7 @@ public:
o->query_.hints(), &o->addrinfo_, o->ec_);
// Pass operation back to main io_context for completion.
- o->io_context_impl_.post_deferred_completion(o);
+ o->scheduler_.post_deferred_completion(o);
p.v = p.p = 0;
}
else
@@ -89,7 +102,7 @@ public:
// handler is ready to be delivered.
// Take ownership of the operation's outstanding work.
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -122,8 +135,9 @@ public:
private:
socket_ops::weak_cancel_token_type cancel_token_;
query_type query_;
- io_context_impl& io_context_impl_;
+ scheduler_impl& scheduler_;
Handler handler_;
+ IoExecutor io_executor_;
boost::asio::detail::addrinfo_type* addrinfo_;
};
diff --git a/boost/asio/detail/resolver_service.hpp b/boost/asio/detail/resolver_service.hpp
index 85c9c2a0a7..744b75ca46 100644
--- a/boost/asio/detail/resolver_service.hpp
+++ b/boost/asio/detail/resolver_service.hpp
@@ -2,7 +2,7 @@
// detail/resolver_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,7 +35,7 @@ namespace detail {
template <typename Protocol>
class resolver_service :
- public service_base<resolver_service<Protocol> >,
+ public execution_context_service_base<resolver_service<Protocol> >,
public resolver_service_base
{
public:
@@ -53,9 +53,9 @@ public:
typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
// Constructor.
- resolver_service(boost::asio::io_context& io_context)
- : service_base<resolver_service<Protocol> >(io_context),
- resolver_service_base(io_context)
+ resolver_service(execution_context& context)
+ : execution_context_service_base<resolver_service<Protocol> >(context),
+ resolver_service_base(context)
{
}
@@ -66,7 +66,7 @@ public:
}
// Perform any fork-related housekeeping.
- void notify_fork(boost::asio::io_context::fork_event fork_ev)
+ void notify_fork(execution_context::fork_event fork_ev)
{
this->base_notify_fork(fork_ev);
}
@@ -86,17 +86,17 @@ public:
}
// Asynchronously resolve a query to a list of entries.
- template <typename Handler>
- void async_resolve(implementation_type& impl,
- const query_type& query, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_resolve(implementation_type& impl, const query_type& query,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef resolve_query_op<Protocol, Handler> op;
+ typedef resolve_query_op<Protocol, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl, query, io_context_impl_, handler);
+ p.p = new (p.v) op(impl, query, scheduler_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_impl_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "resolver", &impl, 0, "async_resolve"));
start_resolve_op(p.p);
@@ -118,17 +118,17 @@ public:
}
// Asynchronously resolve an endpoint to a list of entries.
- template <typename Handler>
- void async_resolve(implementation_type& impl,
- const endpoint_type& endpoint, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_resolve(implementation_type& impl, const endpoint_type& endpoint,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef resolve_endpoint_op<Protocol, Handler> op;
+ typedef resolve_endpoint_op<Protocol, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl, endpoint, io_context_impl_, handler);
+ p.p = new (p.v) op(impl, endpoint, scheduler_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_impl_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "resolver", &impl, 0, "async_resolve"));
start_resolve_op(p.p);
diff --git a/boost/asio/detail/resolver_service_base.hpp b/boost/asio/detail/resolver_service_base.hpp
index 40adca655a..8e1ff5bea8 100644
--- a/boost/asio/detail/resolver_service_base.hpp
+++ b/boost/asio/detail/resolver_service_base.hpp
@@ -2,7 +2,7 @@
// detail/resolver_service_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,8 +17,7 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/executor_work_guard.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/mutex.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/resolve_op.hpp>
@@ -27,6 +26,12 @@
#include <boost/asio/detail/scoped_ptr.hpp>
#include <boost/asio/detail/thread.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -41,7 +46,7 @@ public:
typedef socket_ops::shared_cancel_token_type implementation_type;
// Constructor.
- BOOST_ASIO_DECL resolver_service_base(boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL resolver_service_base(execution_context& context);
// Destructor.
BOOST_ASIO_DECL ~resolver_service_base();
@@ -51,7 +56,7 @@ public:
// Perform any fork-related housekeeping.
BOOST_ASIO_DECL void base_notify_fork(
- boost::asio::io_context::fork_event fork_ev);
+ execution_context::fork_event fork_ev);
// Construct a new resolver implementation.
BOOST_ASIO_DECL void construct(implementation_type& impl);
@@ -102,28 +107,26 @@ protected:
};
#endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME)
- // Helper class to run the work io_context in a thread.
- class work_io_context_runner;
+ // Helper class to run the work scheduler in a thread.
+ class work_scheduler_runner;
- // Start the work thread if it's not already running.
+ // Start the work scheduler if it's not already running.
BOOST_ASIO_DECL void start_work_thread();
- // The io_context implementation used to post completions.
- io_context_impl& io_context_impl_;
+ // The scheduler implementation used to post completions.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
private:
// Mutex to protect access to internal data.
boost::asio::detail::mutex mutex_;
- // Private io_context used for performing asynchronous host resolution.
- boost::asio::detail::scoped_ptr<boost::asio::io_context> work_io_context_;
-
- // The work io_context implementation used to post completions.
- io_context_impl& work_io_context_impl_;
-
- // Work for the private io_context to perform.
- boost::asio::executor_work_guard<
- boost::asio::io_context::executor_type> work_;
+ // Private scheduler used for performing asynchronous host resolution.
+ boost::asio::detail::scoped_ptr<scheduler_impl> work_scheduler_;
// Thread used for running the work io_context's run loop.
boost::asio::detail::scoped_ptr<boost::asio::detail::thread> work_thread_;
diff --git a/boost/asio/detail/scheduler.hpp b/boost/asio/detail/scheduler.hpp
index 835e4c9237..e3861818d4 100644
--- a/boost/asio/detail/scheduler.hpp
+++ b/boost/asio/detail/scheduler.hpp
@@ -2,7 +2,7 @@
// detail/scheduler.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -25,6 +25,7 @@
#include <boost/asio/detail/op_queue.hpp>
#include <boost/asio/detail/reactor_fwd.hpp>
#include <boost/asio/detail/scheduler_operation.hpp>
+#include <boost/asio/detail/thread.hpp>
#include <boost/asio/detail/thread_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -45,7 +46,10 @@ public:
// Constructor. Specifies the number of concurrent threads that are likely to
// run the scheduler. If set to 1 certain optimisation are performed.
BOOST_ASIO_DECL scheduler(boost::asio::execution_context& ctx,
- int concurrency_hint = 0);
+ int concurrency_hint = 0, bool own_thread = true);
+
+ // Destructor.
+ BOOST_ASIO_DECL ~scheduler();
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -157,6 +161,10 @@ private:
BOOST_ASIO_DECL void wake_one_thread_and_unlock(
mutex::scoped_lock& lock);
+ // Helper class to run the scheduler in its own thread.
+ class thread_function;
+ friend class thread_function;
+
// Helper class to perform task-related operations on block exit.
struct task_cleanup;
friend struct task_cleanup;
@@ -200,6 +208,9 @@ private:
// The concurrency hint used to initialise the scheduler.
const int concurrency_hint_;
+
+ // The thread that is running the scheduler.
+ boost::asio::detail::thread* thread_;
};
} // namespace detail
diff --git a/boost/asio/detail/scheduler_operation.hpp b/boost/asio/detail/scheduler_operation.hpp
index 633a8c594f..df6237f48c 100644
--- a/boost/asio/detail/scheduler_operation.hpp
+++ b/boost/asio/detail/scheduler_operation.hpp
@@ -2,7 +2,7 @@
// detail/scheduler_operation.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/scheduler_thread_info.hpp b/boost/asio/detail/scheduler_thread_info.hpp
index 5f18381d50..f9b556ab8f 100644
--- a/boost/asio/detail/scheduler_thread_info.hpp
+++ b/boost/asio/detail/scheduler_thread_info.hpp
@@ -2,7 +2,7 @@
// detail/scheduler_thread_info.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/scoped_lock.hpp b/boost/asio/detail/scoped_lock.hpp
index 005585c700..74239297ed 100644
--- a/boost/asio/detail/scoped_lock.hpp
+++ b/boost/asio/detail/scoped_lock.hpp
@@ -2,7 +2,7 @@
// detail/scoped_lock.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/scoped_ptr.hpp b/boost/asio/detail/scoped_ptr.hpp
index 12ad834919..707be722f3 100644
--- a/boost/asio/detail/scoped_ptr.hpp
+++ b/boost/asio/detail/scoped_ptr.hpp
@@ -2,7 +2,7 @@
// detail/scoped_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/select_interrupter.hpp b/boost/asio/detail/select_interrupter.hpp
index d837634e89..0c2dd91216 100644
--- a/boost/asio/detail/select_interrupter.hpp
+++ b/boost/asio/detail/select_interrupter.hpp
@@ -2,7 +2,7 @@
// detail/select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/select_reactor.hpp b/boost/asio/detail/select_reactor.hpp
index dfb5e96943..435ce0463f 100644
--- a/boost/asio/detail/select_reactor.hpp
+++ b/boost/asio/detail/select_reactor.hpp
@@ -2,7 +2,7 @@
// detail/select_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/service_registry.hpp b/boost/asio/detail/service_registry.hpp
index 894fdb1b75..35140efef1 100644
--- a/boost/asio/detail/service_registry.hpp
+++ b/boost/asio/detail/service_registry.hpp
@@ -2,7 +2,7 @@
// detail/service_registry.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/signal_blocker.hpp b/boost/asio/detail/signal_blocker.hpp
index 875f188f48..9f5b6f5225 100644
--- a/boost/asio/detail/signal_blocker.hpp
+++ b/boost/asio/detail/signal_blocker.hpp
@@ -2,7 +2,7 @@
// detail/signal_blocker.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/signal_handler.hpp b/boost/asio/detail/signal_handler.hpp
index 2045db2188..3796c3b63a 100644
--- a/boost/asio/detail/signal_handler.hpp
+++ b/boost/asio/detail/signal_handler.hpp
@@ -2,7 +2,7 @@
// detail/signal_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -30,17 +30,18 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class signal_handler : public signal_op
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(signal_handler);
- signal_handler(Handler& h)
+ signal_handler(Handler& h, const IoExecutor& io_ex)
: signal_op(&signal_handler::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(h))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(h)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -50,7 +51,7 @@ public:
// Take ownership of the handler object.
signal_handler* h(static_cast<signal_handler*>(base));
ptr p = { boost::asio::detail::addressof(h->handler_), h, h };
- handler_work<Handler> w(h->handler_);
+ handler_work<Handler, IoExecutor> w(h->handler_, h->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*h));
@@ -77,6 +78,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/signal_init.hpp b/boost/asio/detail/signal_init.hpp
index 1889de689b..9fb87e5987 100644
--- a/boost/asio/detail/signal_init.hpp
+++ b/boost/asio/detail/signal_init.hpp
@@ -2,7 +2,7 @@
// detail/signal_init.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/signal_op.hpp b/boost/asio/detail/signal_op.hpp
index 74cc68290d..d7719f4cfd 100644
--- a/boost/asio/detail/signal_op.hpp
+++ b/boost/asio/detail/signal_op.hpp
@@ -2,7 +2,7 @@
// detail/signal_op.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/signal_set_service.hpp b/boost/asio/detail/signal_set_service.hpp
index 17ae44ea37..baaf856349 100644
--- a/boost/asio/detail/signal_set_service.hpp
+++ b/boost/asio/detail/signal_set_service.hpp
@@ -2,7 +2,7 @@
// detail/signal_set_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -20,7 +20,7 @@
#include <cstddef>
#include <signal.h>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/op_queue.hpp>
@@ -28,6 +28,12 @@
#include <boost/asio/detail/signal_op.hpp>
#include <boost/asio/detail/socket_types.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#if !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
# include <boost/asio/detail/reactor.hpp>
#endif // !defined(BOOST_ASIO_WINDOWS) && !defined(__CYGWIN__)
@@ -49,7 +55,7 @@ extern BOOST_ASIO_DECL struct signal_state* get_signal_state();
extern "C" BOOST_ASIO_DECL void boost_asio_signal_handler(int signal_number);
class signal_set_service :
- public service_base<signal_set_service>
+ public execution_context_service_base<signal_set_service>
{
public:
// Type used for tracking an individual signal registration.
@@ -110,7 +116,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL signal_set_service(boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL signal_set_service(execution_context& context);
// Destructor.
BOOST_ASIO_DECL ~signal_set_service();
@@ -120,7 +126,7 @@ public:
// Perform fork-related housekeeping.
BOOST_ASIO_DECL void notify_fork(
- boost::asio::io_context::fork_event fork_ev);
+ boost::asio::execution_context::fork_event fork_ev);
// Construct a new signal_set implementation.
BOOST_ASIO_DECL void construct(implementation_type& impl);
@@ -145,16 +151,17 @@ public:
boost::system::error_code& ec);
// Start an asynchronous operation to wait for a signal to be delivered.
- template <typename Handler>
- void async_wait(implementation_type& impl, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_wait(implementation_type& impl,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef signal_handler<Handler> op;
+ typedef signal_handler<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "signal_set", &impl, 0, "async_wait"));
start_wait_op(impl, p.p);
@@ -180,8 +187,13 @@ private:
// Helper function to start a wait operation.
BOOST_ASIO_DECL void start_wait_op(implementation_type& impl, signal_op* op);
- // The io_context instance used for dispatching handlers.
- io_context_impl& io_context_;
+ // The scheduler used for dispatching handlers.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
#if !defined(BOOST_ASIO_WINDOWS) \
&& !defined(BOOST_ASIO_WINDOWS_RUNTIME) \
diff --git a/boost/asio/detail/socket_holder.hpp b/boost/asio/detail/socket_holder.hpp
index b229f66b1b..c96e98297c 100644
--- a/boost/asio/detail/socket_holder.hpp
+++ b/boost/asio/detail/socket_holder.hpp
@@ -2,7 +2,7 @@
// detail/socket_holder.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/socket_ops.hpp b/boost/asio/detail/socket_ops.hpp
index 8f5fa0b3ca..506a06d776 100644
--- a/boost/asio/detail/socket_ops.hpp
+++ b/boost/asio/detail/socket_ops.hpp
@@ -2,7 +2,7 @@
// detail/socket_ops.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/socket_option.hpp b/boost/asio/detail/socket_option.hpp
index bd940142ca..8a77b1229b 100644
--- a/boost/asio/detail/socket_option.hpp
+++ b/boost/asio/detail/socket_option.hpp
@@ -2,7 +2,7 @@
// detail/socket_option.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/socket_select_interrupter.hpp b/boost/asio/detail/socket_select_interrupter.hpp
index dc7e30d69b..fc812701d7 100644
--- a/boost/asio/detail/socket_select_interrupter.hpp
+++ b/boost/asio/detail/socket_select_interrupter.hpp
@@ -2,7 +2,7 @@
// detail/socket_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/socket_types.hpp b/boost/asio/detail/socket_types.hpp
index 11ed551838..867caa5845 100644
--- a/boost/asio/detail/socket_types.hpp
+++ b/boost/asio/detail/socket_types.hpp
@@ -2,7 +2,7 @@
// detail/socket_types.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/solaris_fenced_block.hpp b/boost/asio/detail/solaris_fenced_block.hpp
index 3b605daf39..aa7fca3303 100644
--- a/boost/asio/detail/solaris_fenced_block.hpp
+++ b/boost/asio/detail/solaris_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/solaris_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/static_mutex.hpp b/boost/asio/detail/static_mutex.hpp
index 1bc5c2c813..b6194e400d 100644
--- a/boost/asio/detail/static_mutex.hpp
+++ b/boost/asio/detail/static_mutex.hpp
@@ -2,7 +2,7 @@
// detail/static_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_event.hpp b/boost/asio/detail/std_event.hpp
index d32bff422e..9532ec9f95 100644
--- a/boost/asio/detail/std_event.hpp
+++ b/boost/asio/detail/std_event.hpp
@@ -2,7 +2,7 @@
// detail/std_event.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_fenced_block.hpp b/boost/asio/detail/std_fenced_block.hpp
index 3993199145..2d87752079 100644
--- a/boost/asio/detail/std_fenced_block.hpp
+++ b/boost/asio/detail/std_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/std_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_global.hpp b/boost/asio/detail/std_global.hpp
index f9df646bc6..1c19afe13c 100644
--- a/boost/asio/detail/std_global.hpp
+++ b/boost/asio/detail/std_global.hpp
@@ -2,7 +2,7 @@
// detail/std_global.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_mutex.hpp b/boost/asio/detail/std_mutex.hpp
index 463735b92a..7bd17cb00f 100644
--- a/boost/asio/detail/std_mutex.hpp
+++ b/boost/asio/detail/std_mutex.hpp
@@ -2,7 +2,7 @@
// detail/std_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_static_mutex.hpp b/boost/asio/detail/std_static_mutex.hpp
index 16104bcfa6..9b0581ee59 100644
--- a/boost/asio/detail/std_static_mutex.hpp
+++ b/boost/asio/detail/std_static_mutex.hpp
@@ -2,7 +2,7 @@
// detail/std_static_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/std_thread.hpp b/boost/asio/detail/std_thread.hpp
index af507ed32f..314a06cae5 100644
--- a/boost/asio/detail/std_thread.hpp
+++ b/boost/asio/detail/std_thread.hpp
@@ -2,7 +2,7 @@
// detail/std_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/strand_executor_service.hpp b/boost/asio/detail/strand_executor_service.hpp
index c3e68408dc..4fc9327ecd 100644
--- a/boost/asio/detail/strand_executor_service.hpp
+++ b/boost/asio/detail/strand_executor_service.hpp
@@ -2,7 +2,7 @@
// detail/strand_executor_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/strand_service.hpp b/boost/asio/detail/strand_service.hpp
index f036264b95..14271c4e4e 100644
--- a/boost/asio/detail/strand_service.hpp
+++ b/boost/asio/detail/strand_service.hpp
@@ -2,7 +2,7 @@
// detail/strand_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/string_view.hpp b/boost/asio/detail/string_view.hpp
index f74d730c0b..07080c1e7c 100644
--- a/boost/asio/detail/string_view.hpp
+++ b/boost/asio/detail/string_view.hpp
@@ -2,7 +2,7 @@
// detail/string_view.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/thread.hpp b/boost/asio/detail/thread.hpp
index 41810c6477..a888d52dd2 100644
--- a/boost/asio/detail/thread.hpp
+++ b/boost/asio/detail/thread.hpp
@@ -2,7 +2,7 @@
// detail/thread.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/thread_context.hpp b/boost/asio/detail/thread_context.hpp
index b4a2435f0f..2005a0d76b 100644
--- a/boost/asio/detail/thread_context.hpp
+++ b/boost/asio/detail/thread_context.hpp
@@ -2,7 +2,7 @@
// detail/thread_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/thread_group.hpp b/boost/asio/detail/thread_group.hpp
index c9c194142f..c6a4a99773 100644
--- a/boost/asio/detail/thread_group.hpp
+++ b/boost/asio/detail/thread_group.hpp
@@ -2,7 +2,7 @@
// detail/thread_group.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -65,6 +65,12 @@ public:
}
}
+ // Test whether the group is empty.
+ bool empty() const
+ {
+ return first_ == 0;
+ }
+
private:
// Structure used to track a single thread in the group.
struct item
diff --git a/boost/asio/detail/thread_info_base.hpp b/boost/asio/detail/thread_info_base.hpp
index 16bb1787f3..6b7a20c5ed 100644
--- a/boost/asio/detail/thread_info_base.hpp
+++ b/boost/asio/detail/thread_info_base.hpp
@@ -2,7 +2,7 @@
// detail/thread_info_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,11 +34,16 @@ public:
enum { mem_index = 0 };
};
- struct awaitee_tag
+ struct awaitable_frame_tag
{
enum { mem_index = 1 };
};
+ struct executor_function_tag
+ {
+ enum { mem_index = 2 };
+ };
+
thread_info_base()
{
for (int i = 0; i < max_mem_index; ++i)
@@ -110,7 +115,7 @@ public:
private:
enum { chunk_size = 4 };
- enum { max_mem_index = 2 };
+ enum { max_mem_index = 3 };
void* reusable_memory_[max_mem_index];
};
diff --git a/boost/asio/detail/throw_error.hpp b/boost/asio/detail/throw_error.hpp
index c1775b2536..d31c859876 100644
--- a/boost/asio/detail/throw_error.hpp
+++ b/boost/asio/detail/throw_error.hpp
@@ -2,7 +2,7 @@
// detail/throw_error.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/throw_exception.hpp b/boost/asio/detail/throw_exception.hpp
index 8690fa6f63..6190419f55 100644
--- a/boost/asio/detail/throw_exception.hpp
+++ b/boost/asio/detail/throw_exception.hpp
@@ -2,7 +2,7 @@
// detail/throw_exception.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_queue.hpp b/boost/asio/detail/timer_queue.hpp
index 3b2bcff774..9ce6995b73 100644
--- a/boost/asio/detail/timer_queue.hpp
+++ b/boost/asio/detail/timer_queue.hpp
@@ -2,7 +2,7 @@
// detail/timer_queue.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_queue_base.hpp b/boost/asio/detail/timer_queue_base.hpp
index f3a14238aa..c95a2a520c 100644
--- a/boost/asio/detail/timer_queue_base.hpp
+++ b/boost/asio/detail/timer_queue_base.hpp
@@ -2,7 +2,7 @@
// detail/timer_queue_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_queue_ptime.hpp b/boost/asio/detail/timer_queue_ptime.hpp
index cc053bff9d..d803befb9f 100644
--- a/boost/asio/detail/timer_queue_ptime.hpp
+++ b/boost/asio/detail/timer_queue_ptime.hpp
@@ -2,7 +2,7 @@
// detail/timer_queue_ptime.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_queue_set.hpp b/boost/asio/detail/timer_queue_set.hpp
index 2bed122fc2..9b25e20892 100644
--- a/boost/asio/detail/timer_queue_set.hpp
+++ b/boost/asio/detail/timer_queue_set.hpp
@@ -2,7 +2,7 @@
// detail/timer_queue_set.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_scheduler.hpp b/boost/asio/detail/timer_scheduler.hpp
index dc6e8d890c..9d68a602c4 100644
--- a/boost/asio/detail/timer_scheduler.hpp
+++ b/boost/asio/detail/timer_scheduler.hpp
@@ -2,7 +2,7 @@
// detail/timer_scheduler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/timer_scheduler_fwd.hpp b/boost/asio/detail/timer_scheduler_fwd.hpp
index c3656c66a0..0675edf83a 100644
--- a/boost/asio/detail/timer_scheduler_fwd.hpp
+++ b/boost/asio/detail/timer_scheduler_fwd.hpp
@@ -2,7 +2,7 @@
// detail/timer_scheduler_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/tss_ptr.hpp b/boost/asio/detail/tss_ptr.hpp
index 7850718a3c..a7c87d2103 100644
--- a/boost/asio/detail/tss_ptr.hpp
+++ b/boost/asio/detail/tss_ptr.hpp
@@ -2,7 +2,7 @@
// detail/tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/type_traits.hpp b/boost/asio/detail/type_traits.hpp
index a0d4cb4902..c53a7e745c 100644
--- a/boost/asio/detail/type_traits.hpp
+++ b/boost/asio/detail/type_traits.hpp
@@ -2,7 +2,7 @@
// detail/type_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/variadic_templates.hpp b/boost/asio/detail/variadic_templates.hpp
index c358feec18..f552b4b026 100644
--- a/boost/asio/detail/variadic_templates.hpp
+++ b/boost/asio/detail/variadic_templates.hpp
@@ -2,7 +2,7 @@
// detail/variadic_templates.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -58,6 +58,20 @@
# define BOOST_ASIO_VARIADIC_BYVAL_ARGS_4 x1, x2, x3, x4
# define BOOST_ASIO_VARIADIC_BYVAL_ARGS_5 x1, x2, x3, x4, x5
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n) \
+ BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_##n
+
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_1 \
+ const T1& x1
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_2 \
+ const T1& x1, const T2& x2
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_3 \
+ const T1& x1, const T2& x2, const T3& x3
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_4 \
+ const T1& x1, const T2& x2, const T3& x3, const T4& x4
+# define BOOST_ASIO_VARIADIC_CONSTREF_PARAMS_5 \
+ const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5
+
# define BOOST_ASIO_VARIADIC_MOVE_PARAMS(n) \
BOOST_ASIO_VARIADIC_MOVE_PARAMS_##n
diff --git a/boost/asio/detail/wait_handler.hpp b/boost/asio/detail/wait_handler.hpp
index a9341244f8..b94773467e 100644
--- a/boost/asio/detail/wait_handler.hpp
+++ b/boost/asio/detail/wait_handler.hpp
@@ -2,7 +2,7 @@
// detail/wait_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -19,9 +19,9 @@
#include <boost/asio/detail/fenced_block.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/handler_work.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/wait_op.hpp>
-#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -29,17 +29,18 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class wait_handler : public wait_op
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(wait_handler);
- wait_handler(Handler& h)
+ wait_handler(Handler& h, const IoExecutor& ex)
: wait_op(&wait_handler::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(h))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(h)),
+ io_executor_(ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -49,7 +50,7 @@ public:
// Take ownership of the handler object.
wait_handler* h(static_cast<wait_handler*>(base));
ptr p = { boost::asio::detail::addressof(h->handler_), h, h };
- handler_work<Handler> w(h->handler_);
+ handler_work<Handler, IoExecutor> w(h->handler_, h->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*h));
@@ -76,6 +77,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/wait_op.hpp b/boost/asio/detail/wait_op.hpp
index 3a95a37580..a6b88f6e35 100644
--- a/boost/asio/detail/wait_op.hpp
+++ b/boost/asio/detail/wait_op.hpp
@@ -2,7 +2,7 @@
// detail/wait_op.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_event.hpp b/boost/asio/detail/win_event.hpp
index 67edbcfb89..08de010af4 100644
--- a/boost/asio/detail/win_event.hpp
+++ b/boost/asio/detail/win_event.hpp
@@ -2,7 +2,7 @@
// detail/win_event.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_fd_set_adapter.hpp b/boost/asio/detail/win_fd_set_adapter.hpp
index bdddb32a9d..3f66d4af33 100644
--- a/boost/asio/detail/win_fd_set_adapter.hpp
+++ b/boost/asio/detail/win_fd_set_adapter.hpp
@@ -2,7 +2,7 @@
// detail/win_fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_fenced_block.hpp b/boost/asio/detail/win_fenced_block.hpp
index c595eaa00f..42aee2d774 100644
--- a/boost/asio/detail/win_fenced_block.hpp
+++ b/boost/asio/detail/win_fenced_block.hpp
@@ -2,7 +2,7 @@
// detail/win_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_global.hpp b/boost/asio/detail/win_global.hpp
index 11204dec6d..1165579baa 100644
--- a/boost/asio/detail/win_global.hpp
+++ b/boost/asio/detail/win_global.hpp
@@ -2,7 +2,7 @@
// detail/win_global.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -36,7 +36,7 @@ struct win_global_impl
static win_global_impl instance_;
static static_mutex mutex_;
- static T* ptr_;
+ T* ptr_;
static tss_ptr<T> tss_ptr_;
};
@@ -47,9 +47,6 @@ template <typename T>
static_mutex win_global_impl<T>::mutex_ = BOOST_ASIO_STATIC_MUTEX_INIT;
template <typename T>
-T* win_global_impl<T>::ptr_ = 0;
-
-template <typename T>
tss_ptr<T> win_global_impl<T>::tss_ptr_;
template <typename T>
@@ -59,9 +56,9 @@ T& win_global()
{
win_global_impl<T>::mutex_.init();
static_mutex::scoped_lock lock(win_global_impl<T>::mutex_);
- if (win_global_impl<T>::ptr_ == 0)
- win_global_impl<T>::ptr_ = new T;
- win_global_impl<T>::tss_ptr_ = win_global_impl<T>::ptr_;
+ if (win_global_impl<T>::instance_.ptr_ == 0)
+ win_global_impl<T>::instance_.ptr_ = new T;
+ win_global_impl<T>::tss_ptr_ = win_global_impl<T>::instance_.ptr_;
}
return *win_global_impl<T>::tss_ptr_;
diff --git a/boost/asio/detail/win_iocp_handle_read_op.hpp b/boost/asio/detail/win_iocp_handle_read_op.hpp
index 842ed80b73..04675ab9a4 100644
--- a/boost/asio/detail/win_iocp_handle_read_op.hpp
+++ b/boost/asio/detail/win_iocp_handle_read_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_handle_read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -35,19 +35,20 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
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)
+ win_iocp_handle_read_op(const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_handle_read_op::do_complete),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -59,7 +60,7 @@ public:
// Take ownership of the operation object.
win_iocp_handle_read_op* o(static_cast<win_iocp_handle_read_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -100,6 +101,7 @@ public:
private:
MutableBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_handle_service.hpp b/boost/asio/detail/win_iocp_handle_service.hpp
index 4d5aadeef5..92aa8e88ca 100644
--- a/boost/asio/detail/win_iocp_handle_service.hpp
+++ b/boost/asio/detail/win_iocp_handle_service.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_handle_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -21,7 +21,7 @@
#if defined(BOOST_ASIO_HAS_IOCP)
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/cstdint.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
@@ -39,7 +39,7 @@ namespace asio {
namespace detail {
class win_iocp_handle_service :
- public service_base<win_iocp_handle_service>
+ public execution_context_service_base<win_iocp_handle_service>
{
public:
// The native type of a stream handle.
@@ -76,7 +76,7 @@ public:
implementation_type* prev_;
};
- BOOST_ASIO_DECL win_iocp_handle_service(boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL win_iocp_handle_service(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -143,15 +143,17 @@ public:
// Start an asynchronous write. The data being written must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, Handler& handler)
+ const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op;
+ typedef win_iocp_handle_write_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl,
reinterpret_cast<uintmax_t>(impl.handle_), "async_write_some"));
@@ -164,15 +166,17 @@ public:
// Start an asynchronous write at a specified offset. The data being written
// must be valid for the lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
- void async_write_some_at(implementation_type& impl, uint64_t offset,
- const ConstBufferSequence& buffers, Handler& handler)
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
+ void async_write_some_at(implementation_type& impl,
+ uint64_t offset, const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_handle_write_op<ConstBufferSequence, Handler> op;
+ typedef win_iocp_handle_write_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl,
reinterpret_cast<uintmax_t>(impl.handle_), "async_write_some_at"));
@@ -205,15 +209,18 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op;
+ typedef win_iocp_handle_read_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl,
reinterpret_cast<uintmax_t>(impl.handle_), "async_read_some"));
@@ -227,15 +234,18 @@ public:
// Start an asynchronous read at a specified offset. The buffer for the data
// being received must be valid for the lifetime of the asynchronous
// operation.
- template <typename MutableBufferSequence, typename Handler>
- void async_read_some_at(implementation_type& impl, uint64_t offset,
- const MutableBufferSequence& buffers, Handler& handler)
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
+ void async_read_some_at(implementation_type& impl,
+ uint64_t offset, const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_handle_read_op<MutableBufferSequence, Handler> op;
+ typedef win_iocp_handle_read_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
BOOST_ASIO_HANDLER_CREATION((iocp_service_.context(), *p.p, "handle", &impl,
reinterpret_cast<uintmax_t>(impl.handle_), "async_read_some_at"));
@@ -252,22 +262,24 @@ private:
const null_buffers& buffers, boost::system::error_code& ec);
size_t write_some_at(implementation_type& impl, uint64_t offset,
const null_buffers& buffers, boost::system::error_code& ec);
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const null_buffers& buffers, Handler& handler);
- template <typename Handler>
+ const null_buffers& buffers, Handler& handler,
+ const IoExecutor& io_ex);
+ template <typename Handler, typename IoExecutor>
void async_write_some_at(implementation_type& impl, uint64_t offset,
- const null_buffers& buffers, Handler& handler);
+ const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex);
size_t read_some(implementation_type& impl,
const null_buffers& buffers, boost::system::error_code& ec);
size_t read_some_at(implementation_type& impl, uint64_t offset,
const null_buffers& buffers, boost::system::error_code& ec);
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const null_buffers& buffers, Handler& handler);
- template <typename Handler>
+ const null_buffers& buffers, Handler& handler,
+ const IoExecutor& io_ex);
+ template <typename Handler, typename IoExecutor>
void async_read_some_at(implementation_type& impl, uint64_t offset,
- const null_buffers& buffers, Handler& handler);
+ const null_buffers& buffers, Handler& handler, const IoExecutor& io_ex);
// Helper class for waiting for synchronous operations to complete.
class overlapped_wrapper;
diff --git a/boost/asio/detail/win_iocp_handle_write_op.hpp b/boost/asio/detail/win_iocp_handle_write_op.hpp
index 582b3f2b82..7e81eb843b 100644
--- a/boost/asio/detail/win_iocp_handle_write_op.hpp
+++ b/boost/asio/detail/win_iocp_handle_write_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_handle_write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -35,18 +35,20 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename ConstBufferSequence, typename Handler>
+template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
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)
+ win_iocp_handle_write_op(const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_handle_write_op::do_complete),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -55,7 +57,7 @@ public:
// Take ownership of the operation object.
win_iocp_handle_write_op* o(static_cast<win_iocp_handle_write_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -92,6 +94,7 @@ public:
private:
ConstBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_io_context.hpp b/boost/asio/detail/win_iocp_io_context.hpp
index 1ccdf35f65..d551b9b27f 100644
--- a/boost/asio/detail/win_iocp_io_context.hpp
+++ b/boost/asio/detail/win_iocp_io_context.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_io_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -49,7 +49,10 @@ public:
// Constructor. Specifies a concurrency hint that is passed through to the
// underlying I/O completion port.
BOOST_ASIO_DECL win_iocp_io_context(boost::asio::execution_context& ctx,
- int concurrency_hint = -1);
+ int concurrency_hint = -1, bool own_thread = true);
+
+ // Destructor.
+ BOOST_ASIO_DECL ~win_iocp_io_context();
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -288,6 +291,10 @@ private:
// Timeout to use with GetQueuedCompletionStatus.
const DWORD gqcs_timeout_;
+ // Helper class to run the scheduler in its own thread.
+ struct thread_function;
+ friend struct thread_function;
+
// Function object for processing timeouts in a background thread.
struct timer_thread_function;
friend struct timer_thread_function;
@@ -312,6 +319,9 @@ private:
// The concurrency hint used to initialise the io_context.
const int concurrency_hint_;
+
+ // The thread that is running the io_context.
+ scoped_ptr<thread> thread_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_null_buffers_op.hpp b/boost/asio/detail/win_iocp_null_buffers_op.hpp
index 106bedeba0..c32163987f 100644
--- a/boost/asio/detail/win_iocp_null_buffers_op.hpp
+++ b/boost/asio/detail/win_iocp_null_buffers_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_null_buffers_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,20 +35,21 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
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)
+ Handler& handler, const IoExecutor& io_ex)
: reactor_op(&win_iocp_null_buffers_op::do_perform,
&win_iocp_null_buffers_op::do_complete),
cancel_token_(cancel_token),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static status do_perform(reactor_op*)
@@ -65,7 +66,7 @@ public:
// Take ownership of the operation object.
win_iocp_null_buffers_op* o(static_cast<win_iocp_null_buffers_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -110,6 +111,7 @@ public:
private:
socket_ops::weak_cancel_token_type cancel_token_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_operation.hpp b/boost/asio/detail/win_iocp_operation.hpp
index 11111f3150..5cad6e338c 100644
--- a/boost/asio/detail/win_iocp_operation.hpp
+++ b/boost/asio/detail/win_iocp_operation.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_operation.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_iocp_overlapped_op.hpp b/boost/asio/detail/win_iocp_overlapped_op.hpp
index 18f0d63173..c36e764a11 100644
--- a/boost/asio/detail/win_iocp_overlapped_op.hpp
+++ b/boost/asio/detail/win_iocp_overlapped_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_overlapped_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -33,17 +33,18 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class win_iocp_overlapped_op : public operation
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_overlapped_op);
- win_iocp_overlapped_op(Handler& handler)
+ win_iocp_overlapped_op(Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_overlapped_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -52,7 +53,7 @@ public:
// Take ownership of the operation object.
win_iocp_overlapped_op* o(static_cast<win_iocp_overlapped_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -79,6 +80,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_overlapped_ptr.hpp b/boost/asio/detail/win_iocp_overlapped_ptr.hpp
index 6cff7ae1d4..d1ed1cb1a0 100644
--- a/boost/asio/detail/win_iocp_overlapped_ptr.hpp
+++ b/boost/asio/detail/win_iocp_overlapped_ptr.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_overlapped_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,6 +21,7 @@
#include <boost/asio/io_context.hpp>
#include <boost/asio/detail/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/io_object_executor.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/win_iocp_overlapped_op.hpp>
@@ -45,13 +46,13 @@ public:
}
// Construct an win_iocp_overlapped_ptr to contain the specified handler.
- template <typename Handler>
- explicit win_iocp_overlapped_ptr(
- boost::asio::io_context& io_context, BOOST_ASIO_MOVE_ARG(Handler) handler)
+ template <typename Executor, typename Handler>
+ explicit win_iocp_overlapped_ptr(const Executor& ex,
+ BOOST_ASIO_MOVE_ARG(Handler) handler)
: ptr_(0),
iocp_service_(0)
{
- this->reset(io_context, BOOST_ASIO_MOVE_CAST(Handler)(handler));
+ this->reset(ex, BOOST_ASIO_MOVE_CAST(Handler)(handler));
}
// Destructor automatically frees the OVERLAPPED object unless released.
@@ -74,22 +75,25 @@ public:
// Reset to contain the specified handler, freeing any current OVERLAPPED
// object.
- template <typename Handler>
- void reset(boost::asio::io_context& io_context, Handler handler)
+ template <typename Executor, typename Handler>
+ void reset(const Executor& ex, Handler handler)
{
- typedef win_iocp_overlapped_op<Handler> op;
+ const bool native = is_same<Executor, io_context::executor_type>::value;
+ win_iocp_io_context* iocp_service = this->get_iocp_service(ex);
+
+ typedef win_iocp_overlapped_op<Handler, io_object_executor<Executor> > op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_object_executor<Executor>(ex, native));
- BOOST_ASIO_HANDLER_CREATION((io_context, *p.p,
- "io_context", &io_context.impl_, 0, "overlapped"));
+ BOOST_ASIO_HANDLER_CREATION((ex.context(), *p.p,
+ "iocp_service", iocp_service, 0, "overlapped"));
- io_context.impl_.work_started();
+ iocp_service->work_started();
reset();
ptr_ = p.p;
p.v = p.p = 0;
- iocp_service_ = &io_context.impl_;
+ iocp_service_ = iocp_service;
}
// Get the contained OVERLAPPED object.
@@ -130,6 +134,18 @@ public:
}
private:
+ template <typename Executor>
+ static win_iocp_io_context* get_iocp_service(const Executor& ex)
+ {
+ return &use_service<win_iocp_io_context>(ex.context());
+ }
+
+ static win_iocp_io_context* get_iocp_service(
+ const io_context::executor_type& ex)
+ {
+ return &ex.context().impl_;
+ }
+
win_iocp_operation* ptr_;
win_iocp_io_context* iocp_service_;
};
diff --git a/boost/asio/detail/win_iocp_serial_port_service.hpp b/boost/asio/detail/win_iocp_serial_port_service.hpp
index 3da2537295..6f05d92fc1 100644
--- a/boost/asio/detail/win_iocp_serial_port_service.hpp
+++ b/boost/asio/detail/win_iocp_serial_port_service.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_serial_port_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -22,7 +22,7 @@
#include <string>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/win_iocp_handle_service.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -33,7 +33,7 @@ namespace detail {
// Extend win_iocp_handle_service to provide serial port support.
class win_iocp_serial_port_service :
- public service_base<win_iocp_serial_port_service>
+ public execution_context_service_base<win_iocp_serial_port_service>
{
public:
// The native type of a serial port.
@@ -43,8 +43,7 @@ public:
typedef win_iocp_handle_service::implementation_type implementation_type;
// Constructor.
- BOOST_ASIO_DECL win_iocp_serial_port_service(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL win_iocp_serial_port_service(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -152,11 +151,12 @@ public:
// Start an asynchronous write. The data being written must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, Handler& handler)
+ const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
- handle_service_.async_write_some(impl, buffers, handler);
+ handle_service_.async_write_some(impl, buffers, handler, io_ex);
}
// Read some data. Returns the number of bytes received.
@@ -169,11 +169,13 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
{
- handle_service_.async_read_some(impl, buffers, handler);
+ handle_service_.async_read_some(impl, buffers, handler, io_ex);
}
private:
diff --git a/boost/asio/detail/win_iocp_socket_accept_op.hpp b/boost/asio/detail/win_iocp_socket_accept_op.hpp
index 8e1b7fc93a..75dadc27c1 100644
--- a/boost/asio/detail/win_iocp_socket_accept_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_accept_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_accept_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -36,7 +36,8 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Socket, typename Protocol, typename Handler>
+template <typename Socket, typename Protocol,
+ typename Handler, typename IoExecutor>
class win_iocp_socket_accept_op : public operation
{
public:
@@ -45,7 +46,7 @@ public:
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)
+ bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_socket_accept_op::do_complete),
socket_service_(socket_service),
socket_(socket),
@@ -53,9 +54,10 @@ public:
protocol_(protocol),
peer_endpoint_(peer_endpoint),
enable_connection_aborted_(enable_connection_aborted),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
socket_holder& new_socket()
@@ -82,7 +84,7 @@ public:
// Take ownership of the operation object.
win_iocp_socket_accept_op* o(static_cast<win_iocp_socket_accept_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
if (owner)
{
@@ -156,11 +158,13 @@ private:
unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
bool enable_connection_aborted_;
Handler handler_;
+ IoExecutor io_executor_;
};
#if defined(BOOST_ASIO_HAS_MOVE)
-template <typename Protocol, typename Handler>
+template <typename Protocol, typename PeerIoExecutor,
+ typename Handler, typename IoExecutor>
class win_iocp_socket_move_accept_op : public operation
{
public:
@@ -168,19 +172,20 @@ public:
win_iocp_socket_move_accept_op(
win_iocp_socket_service_base& socket_service, socket_type socket,
- const Protocol& protocol, boost::asio::io_context& peer_io_context,
+ const Protocol& protocol, const PeerIoExecutor& peer_io_ex,
typename Protocol::endpoint* peer_endpoint,
- bool enable_connection_aborted, Handler& handler)
+ bool enable_connection_aborted, Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_socket_move_accept_op::do_complete),
socket_service_(socket_service),
socket_(socket),
- peer_(peer_io_context),
+ peer_(peer_io_ex),
protocol_(protocol),
peer_endpoint_(peer_endpoint),
enable_connection_aborted_(enable_connection_aborted),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
socket_holder& new_socket()
@@ -208,7 +213,7 @@ public:
win_iocp_socket_move_accept_op* o(
static_cast<win_iocp_socket_move_accept_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
if (owner)
{
@@ -258,9 +263,9 @@ public:
// to ensure that any owning sub-object remains valid until after we have
// deallocated the memory here.
detail::move_binder2<Handler,
- boost::system::error_code, typename Protocol::socket>
+ boost::system::error_code, peer_socket_type>
handler(0, BOOST_ASIO_MOVE_CAST(Handler)(o->handler_), ec,
- BOOST_ASIO_MOVE_CAST(typename Protocol::socket)(o->peer_));
+ BOOST_ASIO_MOVE_CAST(peer_socket_type)(o->peer_));
p.h = boost::asio::detail::addressof(handler.handler_);
p.reset();
@@ -275,15 +280,19 @@ public:
}
private:
+ typedef typename Protocol::socket::template
+ rebind_executor<PeerIoExecutor>::other peer_socket_type;
+
win_iocp_socket_service_base& socket_service_;
socket_type socket_;
socket_holder new_socket_;
- typename Protocol::socket peer_;
+ peer_socket_type peer_;
Protocol protocol_;
typename Protocol::endpoint* peer_endpoint_;
unsigned char output_buffer_[(sizeof(sockaddr_storage_type) + 16) * 2];
bool enable_connection_aborted_;
Handler handler_;
+ IoExecutor io_executor_;
};
#endif // defined(BOOST_ASIO_HAS_MOVE)
diff --git a/boost/asio/detail/win_iocp_socket_connect_op.hpp b/boost/asio/detail/win_iocp_socket_connect_op.hpp
index 916d22ee49..0041a059ab 100644
--- a/boost/asio/detail/win_iocp_socket_connect_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_connect_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_connect_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -57,18 +57,20 @@ public:
bool connect_ex_;
};
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class win_iocp_socket_connect_op : public win_iocp_socket_connect_op_base
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_socket_connect_op);
- win_iocp_socket_connect_op(socket_type socket, Handler& handler)
+ win_iocp_socket_connect_op(socket_type socket,
+ Handler& handler, const IoExecutor& io_ex)
: win_iocp_socket_connect_op_base(socket,
&win_iocp_socket_connect_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -81,7 +83,7 @@ public:
win_iocp_socket_connect_op* o(
static_cast<win_iocp_socket_connect_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
if (owner)
{
@@ -116,6 +118,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_socket_recv_op.hpp b/boost/asio/detail/win_iocp_socket_recv_op.hpp
index b052ec236e..daa3ca24ec 100644
--- a/boost/asio/detail/win_iocp_socket_recv_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_recv_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_recv_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,7 +35,7 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class win_iocp_socket_recv_op : public operation
{
public:
@@ -43,14 +43,16 @@ public:
win_iocp_socket_recv_op(socket_ops::state_type state,
socket_ops::weak_cancel_token_type cancel_token,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers, Handler& handler,
+ const IoExecutor& io_ex)
: operation(&win_iocp_socket_recv_op::do_complete),
state_(state),
cancel_token_(cancel_token),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -62,7 +64,7 @@ public:
// Take ownership of the operation object.
win_iocp_socket_recv_op* o(static_cast<win_iocp_socket_recv_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -106,6 +108,7 @@ private:
socket_ops::weak_cancel_token_type cancel_token_;
MutableBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp b/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp
index a7338c8877..bfd469a3d0 100644
--- a/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_recvfrom_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_recvfrom_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,7 +35,8 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename MutableBufferSequence, typename Endpoint, typename Handler>
+template <typename MutableBufferSequence, typename Endpoint,
+ typename Handler, typename IoExecutor>
class win_iocp_socket_recvfrom_op : public operation
{
public:
@@ -43,15 +44,17 @@ public:
win_iocp_socket_recvfrom_op(Endpoint& endpoint,
socket_ops::weak_cancel_token_type cancel_token,
- const MutableBufferSequence& buffers, Handler& handler)
+ const MutableBufferSequence& buffers, Handler& handler,
+ const IoExecutor& io_ex)
: operation(&win_iocp_socket_recvfrom_op::do_complete),
endpoint_(endpoint),
endpoint_size_(static_cast<int>(endpoint.capacity())),
cancel_token_(cancel_token),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
int& endpoint_size()
@@ -69,7 +72,7 @@ public:
win_iocp_socket_recvfrom_op* o(
static_cast<win_iocp_socket_recvfrom_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -114,6 +117,7 @@ private:
socket_ops::weak_cancel_token_type cancel_token_;
MutableBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp b/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp
index 4a8313225d..73127dca80 100644
--- a/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_recvmsg_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_recvmsg_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -36,7 +36,7 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class win_iocp_socket_recvmsg_op : public operation
{
public:
@@ -45,14 +45,16 @@ public:
win_iocp_socket_recvmsg_op(
socket_ops::weak_cancel_token_type cancel_token,
const MutableBufferSequence& buffers,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags,
+ Handler& handler, const IoExecutor& io_ex)
: operation(&win_iocp_socket_recvmsg_op::do_complete),
cancel_token_(cancel_token),
buffers_(buffers),
out_flags_(out_flags),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -65,7 +67,7 @@ public:
win_iocp_socket_recvmsg_op* o(
static_cast<win_iocp_socket_recvmsg_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -107,6 +109,7 @@ private:
MutableBufferSequence buffers_;
socket_base::message_flags& out_flags_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_socket_send_op.hpp b/boost/asio/detail/win_iocp_socket_send_op.hpp
index 7dc9ab3175..5f1fc4ad8e 100644
--- a/boost/asio/detail/win_iocp_socket_send_op.hpp
+++ b/boost/asio/detail/win_iocp_socket_send_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_send_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,20 +35,22 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename ConstBufferSequence, typename Handler>
+template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
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)
+ const ConstBufferSequence& buffers, Handler& handler,
+ const IoExecutor& io_ex)
: operation(&win_iocp_socket_send_op::do_complete),
cancel_token_(cancel_token),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -60,7 +62,7 @@ public:
// Take ownership of the operation object.
win_iocp_socket_send_op* o(static_cast<win_iocp_socket_send_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -100,6 +102,7 @@ private:
socket_ops::weak_cancel_token_type cancel_token_;
ConstBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_iocp_socket_service.hpp b/boost/asio/detail/win_iocp_socket_service.hpp
index d71c6ee046..df2292a55e 100644
--- a/boost/asio/detail/win_iocp_socket_service.hpp
+++ b/boost/asio/detail/win_iocp_socket_service.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,7 +21,7 @@
#include <cstring>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
@@ -52,7 +52,7 @@ namespace detail {
template <typename Protocol>
class win_iocp_socket_service :
- public service_base<win_iocp_socket_service<Protocol> >,
+ public execution_context_service_base<win_iocp_socket_service<Protocol> >,
public win_iocp_socket_service_base
{
public:
@@ -130,9 +130,10 @@ public:
};
// Constructor.
- win_iocp_socket_service(boost::asio::io_context& io_context)
- : service_base<win_iocp_socket_service<Protocol> >(io_context),
- win_iocp_socket_service_base(io_context)
+ win_iocp_socket_service(execution_context& context)
+ : execution_context_service_base<
+ win_iocp_socket_service<Protocol> >(context),
+ win_iocp_socket_service_base(context)
{
}
@@ -324,18 +325,20 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
- socket_base::message_flags flags, Handler& handler)
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op;
+ typedef win_iocp_socket_send_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, buffers, handler);
+ p.p = new (p.v) op(impl.cancel_token_, buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_send_to"));
buffer_sequence_adapter<boost::asio::const_buffer,
@@ -348,17 +351,18 @@ public:
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send_to(implementation_type& impl, const null_buffers&,
- const endpoint_type&, socket_base::message_flags, Handler& handler)
+ const endpoint_type&, socket_base::message_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_null_buffers_op<Handler> op;
+ typedef win_iocp_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_send_to(null_buffers)"));
start_reactor_op(impl, select_reactor::write_op, p.p);
@@ -404,19 +408,22 @@ public:
// 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.
- template <typename MutableBufferSequence, typename Handler>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endp,
- socket_base::message_flags flags, Handler& handler)
+ socket_base::message_flags flags, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_recvfrom_op<
- MutableBufferSequence, endpoint_type, Handler> op;
+ typedef win_iocp_socket_recvfrom_op<MutableBufferSequence,
+ endpoint_type, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(sender_endp, impl.cancel_token_, buffers, handler);
+ p.p = new (p.v) op(sender_endp, impl.cancel_token_,
+ buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive_from"));
buffer_sequence_adapter<boost::asio::mutable_buffer,
@@ -428,18 +435,18 @@ public:
}
// Wait until data can be received without blocking.
- template <typename Handler>
- void async_receive_from(implementation_type& impl,
- const null_buffers&, endpoint_type& sender_endpoint,
- socket_base::message_flags flags, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_null_buffers_op<Handler> op;
+ typedef win_iocp_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive_from(null_buffers)"));
// Reset endpoint since it can be given no sensible value at this time.
@@ -479,50 +486,23 @@ public:
return ec;
}
-#if defined(BOOST_ASIO_HAS_MOVE)
- // Accept a new connection.
- typename Protocol::socket accept(implementation_type& impl,
- io_context* peer_io_context, endpoint_type* peer_endpoint,
- boost::system::error_code& ec)
- {
- typename Protocol::socket peer(
- peer_io_context ? *peer_io_context : io_context_);
-
- 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() != invalid_socket)
- {
- if (peer_endpoint)
- peer_endpoint->resize(addr_len);
- peer.assign(impl.protocol_, new_socket.get(), ec);
- if (!ec)
- new_socket.release();
- }
-
- return peer;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
// Start an asynchronous accept. The peer and peer_endpoint objects
// must be valid until the accept's handler is invoked.
- template <typename Socket, typename Handler>
+ template <typename Socket, typename Handler, typename IoExecutor>
void async_accept(implementation_type& impl, Socket& peer,
- endpoint_type* peer_endpoint, Handler& handler)
+ endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_accept_op<Socket, protocol_type, Handler> op;
+ typedef win_iocp_socket_accept_op<Socket,
+ protocol_type, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
bool enable_connection_aborted =
(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);
+ peer_endpoint, enable_connection_aborted, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_accept"));
start_accept_op(impl, peer.is_open(), p.p->new_socket(),
@@ -535,22 +515,23 @@ public:
#if defined(BOOST_ASIO_HAS_MOVE)
// Start an asynchronous accept. The peer and peer_endpoint objects
// must be valid until the accept's handler is invoked.
- template <typename Handler>
- void async_accept(implementation_type& impl,
- boost::asio::io_context* peer_io_context,
- endpoint_type* peer_endpoint, Handler& handler)
+ template <typename PeerIoExecutor, typename Handler, typename IoExecutor>
+ void async_move_accept(implementation_type& impl,
+ const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_move_accept_op<protocol_type, Handler> op;
+ typedef win_iocp_socket_move_accept_op<
+ protocol_type, PeerIoExecutor, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
bool enable_connection_aborted =
(impl.state_ & socket_ops::enable_connection_aborted) != 0;
p.p = new (p.v) op(*this, impl.socket_, impl.protocol_,
- peer_io_context ? *peer_io_context : io_context_,
- peer_endpoint, enable_connection_aborted, handler);
+ peer_io_ex, peer_endpoint, enable_connection_aborted,
+ handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_accept"));
start_accept_op(impl, false, p.p->new_socket(),
@@ -571,17 +552,18 @@ public:
}
// Start an asynchronous connect.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, Handler& handler)
+ const endpoint_type& peer_endpoint, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_connect_op<Handler> op;
+ typedef win_iocp_socket_connect_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.socket_, handler);
+ p.p = new (p.v) op(impl.socket_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_connect"));
start_connect_op(impl, impl.protocol_.family(), impl.protocol_.type(),
diff --git a/boost/asio/detail/win_iocp_socket_service_base.hpp b/boost/asio/detail/win_iocp_socket_service_base.hpp
index dd2bf9f6a9..7a7c900be4 100644
--- a/boost/asio/detail/win_iocp_socket_service_base.hpp
+++ b/boost/asio/detail/win_iocp_socket_service_base.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_socket_service_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -20,7 +20,7 @@
#if defined(BOOST_ASIO_HAS_IOCP)
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
@@ -86,8 +86,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL win_iocp_socket_service_base(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL win_iocp_socket_service_base(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void base_shutdown();
@@ -211,20 +210,20 @@ public:
// Asynchronously wait for the socket to become ready to read, ready to
// write, or to have pending error conditions.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_wait(base_implementation_type& impl,
- socket_base::wait_type w, Handler& handler)
+ socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_wait_op<Handler> op;
+ typedef win_iocp_wait_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_wait"));
switch (w)
@@ -272,18 +271,19 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_send_op<ConstBufferSequence, Handler> op;
+ typedef win_iocp_socket_send_op<
+ ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, buffers, handler);
+ p.p = new (p.v) op(impl.cancel_token_, buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_send"));
buffer_sequence_adapter<boost::asio::const_buffer,
@@ -296,17 +296,17 @@ public:
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send(base_implementation_type& impl, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_null_buffers_op<Handler> op;
+ typedef win_iocp_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_send(null_buffers)"));
start_reactor_op(impl, select_reactor::write_op, p.p);
@@ -338,18 +338,21 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_recv_op<MutableBufferSequence, Handler> op;
+ typedef win_iocp_socket_recv_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.state_, impl.cancel_token_, buffers, handler);
+ p.p = new (p.v) op(impl.state_, impl.cancel_token_,
+ buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive"));
buffer_sequence_adapter<boost::asio::mutable_buffer,
@@ -362,17 +365,18 @@ public:
}
// 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)
+ template <typename Handler, typename IoExecutor>
+ void async_receive(base_implementation_type& impl,
+ const null_buffers&, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_null_buffers_op<Handler> op;
+ typedef win_iocp_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive(null_buffers)"));
start_null_buffers_receive_op(impl, flags, p.p);
@@ -411,18 +415,22 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive_with_flags(base_implementation_type& impl,
const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_socket_recvmsg_op<MutableBufferSequence, Handler> op;
+ typedef win_iocp_socket_recvmsg_op<
+ MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, buffers, out_flags, handler);
+ p.p = new (p.v) op(impl.cancel_token_,
+ buffers, out_flags, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive_with_flags"));
buffer_sequence_adapter<boost::asio::mutable_buffer,
@@ -433,18 +441,19 @@ public:
}
// Wait until data can be received without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_receive_with_flags(base_implementation_type& impl,
const null_buffers&, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, Handler& handler)
+ socket_base::message_flags& out_flags, Handler& handler,
+ const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef win_iocp_null_buffers_op<Handler> op;
+ typedef win_iocp_null_buffers_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(impl.cancel_token_, handler);
+ p.p = new (p.v) op(impl.cancel_token_, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_, *p.p, "socket",
+ BOOST_ASIO_HANDLER_CREATION((context_, *p.p, "socket",
&impl, impl.socket_, "async_receive_with_flags(null_buffers)"));
// Reset out_flags since it can be given no sensible value at this time.
@@ -519,8 +528,8 @@ protected:
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_context and a pointer to it is cached in
- // this service.
+ // new one is obtained from the execution context and a pointer to it is
+ // cached in this service.
BOOST_ASIO_DECL select_reactor& get_reactor();
// The type of a ConnectEx function pointer, as old SDKs may not provide it.
@@ -554,8 +563,8 @@ protected:
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
BOOST_ASIO_DECL void* interlocked_exchange_pointer(void** dest, void* val);
- // The io_context used to obtain the reactor, if required.
- boost::asio::io_context& io_context_;
+ // The execution context used to obtain the reactor, if required.
+ execution_context& context_;
// The IOCP service used for running asynchronous operations and dispatching
// handlers.
diff --git a/boost/asio/detail/win_iocp_thread_info.hpp b/boost/asio/detail/win_iocp_thread_info.hpp
index 53f853e104..c6819825c0 100644
--- a/boost/asio/detail/win_iocp_thread_info.hpp
+++ b/boost/asio/detail/win_iocp_thread_info.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_thread_info.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_iocp_wait_op.hpp b/boost/asio/detail/win_iocp_wait_op.hpp
index b067da3e3d..1f0929f99b 100644
--- a/boost/asio/detail/win_iocp_wait_op.hpp
+++ b/boost/asio/detail/win_iocp_wait_op.hpp
@@ -2,7 +2,7 @@
// detail/win_iocp_wait_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,20 +35,21 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class win_iocp_wait_op : public reactor_op
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(win_iocp_wait_op);
win_iocp_wait_op(socket_ops::weak_cancel_token_type cancel_token,
- Handler& handler)
+ Handler& handler, const IoExecutor& io_ex)
: reactor_op(&win_iocp_wait_op::do_perform,
&win_iocp_wait_op::do_complete),
cancel_token_(cancel_token),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static status do_perform(reactor_op*)
@@ -65,7 +66,7 @@ public:
// Take ownership of the operation object.
win_iocp_wait_op* o(static_cast<win_iocp_wait_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -110,6 +111,7 @@ public:
private:
socket_ops::weak_cancel_token_type cancel_token_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/win_mutex.hpp b/boost/asio/detail/win_mutex.hpp
index 45d87c63bb..7509131c4b 100644
--- a/boost/asio/detail/win_mutex.hpp
+++ b/boost/asio/detail/win_mutex.hpp
@@ -2,7 +2,7 @@
// detail/win_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_object_handle_service.hpp b/boost/asio/detail/win_object_handle_service.hpp
index 03fb634888..42032224a8 100644
--- a/boost/asio/detail/win_object_handle_service.hpp
+++ b/boost/asio/detail/win_object_handle_service.hpp
@@ -2,7 +2,7 @@
// detail/win_object_handle_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -24,7 +24,13 @@
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/wait_handler.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
#include <boost/asio/detail/push_options.hpp>
@@ -33,7 +39,7 @@ namespace asio {
namespace detail {
class win_object_handle_service :
- public service_base<win_object_handle_service>
+ public execution_context_service_base<win_object_handle_service>
{
public:
// The native type of an object handle.
@@ -80,8 +86,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL win_object_handle_service(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL win_object_handle_service(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void shutdown();
@@ -130,16 +135,17 @@ public:
boost::system::error_code& ec);
/// Start an asynchronous wait.
- template <typename Handler>
- void async_wait(implementation_type& impl, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_wait(implementation_type& impl,
+ Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
- typedef wait_handler<Handler> op;
+ typedef wait_handler<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(), *p.p, "object_handle",
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(), *p.p, "object_handle",
&impl, reinterpret_cast<uintmax_t>(impl.wait_handle_), "async_wait"));
start_wait_op(impl, p.p);
@@ -158,8 +164,13 @@ private:
static BOOST_ASIO_DECL VOID CALLBACK wait_callback(
PVOID param, BOOLEAN timeout);
- // The io_context implementation used to post completions.
- io_context_impl& io_context_;
+ // The scheduler used to post completions.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
// Mutex to protect access to internal state.
mutex mutex_;
diff --git a/boost/asio/detail/win_static_mutex.hpp b/boost/asio/detail/win_static_mutex.hpp
index 78d3a2eb7f..c310d314db 100644
--- a/boost/asio/detail/win_static_mutex.hpp
+++ b/boost/asio/detail/win_static_mutex.hpp
@@ -2,7 +2,7 @@
// detail/win_static_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_thread.hpp b/boost/asio/detail/win_thread.hpp
index 377c3e3f93..ef867448a9 100644
--- a/boost/asio/detail/win_thread.hpp
+++ b/boost/asio/detail/win_thread.hpp
@@ -2,7 +2,7 @@
// detail/win_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/win_tss_ptr.hpp b/boost/asio/detail/win_tss_ptr.hpp
index e1761c2e27..102b41a583 100644
--- a/boost/asio/detail/win_tss_ptr.hpp
+++ b/boost/asio/detail/win_tss_ptr.hpp
@@ -2,7 +2,7 @@
// detail/win_tss_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/winapp_thread.hpp b/boost/asio/detail/winapp_thread.hpp
index 775f663d84..b92c7f5a67 100644
--- a/boost/asio/detail/winapp_thread.hpp
+++ b/boost/asio/detail/winapp_thread.hpp
@@ -2,7 +2,7 @@
// detail/winapp_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/wince_thread.hpp b/boost/asio/detail/wince_thread.hpp
index 77ec7c8265..492a37c03f 100644
--- a/boost/asio/detail/wince_thread.hpp
+++ b/boost/asio/detail/wince_thread.hpp
@@ -2,7 +2,7 @@
// detail/wince_thread.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/winrt_async_manager.hpp b/boost/asio/detail/winrt_async_manager.hpp
index 57d6a1c218..e9dc6cb257 100644
--- a/boost/asio/detail/winrt_async_manager.hpp
+++ b/boost/asio/detail/winrt_async_manager.hpp
@@ -2,7 +2,7 @@
// detail/winrt_async_manager.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,7 +23,13 @@
#include <boost/asio/detail/atomic_count.hpp>
#include <boost/asio/detail/winrt_async_op.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
#include <boost/asio/detail/push_options.hpp>
@@ -32,13 +38,13 @@ namespace asio {
namespace detail {
class winrt_async_manager
- : public boost::asio::detail::service_base<winrt_async_manager>
+ : public execution_context_service_base<winrt_async_manager>
{
public:
// Constructor.
- winrt_async_manager(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<winrt_async_manager>(io_context),
- io_context_(use_service<io_context_impl>(io_context)),
+ winrt_async_manager(execution_context& context)
+ : execution_context_service_base<winrt_async_manager>(context),
+ scheduler_(use_service<scheduler_impl>(context)),
outstanding_ops_(1)
{
}
@@ -186,12 +192,12 @@ public:
boost::system::system_category());
break;
}
- io_context_.post_deferred_completion(handler);
+ scheduler_.post_deferred_completion(handler);
if (--outstanding_ops_ == 0)
promise_.set_value();
});
- io_context_.work_started();
+ scheduler_.work_started();
++outstanding_ops_;
action->Completed = on_completed;
}
@@ -223,12 +229,12 @@ public:
boost::system::system_category());
break;
}
- io_context_.post_deferred_completion(handler);
+ scheduler_.post_deferred_completion(handler);
if (--outstanding_ops_ == 0)
promise_.set_value();
});
- io_context_.work_started();
+ scheduler_.work_started();
++outstanding_ops_;
operation->Completed = on_completed;
}
@@ -264,19 +270,24 @@ public:
boost::system::system_category());
break;
}
- io_context_.post_deferred_completion(handler);
+ scheduler_.post_deferred_completion(handler);
if (--outstanding_ops_ == 0)
promise_.set_value();
});
- io_context_.work_started();
+ scheduler_.work_started();
++outstanding_ops_;
operation->Completed = on_completed;
}
private:
- // The io_context implementation used to post completed handlers.
- io_context_impl& io_context_;
+ // The scheduler implementation used to post completed handlers.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
// Count of outstanding operations.
atomic_count outstanding_ops_;
diff --git a/boost/asio/detail/winrt_async_op.hpp b/boost/asio/detail/winrt_async_op.hpp
index c3203ff88a..251dd878e4 100644
--- a/boost/asio/detail/winrt_async_op.hpp
+++ b/boost/asio/detail/winrt_async_op.hpp
@@ -2,7 +2,7 @@
// detail/winrt_async_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/winrt_resolve_op.hpp b/boost/asio/detail/winrt_resolve_op.hpp
index 80f102f4c8..f7faa2993a 100644
--- a/boost/asio/detail/winrt_resolve_op.hpp
+++ b/boost/asio/detail/winrt_resolve_op.hpp
@@ -2,7 +2,7 @@
// detail/winrt_resolve_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,7 +34,7 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Protocol, typename Handler>
+template <typename Protocol, typename Handler, typename IoExecutor>
class winrt_resolve_op :
public winrt_async_op<
Windows::Foundation::Collections::IVectorView<
@@ -47,15 +47,17 @@ public:
typedef boost::asio::ip::basic_resolver_query<Protocol> query_type;
typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
- winrt_resolve_op(const query_type& query, Handler& handler)
+ winrt_resolve_op(const query_type& query,
+ Handler& handler, const IoExecutor& io_ex)
: winrt_async_op<
Windows::Foundation::Collections::IVectorView<
Windows::Networking::EndpointPair^>^>(
&winrt_resolve_op::do_complete),
query_(query),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -64,7 +66,7 @@ public:
// Take ownership of the operation object.
winrt_resolve_op* o(static_cast<winrt_resolve_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -107,6 +109,7 @@ public:
private:
query_type query_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/winrt_resolver_service.hpp b/boost/asio/detail/winrt_resolver_service.hpp
index 463dbde11f..054b6abfbc 100644
--- a/boost/asio/detail/winrt_resolver_service.hpp
+++ b/boost/asio/detail/winrt_resolver_service.hpp
@@ -2,7 +2,7 @@
// detail/winrt_resolver_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,6 +21,7 @@
#include <boost/asio/ip/basic_resolver_query.hpp>
#include <boost/asio/ip/basic_resolver_results.hpp>
+#include <boost/asio/post.hpp>
#include <boost/asio/detail/bind_handler.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/socket_ops.hpp>
@@ -28,6 +29,12 @@
#include <boost/asio/detail/winrt_resolve_op.hpp>
#include <boost/asio/detail/winrt_utils.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -36,7 +43,7 @@ namespace detail {
template <typename Protocol>
class winrt_resolver_service :
- public service_base<winrt_resolver_service<Protocol> >
+ public execution_context_service_base<winrt_resolver_service<Protocol> >
{
public:
// The implementation type of the resolver. A cancellation token is used to
@@ -54,10 +61,11 @@ public:
typedef boost::asio::ip::basic_resolver_results<Protocol> results_type;
// Constructor.
- winrt_resolver_service(boost::asio::io_context& io_context)
- : service_base<winrt_resolver_service<Protocol> >(io_context),
- io_context_(use_service<io_context_impl>(io_context)),
- async_manager_(use_service<winrt_async_manager>(io_context))
+ winrt_resolver_service(execution_context& context)
+ : execution_context_service_base<
+ winrt_resolver_service<Protocol> >(context),
+ scheduler_(use_service<scheduler_impl>(context)),
+ async_manager_(use_service<winrt_async_manager>(context))
{
}
@@ -72,7 +80,7 @@ public:
}
// Perform any fork-related housekeeping.
- void notify_fork(boost::asio::io_context::fork_event)
+ void notify_fork(execution_context::fork_event)
{
}
@@ -131,20 +139,20 @@ public:
}
// Asynchronously resolve a query to a list of entries.
- template <typename Handler>
- void async_resolve(implementation_type& impl,
- const query_type& query, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_resolve(implementation_type& impl, const query_type& query,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef winrt_resolve_op<Protocol, Handler> op;
+ typedef winrt_resolve_op<Protocol, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(query, handler);
+ p.p = new (p.v) op(query, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "resolver", &impl, 0, "async_resolve"));
(void)impl;
@@ -160,7 +168,7 @@ public:
{
p.p->ec_ = boost::system::error_code(
e->HResult, boost::system::system_category());
- io_context_.post_immediate_completion(p.p, is_continuation);
+ scheduler_.post_immediate_completion(p.p, is_continuation);
p.v = p.p = 0;
}
}
@@ -174,18 +182,24 @@ public:
}
// Asynchronously resolve an endpoint to a list of entries.
- template <typename Handler>
- void async_resolve(implementation_type&,
- const endpoint_type&, Handler& handler)
+ template <typename Handler, typename IoExecutor>
+ void async_resolve(implementation_type&, const endpoint_type&,
+ Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const results_type results;
- io_context_.get_io_context().post(
- detail::bind_handler(handler, ec, results));
+ boost::asio::post(io_ex, detail::bind_handler(handler, ec, results));
}
private:
- io_context_impl& io_context_;
+ // The scheduler implementation used for delivering completions.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
+
winrt_async_manager& async_manager_;
};
diff --git a/boost/asio/detail/winrt_socket_connect_op.hpp b/boost/asio/detail/winrt_socket_connect_op.hpp
index 9926da97d9..291c886086 100644
--- a/boost/asio/detail/winrt_socket_connect_op.hpp
+++ b/boost/asio/detail/winrt_socket_connect_op.hpp
@@ -2,7 +2,7 @@
// detail/winrt_socket_connect_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,18 +34,19 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename Handler>
+template <typename Handler, typename IoExecutor>
class winrt_socket_connect_op :
public winrt_async_op<void>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(winrt_socket_connect_op);
- winrt_socket_connect_op(Handler& handler)
+ winrt_socket_connect_op(Handler& handler, const IoExecutor& io_ex)
: winrt_async_op<void>(&winrt_socket_connect_op::do_complete),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -54,7 +55,7 @@ public:
// Take ownership of the operation object.
winrt_socket_connect_op* o(static_cast<winrt_socket_connect_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -81,6 +82,7 @@ public:
private:
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/winrt_socket_recv_op.hpp b/boost/asio/detail/winrt_socket_recv_op.hpp
index 0701208da4..34a5a755bf 100644
--- a/boost/asio/detail/winrt_socket_recv_op.hpp
+++ b/boost/asio/detail/winrt_socket_recv_op.hpp
@@ -2,7 +2,7 @@
// detail/winrt_socket_recv_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,20 +34,22 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename MutableBufferSequence, typename Handler>
+template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class winrt_socket_recv_op :
public winrt_async_op<Windows::Storage::Streams::IBuffer^>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(winrt_socket_recv_op);
- winrt_socket_recv_op(const MutableBufferSequence& buffers, Handler& handler)
+ winrt_socket_recv_op(const MutableBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: winrt_async_op<Windows::Storage::Streams::IBuffer^>(
&winrt_socket_recv_op::do_complete),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -56,7 +58,7 @@ public:
// Take ownership of the operation object.
winrt_socket_recv_op* o(static_cast<winrt_socket_recv_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -101,6 +103,7 @@ public:
private:
MutableBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/winrt_socket_send_op.hpp b/boost/asio/detail/winrt_socket_send_op.hpp
index 4e62056c4f..cbf42110f8 100644
--- a/boost/asio/detail/winrt_socket_send_op.hpp
+++ b/boost/asio/detail/winrt_socket_send_op.hpp
@@ -2,7 +2,7 @@
// detail/winrt_socket_send_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,19 +34,21 @@ namespace boost {
namespace asio {
namespace detail {
-template <typename ConstBufferSequence, typename Handler>
+template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
class winrt_socket_send_op :
public winrt_async_op<unsigned int>
{
public:
BOOST_ASIO_DEFINE_HANDLER_PTR(winrt_socket_send_op);
- winrt_socket_send_op(const ConstBufferSequence& buffers, Handler& handler)
+ winrt_socket_send_op(const ConstBufferSequence& buffers,
+ Handler& handler, const IoExecutor& io_ex)
: winrt_async_op<unsigned int>(&winrt_socket_send_op::do_complete),
buffers_(buffers),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ io_executor_(io_ex)
{
- handler_work<Handler>::start(handler_);
+ handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -55,7 +57,7 @@ public:
// Take ownership of the operation object.
winrt_socket_send_op* o(static_cast<winrt_socket_send_op*>(base));
ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
- handler_work<Handler> w(o->handler_);
+ handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
BOOST_ASIO_HANDLER_COMPLETION((*o));
@@ -92,6 +94,7 @@ public:
private:
ConstBufferSequence buffers_;
Handler handler_;
+ IoExecutor io_executor_;
};
} // namespace detail
diff --git a/boost/asio/detail/winrt_ssocket_service.hpp b/boost/asio/detail/winrt_ssocket_service.hpp
index c874f2520d..af2c718699 100644
--- a/boost/asio/detail/winrt_ssocket_service.hpp
+++ b/boost/asio/detail/winrt_ssocket_service.hpp
@@ -2,7 +2,7 @@
// detail/winrt_ssocket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -20,7 +20,7 @@
#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/winrt_socket_connect_op.hpp>
#include <boost/asio/detail/winrt_ssocket_service_base.hpp>
@@ -34,7 +34,7 @@ namespace detail {
template <typename Protocol>
class winrt_ssocket_service :
- public service_base<winrt_ssocket_service<Protocol> >,
+ public execution_context_service_base<winrt_ssocket_service<Protocol> >,
public winrt_ssocket_service_base
{
public:
@@ -62,9 +62,9 @@ public:
};
// Constructor.
- winrt_ssocket_service(boost::asio::io_context& io_context)
- : service_base<winrt_ssocket_service<Protocol> >(io_context),
- winrt_ssocket_service_base(io_context)
+ winrt_ssocket_service(execution_context& context)
+ : execution_context_service_base<winrt_ssocket_service<Protocol> >(context),
+ winrt_ssocket_service_base(context)
{
}
@@ -211,20 +211,21 @@ public:
}
// Start an asynchronous connect.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, Handler& handler)
+ const endpoint_type& peer_endpoint,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef winrt_socket_connect_op<Handler> op;
+ typedef winrt_socket_connect_op<Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(handler);
+ p.p = new (p.v) op(handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "socket", &impl, 0, "async_connect"));
start_connect_op(impl, peer_endpoint.data(), p.p, is_continuation);
diff --git a/boost/asio/detail/winrt_ssocket_service_base.hpp b/boost/asio/detail/winrt_ssocket_service_base.hpp
index dcb5aa1c40..cb7b6c07f7 100644
--- a/boost/asio/detail/winrt_ssocket_service_base.hpp
+++ b/boost/asio/detail/winrt_ssocket_service_base.hpp
@@ -2,7 +2,7 @@
// detail/winrt_ssocket_service_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,7 +21,7 @@
#include <boost/asio/buffer.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
#include <boost/asio/socket_base.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/memory.hpp>
@@ -30,6 +30,12 @@
#include <boost/asio/detail/winrt_socket_recv_op.hpp>
#include <boost/asio/detail/winrt_socket_send_op.hpp>
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -62,8 +68,7 @@ public:
};
// Constructor.
- BOOST_ASIO_DECL winrt_ssocket_service_base(
- boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL winrt_ssocket_service_base(execution_context& context);
// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL void base_shutdown();
@@ -193,21 +198,21 @@ public:
// Start an asynchronous send. The data being sent must be valid for the
// lifetime of the asynchronous operation.
- template <typename ConstBufferSequence, typename Handler>
+ template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
void async_send(base_implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const ConstBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef winrt_socket_send_op<ConstBufferSequence, Handler> op;
+ typedef winrt_socket_send_op<ConstBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "socket", &impl, 0, "async_send"));
start_send_op(impl,
@@ -218,13 +223,13 @@ public:
}
// Start an asynchronous wait until data can be sent without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_send(base_implementation_type&, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.get_io_context().post(
+ boost::asio::post(io_ex,
detail::bind_handler(handler, ec, bytes_transferred));
}
@@ -249,21 +254,22 @@ public:
// 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>
+ template <typename MutableBufferSequence,
+ typename Handler, typename IoExecutor>
void async_receive(base_implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, Handler& handler)
+ const MutableBufferSequence& buffers, socket_base::message_flags flags,
+ Handler& handler, const IoExecutor& io_ex)
{
bool is_continuation =
boost_asio_handler_cont_helpers::is_continuation(handler);
// Allocate and construct an operation to wrap the handler.
- typedef winrt_socket_recv_op<MutableBufferSequence, Handler> op;
+ typedef winrt_socket_recv_op<MutableBufferSequence, Handler, IoExecutor> op;
typename op::ptr p = { boost::asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
- p.p = new (p.v) op(buffers, handler);
+ p.p = new (p.v) op(buffers, handler, io_ex);
- BOOST_ASIO_HANDLER_CREATION((io_context_.context(),
+ BOOST_ASIO_HANDLER_CREATION((scheduler_.context(),
*p.p, "socket", &impl, 0, "async_receive"));
start_receive_op(impl,
@@ -274,13 +280,13 @@ public:
}
// Wait until data can be received without blocking.
- template <typename Handler>
+ template <typename Handler, typename IoExecutor>
void async_receive(base_implementation_type&, const null_buffers&,
- socket_base::message_flags, Handler& handler)
+ socket_base::message_flags, Handler& handler, const IoExecutor& io_ex)
{
boost::system::error_code ec = boost::asio::error::operation_not_supported;
const std::size_t bytes_transferred = 0;
- io_context_.get_io_context().post(
+ boost::asio::post(io_ex,
detail::bind_handler(handler, ec, bytes_transferred));
}
@@ -333,8 +339,13 @@ protected:
winrt_async_op<Windows::Storage::Streams::IBuffer^>* op,
bool is_continuation);
- // The io_context implementation used for delivering completions.
- io_context_impl& io_context_;
+ // The scheduler implementation used for delivering completions.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
// The manager that keeps track of outstanding operations.
winrt_async_manager& async_manager_;
diff --git a/boost/asio/detail/winrt_timer_scheduler.hpp b/boost/asio/detail/winrt_timer_scheduler.hpp
index 8f61ad843e..d48ed2cb6a 100644
--- a/boost/asio/detail/winrt_timer_scheduler.hpp
+++ b/boost/asio/detail/winrt_timer_scheduler.hpp
@@ -2,7 +2,7 @@
// detail/winrt_timer_scheduler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,7 +28,13 @@
#include <boost/asio/detail/timer_queue_base.hpp>
#include <boost/asio/detail/timer_queue_set.hpp>
#include <boost/asio/detail/wait_op.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+
+#if defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/win_iocp_io_context.hpp>
+#else // defined(BOOST_ASIO_HAS_IOCP)
+# include <boost/asio/detail/scheduler.hpp>
+#endif // defined(BOOST_ASIO_HAS_IOCP)
#if defined(BOOST_ASIO_HAS_IOCP)
# include <boost/asio/detail/thread.hpp>
@@ -41,11 +47,11 @@ namespace asio {
namespace detail {
class winrt_timer_scheduler
- : public boost::asio::detail::service_base<winrt_timer_scheduler>
+ : public execution_context_service_base<winrt_timer_scheduler>
{
public:
// Constructor.
- BOOST_ASIO_DECL winrt_timer_scheduler(boost::asio::io_context& io_context);
+ BOOST_ASIO_DECL winrt_timer_scheduler(execution_context& context);
// Destructor.
BOOST_ASIO_DECL ~winrt_timer_scheduler();
@@ -54,8 +60,7 @@ public:
BOOST_ASIO_DECL void shutdown();
// Recreate internal descriptors following a fork.
- BOOST_ASIO_DECL void notify_fork(
- boost::asio::io_context::fork_event fork_ev);
+ BOOST_ASIO_DECL void notify_fork(execution_context::fork_event fork_ev);
// Initialise the task. No effect as this class uses its own thread.
BOOST_ASIO_DECL void init_task();
@@ -101,8 +106,13 @@ private:
// Helper function to remove a timer queue.
BOOST_ASIO_DECL void do_remove_timer_queue(timer_queue_base& queue);
- // The io_context implementation used to post completions.
- io_context_impl& io_context_;
+ // The scheduler implementation used to post completions.
+#if defined(BOOST_ASIO_HAS_IOCP)
+ typedef class win_iocp_io_context scheduler_impl;
+#else
+ typedef class scheduler scheduler_impl;
+#endif
+ scheduler_impl& scheduler_;
// Mutex used to protect internal variables.
boost::asio::detail::mutex mutex_;
diff --git a/boost/asio/detail/winrt_utils.hpp b/boost/asio/detail/winrt_utils.hpp
index 765edeecb8..bc765aeb66 100644
--- a/boost/asio/detail/winrt_utils.hpp
+++ b/boost/asio/detail/winrt_utils.hpp
@@ -2,7 +2,7 @@
// detail/winrt_utils.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/winsock_init.hpp b/boost/asio/detail/winsock_init.hpp
index abf59cd1bf..dfda010839 100644
--- a/boost/asio/detail/winsock_init.hpp
+++ b/boost/asio/detail/winsock_init.hpp
@@ -2,7 +2,7 @@
// detail/winsock_init.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/detail/work_dispatcher.hpp b/boost/asio/detail/work_dispatcher.hpp
index 3167f244fd..9a92c45e02 100644
--- a/boost/asio/detail/work_dispatcher.hpp
+++ b/boost/asio/detail/work_dispatcher.hpp
@@ -2,7 +2,7 @@
// detail/work_dispatcher.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -30,9 +30,10 @@ template <typename Handler>
class work_dispatcher
{
public:
- work_dispatcher(Handler& handler)
+ template <typename CompletionHandler>
+ explicit work_dispatcher(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler)
: work_((get_associated_executor)(handler)),
- handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ handler_(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler))
{
}
diff --git a/boost/asio/detail/wrapped_handler.hpp b/boost/asio/detail/wrapped_handler.hpp
index 8e23d1db9e..8496168975 100644
--- a/boost/asio/detail/wrapped_handler.hpp
+++ b/boost/asio/detail/wrapped_handler.hpp
@@ -2,7 +2,7 @@
// detail/wrapped_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/dispatch.hpp b/boost/asio/dispatch.hpp
index 4136eda64f..578608c0c3 100644
--- a/boost/asio/dispatch.hpp
+++ b/boost/asio/dispatch.hpp
@@ -2,7 +2,7 @@
// dispatch.hpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -29,8 +29,8 @@ namespace asio {
/// Submits a completion token or function object for execution.
/**
* This function submits an object for execution using the object's associated
- * executor. The function object is queued for execution, and is never called
- * from the current thread prior to returning from <tt>dispatch()</tt>.
+ * executor. The function object may be called from the current thread prior to
+ * returning from <tt>dispatch()</tt>. Otherwise, it is queued for execution.
*
* This function has the following effects:
*
@@ -57,8 +57,8 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
/// Submits a completion token or function object for execution.
/**
* This function submits an object for execution using the specified executor.
- * The function object is queued for execution, and is never called from the
- * current thread prior to returning from <tt>dispatch()</tt>.
+ * The function object may be called from the current thread prior to returning
+ * from <tt>dispatch()</tt>. Otherwise, it is queued for execution.
*
* This function has the following effects:
*
diff --git a/boost/asio/error.hpp b/boost/asio/error.hpp
index 53810b287a..448d9aeb84 100644
--- a/boost/asio/error.hpp
+++ b/boost/asio/error.hpp
@@ -2,7 +2,7 @@
// error.hpp
// ~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/execution_context.hpp b/boost/asio/execution_context.hpp
index 4ebb607a1a..f89fb4cdeb 100644
--- a/boost/asio/execution_context.hpp
+++ b/boost/asio/execution_context.hpp
@@ -2,7 +2,7 @@
// execution_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -110,13 +110,14 @@ public:
class id;
class service;
-protected:
+public:
/// Constructor.
BOOST_ASIO_DECL execution_context();
/// Destructor.
BOOST_ASIO_DECL ~execution_context();
+protected:
/// Shuts down all services in the context.
/**
* This function is implemented as follows:
diff --git a/boost/asio/executor.hpp b/boost/asio/executor.hpp
index 43a5a2c105..7c6a353f0e 100644
--- a/boost/asio/executor.hpp
+++ b/boost/asio/executor.hpp
@@ -2,7 +2,7 @@
// executor.hpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/executor_work_guard.hpp b/boost/asio/executor_work_guard.hpp
index a9303462eb..546f7ef9cf 100644
--- a/boost/asio/executor_work_guard.hpp
+++ b/boost/asio/executor_work_guard.hpp
@@ -2,7 +2,7 @@
// executor_work_guard.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -56,7 +56,7 @@ public:
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move constructor.
- executor_work_guard(executor_work_guard&& other)
+ executor_work_guard(executor_work_guard&& other) BOOST_ASIO_NOEXCEPT
: executor_(BOOST_ASIO_MOVE_CAST(Executor)(other.executor_)),
owns_(other.owns_)
{
diff --git a/boost/asio/experimental.hpp b/boost/asio/experimental.hpp
deleted file mode 100644
index 0ca0a9658f..0000000000
--- a/boost/asio/experimental.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// experimental.hpp
-// ~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2017 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_EXPERIMENTAL_HPP
-#define BOOST_ASIO_EXPERIMENTAL_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/experimental/co_spawn.hpp>
-#include <boost/asio/experimental/detached.hpp>
-#include <boost/asio/experimental/redirect_error.hpp>
-
-#endif // BOOST_ASIO_EXPERIMENTAL_HPP
diff --git a/boost/asio/experimental/co_spawn.hpp b/boost/asio/experimental/co_spawn.hpp
deleted file mode 100644
index c900da11f0..0000000000
--- a/boost/asio/experimental/co_spawn.hpp
+++ /dev/null
@@ -1,228 +0,0 @@
-//
-// experimental/co_spawn.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_EXPERIMENTAL_CO_SPAWN_HPP
-#define BOOST_ASIO_EXPERIMENTAL_CO_SPAWN_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
-
-#include <experimental/coroutine>
-#include <boost/asio/executor.hpp>
-#include <boost/asio/strand.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace experimental {
-namespace detail {
-
-using std::experimental::coroutine_handle;
-
-template <typename> class awaiter;
-template <typename> class awaitee_base;
-template <typename, typename> class awaitee;
-template <typename, typename> class await_handler_base;
-template <typename Executor, typename F, typename CompletionToken>
-auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token);
-
-} // namespace detail
-
-namespace this_coro {
-
-/// Awaitable type that returns a completion token for the current coroutine.
-struct token_t {};
-
-/// Awaitable object that returns a completion token for the current coroutine.
-constexpr inline token_t token() { return {}; }
-
-/// Awaitable type that returns the executor of the current coroutine.
-struct executor_t {};
-
-/// Awaitable object that returns the executor of the current coroutine.
-constexpr inline executor_t executor() { return {}; }
-
-} // namespace this_coro
-
-/// A completion token that represents the currently executing coroutine.
-/**
- * The await_token class is used to represent the currently executing
- * coroutine. An await_token may be passed as a handler to an asynchronous
- * operation. For example:
- *
- * @code awaitable<void> my_coroutine()
- * {
- * await_token token = co_await this_coro::token();
- * ...
- * std::size_t n = co_await my_socket.async_read_some(buffer, token);
- * ...
- * } @endcode
- *
- * The initiating function (async_read_some in the above example) suspends the
- * current coroutine. The coroutine is resumed when the asynchronous operation
- * completes, and the result of the operation is returned.
- */
-template <typename Executor>
-class await_token
-{
-public:
- /// The associated executor type.
- typedef Executor executor_type;
-
- /// Copy constructor.
- await_token(const await_token& other) noexcept
- : awaiter_(other.awaiter_)
- {
- }
-
- /// Move constructor.
- await_token(await_token&& other) noexcept
- : awaiter_(std::exchange(other.awaiter_, nullptr))
- {
- }
-
- /// Get the associated executor.
- executor_type get_executor() const noexcept
- {
- return awaiter_->get_executor();
- }
-
-private:
- // No assignment allowed.
- await_token& operator=(const await_token&) = delete;
-
- template <typename> friend class detail::awaitee_base;
- template <typename, typename> friend class detail::await_handler_base;
-
- // Private constructor used by awaitee_base.
- explicit await_token(detail::awaiter<Executor>* a)
- : awaiter_(a)
- {
- }
-
- detail::awaiter<Executor>* awaiter_;
-};
-
-/// The return type of a coroutine or asynchronous operation.
-template <typename T, typename Executor = strand<executor>>
-class awaitable
-{
-public:
- /// The type of the awaited value.
- typedef T value_type;
-
- /// The executor type that will be used for the coroutine.
- typedef Executor executor_type;
-
- /// Move constructor.
- awaitable(awaitable&& other) noexcept
- : awaitee_(std::exchange(other.awaitee_, nullptr))
- {
- }
-
- /// Destructor
- ~awaitable()
- {
- if (awaitee_)
- {
- detail::coroutine_handle<
- detail::awaitee<T, Executor>>::from_promise(
- *awaitee_).destroy();
- }
- }
-
-#if !defined(GENERATING_DOCUMENTATION)
-
- // Support for co_await keyword.
- bool await_ready() const noexcept
- {
- return awaitee_->ready();
- }
-
- // Support for co_await keyword.
- void await_suspend(detail::coroutine_handle<detail::awaiter<Executor>> h)
- {
- awaitee_->attach_caller(h);
- }
-
- // Support for co_await keyword.
- template <class U>
- void await_suspend(detail::coroutine_handle<detail::awaitee<U, Executor>> h)
- {
- awaitee_->attach_caller(h);
- }
-
- // Support for co_await keyword.
- T await_resume()
- {
- return awaitee_->get();
- }
-
-#endif // !defined(GENERATING_DOCUMENTATION)
-
-private:
- template <typename, typename> friend class detail::awaitee;
- template <typename, typename> friend class detail::await_handler_base;
-
- // Not copy constructible or copy assignable.
- awaitable(const awaitable&) = delete;
- awaitable& operator=(const awaitable&) = delete;
-
- // Construct the awaitable from a coroutine's promise object.
- explicit awaitable(detail::awaitee<T, Executor>* a) : awaitee_(a) {}
-
- detail::awaitee<T, Executor>* awaitee_;
-};
-
-/// Spawn a new thread of execution.
-template <typename Executor, typename F, typename CompletionToken,
- typename = typename enable_if<is_executor<Executor>::value>::type>
-inline auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token)
-{
- return detail::co_spawn(ex, std::forward<F>(f),
- std::forward<CompletionToken>(token));
-}
-
-/// Spawn a new thread of execution.
-template <typename ExecutionContext, typename F, typename CompletionToken,
- typename = typename enable_if<
- is_convertible<ExecutionContext&, execution_context&>::value>::type>
-inline auto co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token)
-{
- return detail::co_spawn(ctx.get_executor(), std::forward<F>(f),
- std::forward<CompletionToken>(token));
-}
-
-/// Spawn a new thread of execution.
-template <typename Executor, typename F, typename CompletionToken>
-inline auto co_spawn(const await_token<Executor>& parent,
- F&& f, CompletionToken&& token)
-{
- return detail::co_spawn(parent.get_executor(), std::forward<F>(f),
- std::forward<CompletionToken>(token));
-}
-
-} // namespace experimental
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#include <boost/asio/experimental/impl/co_spawn.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
-
-#endif // BOOST_ASIO_EXPERIMENTAL_CO_SPAWN_HPP
diff --git a/boost/asio/experimental/impl/co_spawn.hpp b/boost/asio/experimental/impl/co_spawn.hpp
deleted file mode 100644
index 51ffb4eeb1..0000000000
--- a/boost/asio/experimental/impl/co_spawn.hpp
+++ /dev/null
@@ -1,878 +0,0 @@
-//
-// experimental/impl/co_spawn.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_EXPERIMENTAL_IMPL_CO_SPAWN_HPP
-#define BOOST_ASIO_EXPERIMENTAL_IMPL_CO_SPAWN_HPP
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-
-#include <boost/asio/detail/config.hpp>
-#include <exception>
-#include <functional>
-#include <memory>
-#include <new>
-#include <tuple>
-#include <utility>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/thread_context.hpp>
-#include <boost/asio/detail/thread_info_base.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/dispatch.hpp>
-#include <boost/asio/post.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace experimental {
-namespace detail {
-
-// Promise object for coroutine at top of thread-of-execution "stack".
-template <typename Executor>
-class awaiter
-{
-public:
- struct deleter
- {
- void operator()(awaiter* a)
- {
- if (a)
- a->release();
- }
- };
-
- typedef std::unique_ptr<awaiter, deleter> ptr;
-
- typedef Executor executor_type;
-
- ~awaiter()
- {
- if (has_executor_)
- static_cast<Executor*>(static_cast<void*>(executor_))->~Executor();
- }
-
- void set_executor(const Executor& ex)
- {
- new (&executor_) Executor(ex);
- has_executor_ = true;
- }
-
- executor_type get_executor() const noexcept
- {
- return *static_cast<const Executor*>(static_cast<const void*>(executor_));
- }
-
- awaiter* get_return_object()
- {
- return this;
- }
-
- auto initial_suspend()
- {
- return std::experimental::suspend_always();
- }
-
- auto final_suspend()
- {
- return std::experimental::suspend_always();
- }
-
- void return_void()
- {
- }
-
- awaiter* add_ref()
- {
- ++ref_count_;
- return this;
- }
-
- void release()
- {
- if (--ref_count_ == 0)
- coroutine_handle<awaiter>::from_promise(*this).destroy();
- }
-
- void unhandled_exception()
- {
- pending_exception_ = std::current_exception();
- }
-
- void rethrow_unhandled_exception()
- {
- if (pending_exception_)
- {
- std::exception_ptr ex = std::exchange(pending_exception_, nullptr);
- std::rethrow_exception(ex);
- }
- }
-
-private:
- std::size_t ref_count_ = 0;
- std::exception_ptr pending_exception_ = nullptr;
- alignas(Executor) unsigned char executor_[sizeof(Executor)];
- bool has_executor_ = false;
-};
-
-// Base promise for coroutines further down the thread-of-execution "stack".
-template <typename Executor>
-class awaitee_base
-{
-public:
-#if !defined(BOOST_ASIO_DISABLE_AWAITEE_RECYCLING)
- void* operator new(std::size_t size)
- {
- return boost::asio::detail::thread_info_base::allocate(
- boost::asio::detail::thread_info_base::awaitee_tag(),
- boost::asio::detail::thread_context::thread_call_stack::top(),
- size);
- }
-
- void operator delete(void* pointer, std::size_t size)
- {
- boost::asio::detail::thread_info_base::deallocate(
- boost::asio::detail::thread_info_base::awaitee_tag(),
- boost::asio::detail::thread_context::thread_call_stack::top(),
- pointer, size);
- }
-#endif // !defined(BOOST_ASIO_DISABLE_AWAITEE_RECYCLING)
-
- auto initial_suspend()
- {
- return std::experimental::suspend_never();
- }
-
- struct final_suspender
- {
- awaitee_base* this_;
-
- bool await_ready() const noexcept
- {
- return false;
- }
-
- void await_suspend(coroutine_handle<void>)
- {
- this_->wake_caller();
- }
-
- void await_resume() const noexcept
- {
- }
- };
-
- auto final_suspend()
- {
- return final_suspender{this};
- }
-
- void set_except(std::exception_ptr e)
- {
- pending_exception_ = e;
- }
-
- void unhandled_exception()
- {
- set_except(std::current_exception());
- }
-
- void rethrow_exception()
- {
- if (pending_exception_)
- {
- std::exception_ptr ex = std::exchange(pending_exception_, nullptr);
- std::rethrow_exception(ex);
- }
- }
-
- awaiter<Executor>* top()
- {
- return awaiter_;
- }
-
- coroutine_handle<void> caller()
- {
- return caller_;
- }
-
- bool ready() const
- {
- return ready_;
- }
-
- void wake_caller()
- {
- if (caller_)
- caller_.resume();
- else
- ready_ = true;
- }
-
- class awaitable_executor
- {
- public:
- explicit awaitable_executor(awaitee_base* a)
- : this_(a)
- {
- }
-
- bool await_ready() const noexcept
- {
- return this_->awaiter_ != nullptr;
- }
-
- template <typename U, typename Ex>
- void await_suspend(coroutine_handle<detail::awaitee<U, Ex>> h) noexcept
- {
- this_->resume_on_attach_ = h;
- }
-
- Executor await_resume()
- {
- return this_->awaiter_->get_executor();
- }
-
- private:
- awaitee_base* this_;
- };
-
- awaitable_executor await_transform(this_coro::executor_t) noexcept
- {
- return awaitable_executor(this);
- }
-
- class awaitable_token
- {
- public:
- explicit awaitable_token(awaitee_base* a)
- : this_(a)
- {
- }
-
- bool await_ready() const noexcept
- {
- return this_->awaiter_ != nullptr;
- }
-
- template <typename U, typename Ex>
- void await_suspend(coroutine_handle<detail::awaitee<U, Ex>> h) noexcept
- {
- this_->resume_on_attach_ = h;
- }
-
- await_token<Executor> await_resume()
- {
- return await_token<Executor>(this_->awaiter_);
- }
-
- private:
- awaitee_base* this_;
- };
-
- awaitable_token await_transform(this_coro::token_t) noexcept
- {
- return awaitable_token(this);
- }
-
- template <typename T>
- awaitable<T, Executor> await_transform(awaitable<T, Executor>& t) const
- {
- return std::move(t);
- }
-
- template <typename T>
- awaitable<T, Executor> await_transform(awaitable<T, Executor>&& t) const
- {
- return std::move(t);
- }
-
- std::experimental::suspend_always await_transform(
- std::experimental::suspend_always) const
- {
- return std::experimental::suspend_always();
- }
-
- void attach_caller(coroutine_handle<awaiter<Executor>> h)
- {
- this->caller_ = h;
- this->attach_callees(&h.promise());
- }
-
- template <typename U>
- void attach_caller(coroutine_handle<awaitee<U, Executor>> h)
- {
- this->caller_ = h;
- if (h.promise().awaiter_)
- this->attach_callees(h.promise().awaiter_);
- else
- h.promise().unattached_callee_ = this;
- }
-
- void attach_callees(awaiter<Executor>* a)
- {
- for (awaitee_base* curr = this; curr != nullptr;
- curr = std::exchange(curr->unattached_callee_, nullptr))
- {
- curr->awaiter_ = a;
- if (curr->resume_on_attach_)
- return std::exchange(curr->resume_on_attach_, nullptr).resume();
- }
- }
-
-protected:
- awaiter<Executor>* awaiter_ = nullptr;
- coroutine_handle<void> caller_ = nullptr;
- awaitee_base<Executor>* unattached_callee_ = nullptr;
- std::exception_ptr pending_exception_ = nullptr;
- coroutine_handle<void> resume_on_attach_ = nullptr;
- bool ready_ = false;
-};
-
-// Promise object for coroutines further down the thread-of-execution "stack".
-template <typename T, typename Executor>
-class awaitee
- : public awaitee_base<Executor>
-{
-public:
- awaitee()
- {
- }
-
- awaitee(awaitee&& other) noexcept
- : awaitee_base<Executor>(std::move(other))
- {
- }
-
- ~awaitee()
- {
- if (has_result_)
- static_cast<T*>(static_cast<void*>(result_))->~T();
- }
-
- awaitable<T, Executor> get_return_object()
- {
- return awaitable<T, Executor>(this);
- };
-
- template <typename U>
- void return_value(U&& u)
- {
- new (&result_) T(std::forward<U>(u));
- has_result_ = true;
- }
-
- T get()
- {
- this->caller_ = nullptr;
- this->rethrow_exception();
- return std::move(*static_cast<T*>(static_cast<void*>(result_)));
- }
-
-private:
- alignas(T) unsigned char result_[sizeof(T)];
- bool has_result_ = false;
-};
-
-// Promise object for coroutines further down the thread-of-execution "stack".
-template <typename Executor>
-class awaitee<void, Executor>
- : public awaitee_base<Executor>
-{
-public:
- awaitable<void, Executor> get_return_object()
- {
- return awaitable<void, Executor>(this);
- };
-
- void return_void()
- {
- }
-
- void get()
- {
- this->caller_ = nullptr;
- this->rethrow_exception();
- }
-};
-
-template <typename Executor>
-class awaiter_task
-{
-public:
- typedef Executor executor_type;
-
- awaiter_task(awaiter<Executor>* a)
- : awaiter_(a->add_ref())
- {
- }
-
- awaiter_task(awaiter_task&& other) noexcept
- : awaiter_(std::exchange(other.awaiter_, nullptr))
- {
- }
-
- ~awaiter_task()
- {
- if (awaiter_)
- {
- // Coroutine "stack unwinding" must be performed through the executor.
- executor_type ex(awaiter_->get_executor());
- (post)(ex,
- [a = std::move(awaiter_)]() mutable
- {
- typename awaiter<Executor>::ptr(std::move(a));
- });
- }
- }
-
- executor_type get_executor() const noexcept
- {
- return awaiter_->get_executor();
- }
-
-protected:
- typename awaiter<Executor>::ptr awaiter_;
-};
-
-template <typename Executor>
-class co_spawn_handler : public awaiter_task<Executor>
-{
-public:
- using awaiter_task<Executor>::awaiter_task;
-
- void operator()()
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- coroutine_handle<awaiter<Executor>>::from_promise(*ptr.get()).resume();
- }
-};
-
-template <typename Executor, typename T>
-class await_handler_base : public awaiter_task<Executor>
-{
-public:
- typedef awaitable<T, Executor> awaitable_type;
-
- await_handler_base(await_token<Executor> token)
- : awaiter_task<Executor>(token.awaiter_),
- awaitee_(nullptr)
- {
- }
-
- await_handler_base(await_handler_base&& other) noexcept
- : awaiter_task<Executor>(std::move(other)),
- awaitee_(std::exchange(other.awaitee_, nullptr))
- {
- }
-
- void attach_awaitee(const awaitable<T, Executor>& a)
- {
- awaitee_ = a.awaitee_;
- }
-
-protected:
- awaitee<T, Executor>* awaitee_;
-};
-
-template <typename, typename...> class await_handler;
-
-template <typename Executor>
-class await_handler<Executor, void>
- : public await_handler_base<Executor, void>
-{
-public:
- using await_handler_base<Executor, void>::await_handler_base;
-
- void operator()()
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- this->awaitee_->return_void();
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor>
-class await_handler<Executor, boost::system::error_code>
- : public await_handler_base<Executor, void>
-{
-public:
- typedef void return_type;
-
- using await_handler_base<Executor, void>::await_handler_base;
-
- void operator()(const boost::system::error_code& ec)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ec)
- {
- this->awaitee_->set_except(
- std::make_exception_ptr(boost::system::system_error(ec)));
- }
- else
- this->awaitee_->return_void();
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor>
-class await_handler<Executor, std::exception_ptr>
- : public await_handler_base<Executor, void>
-{
-public:
- using await_handler_base<Executor, void>::await_handler_base;
-
- void operator()(std::exception_ptr ex)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ex)
- this->awaitee_->set_except(ex);
- else
- this->awaitee_->return_void();
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename T>
-class await_handler<Executor, T>
- : public await_handler_base<Executor, T>
-{
-public:
- using await_handler_base<Executor, T>::await_handler_base;
-
- template <typename Arg>
- void operator()(Arg&& arg)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- this->awaitee_->return_value(std::forward<Arg>(arg));
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename T>
-class await_handler<Executor, boost::system::error_code, T>
- : public await_handler_base<Executor, T>
-{
-public:
- using await_handler_base<Executor, T>::await_handler_base;
-
- template <typename Arg>
- void operator()(const boost::system::error_code& ec, Arg&& arg)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ec)
- {
- this->awaitee_->set_except(
- std::make_exception_ptr(boost::system::system_error(ec)));
- }
- else
- this->awaitee_->return_value(std::forward<Arg>(arg));
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename T>
-class await_handler<Executor, std::exception_ptr, T>
- : public await_handler_base<Executor, T>
-{
-public:
- using await_handler_base<Executor, T>::await_handler_base;
-
- template <typename Arg>
- void operator()(std::exception_ptr ex, Arg&& arg)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ex)
- this->awaitee_->set_except(ex);
- else
- this->awaitee_->return_value(std::forward<Arg>(arg));
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename... Ts>
-class await_handler
- : public await_handler_base<Executor, std::tuple<Ts...>>
-{
-public:
- using await_handler_base<Executor, std::tuple<Ts...>>::await_handler_base;
-
- template <typename... Args>
- void operator()(Args&&... args)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- this->awaitee_->return_value(
- std::forward_as_tuple(std::forward<Args>(args)...));
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename... Ts>
-class await_handler<Executor, boost::system::error_code, Ts...>
- : public await_handler_base<Executor, std::tuple<Ts...>>
-{
-public:
- using await_handler_base<Executor, std::tuple<Ts...>>::await_handler_base;
-
- template <typename... Args>
- void operator()(const boost::system::error_code& ec, Args&&... args)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ec)
- {
- this->awaitee_->set_except(
- std::make_exception_ptr(boost::system::system_error(ec)));
- }
- else
- {
- this->awaitee_->return_value(
- std::forward_as_tuple(std::forward<Args>(args)...));
- }
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename Executor, typename... Ts>
-class await_handler<Executor, std::exception_ptr, Ts...>
- : public await_handler_base<Executor, std::tuple<Ts...>>
-{
-public:
- using await_handler_base<Executor, std::tuple<Ts...>>::await_handler_base;
-
- template <typename... Args>
- void operator()(std::exception_ptr ex, Args&&... args)
- {
- typename awaiter<Executor>::ptr ptr(std::move(this->awaiter_));
- if (ex)
- this->awaitee_->set_except(ex);
- else
- {
- this->awaitee_->return_value(
- std::forward_as_tuple(std::forward<Args>(args)...));
- }
- this->awaitee_->wake_caller();
- ptr->rethrow_unhandled_exception();
- }
-};
-
-template <typename T>
-struct awaitable_signature;
-
-template <typename T, typename Executor>
-struct awaitable_signature<awaitable<T, Executor>>
-{
- typedef void type(std::exception_ptr, T);
-};
-
-template <typename Executor>
-struct awaitable_signature<awaitable<void, Executor>>
-{
- typedef void type(std::exception_ptr);
-};
-
-template <typename T, typename Executor, typename F, typename Handler>
-awaiter<Executor>* co_spawn_entry_point(awaitable<T, Executor>*,
- executor_work_guard<Executor> work_guard, F f, Handler handler)
-{
- bool done = false;
-
- try
- {
- T t = co_await f();
-
- done = true;
-
- (dispatch)(work_guard.get_executor(),
- [handler = std::move(handler), t = std::move(t)]() mutable
- {
- handler(std::exception_ptr(), std::move(t));
- });
- }
- catch (...)
- {
- if (done)
- throw;
-
- (dispatch)(work_guard.get_executor(),
- [handler = std::move(handler), e = std::current_exception()]() mutable
- {
- handler(e, T());
- });
- }
-}
-
-template <typename Executor, typename F, typename Handler>
-awaiter<Executor>* co_spawn_entry_point(awaitable<void, Executor>*,
- executor_work_guard<Executor> work_guard, F f, Handler handler)
-{
- std::exception_ptr e = nullptr;
-
- try
- {
- co_await f();
- }
- catch (...)
- {
- e = std::current_exception();
- }
-
- (dispatch)(work_guard.get_executor(),
- [handler = std::move(handler), e]() mutable
- {
- handler(e);
- });
-}
-
-template <typename Executor, typename F, typename CompletionToken>
-auto co_spawn(const Executor& ex, F&& f, CompletionToken&& token)
-{
- typedef typename result_of<F()>::type awaitable_type;
- typedef typename awaitable_type::executor_type executor_type;
- typedef typename awaitable_signature<awaitable_type>::type signature_type;
-
- async_completion<CompletionToken, signature_type> completion(token);
-
- executor_type ex2(ex);
- auto work_guard = make_work_guard(completion.completion_handler, ex2);
-
- auto* a = (co_spawn_entry_point)(
- static_cast<awaitable_type*>(nullptr), std::move(work_guard),
- std::forward<F>(f), std::move(completion.completion_handler));
-
- a->set_executor(ex2);
- (post)(co_spawn_handler<executor_type>(a));
-
- return completion.result.get();
-}
-
-#if defined(_MSC_VER)
-# pragma warning(push)
-# pragma warning(disable:4033)
-#endif // defined(_MSC_VER)
-
-#if defined(_MSC_VER)
-template <typename T> T dummy_return()
-{
- return std::move(*static_cast<T*>(nullptr));
-}
-
-template <>
-inline void dummy_return()
-{
-}
-#endif // defined(_MSC_VER)
-
-template <typename Awaitable>
-inline Awaitable make_dummy_awaitable()
-{
- for (;;) co_await std::experimental::suspend_always();
-#if defined(_MSC_VER)
- co_return dummy_return<typename Awaitable::value_type>();
-#endif // defined(_MSC_VER)
-}
-
-#if defined(_MSC_VER)
-# pragma warning(pop)
-#endif // defined(_MSC_VER)
-
-} // namespace detail
-} // namespace experimental
-
-template <typename Executor, typename R, typename... Args>
-class async_result<experimental::await_token<Executor>, R(Args...)>
-{
-public:
- typedef experimental::detail::await_handler<
- Executor, typename decay<Args>::type...> completion_handler_type;
-
- typedef typename experimental::detail::await_handler<
- Executor, Args...>::awaitable_type return_type;
-
- async_result(completion_handler_type& h)
- : awaitable_(experimental::detail::make_dummy_awaitable<return_type>())
- {
- h.attach_awaitee(awaitable_);
- }
-
- return_type get()
- {
- return std::move(awaitable_);
- }
-
-private:
- return_type awaitable_;
-};
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-
-template <typename Executor, typename R, typename... Args>
-struct handler_type<experimental::await_token<Executor>, R(Args...)>
-{
- typedef experimental::detail::await_handler<
- Executor, typename decay<Args>::type...> type;
-};
-
-template <typename Executor, typename... Args>
-class async_result<experimental::detail::await_handler<Executor, Args...>>
-{
-public:
- typedef typename experimental::detail::await_handler<
- Executor, Args...>::awaitable_type type;
-
- async_result(experimental::detail::await_handler<Executor, Args...>& h)
- : awaitable_(experimental::detail::make_dummy_awaitable<type>())
- {
- h.attach_awaitee(awaitable_);
- }
-
- type get()
- {
- return std::move(awaitable_);
- }
-
-private:
- type awaitable_;
-};
-
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
-} // namespace asio
-} // namespace boost
-
-namespace std { namespace experimental {
-
-template <typename Executor, typename... Args>
-struct coroutine_traits<
- boost::asio::experimental::detail::awaiter<Executor>*, Args...>
-{
- typedef boost::asio::experimental::detail::awaiter<Executor> promise_type;
-};
-
-template <typename T, typename Executor, typename... Args>
-struct coroutine_traits<
- boost::asio::experimental::awaitable<T, Executor>, Args...>
-{
- typedef boost::asio::experimental::detail::awaitee<T, Executor> promise_type;
-};
-
-}} // namespace std::experimental
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_EXPERIMENTAL_IMPL_CO_SPAWN_HPP
diff --git a/boost/asio/experimental/impl/detached.hpp b/boost/asio/experimental/impl/detached.hpp
deleted file mode 100644
index c3baf20299..0000000000
--- a/boost/asio/experimental/impl/detached.hpp
+++ /dev/null
@@ -1,93 +0,0 @@
-//
-// experimental/impl/detached.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_EXPERIMENTAL_IMPL_DETACHED_HPP
-#define BOOST_ASIO_EXPERIMENTAL_IMPL_DETACHED_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/async_result.hpp>
-#include <boost/asio/detail/variadic_templates.hpp>
-#include <boost/asio/handler_type.hpp>
-#include <boost/system/system_error.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace experimental {
-namespace detail {
-
- // Class to adapt a detached_t as a completion handler.
- class detached_handler
- {
- public:
- detached_handler(detached_t)
- {
- }
-
-#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-
- template <typename... Args>
- void operator()(Args...)
- {
- }
-
-#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-
- void operator()()
- {
- }
-
-#define BOOST_ASIO_PRIVATE_DETACHED_DEF(n) \
- template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
- void operator()(BOOST_ASIO_VARIADIC_BYVAL_PARAMS(n)) \
- { \
- } \
- /**/
- BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_DETACHED_DEF)
-#undef BOOST_ASIO_PRIVATE_DETACHED_DEF
-
-#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
- };
-
-} // namespace detail
-} // namespace experimental
-
-#if !defined(GENERATING_DOCUMENTATION)
-
-template <typename Signature>
-struct async_result<experimental::detached_t, Signature>
-{
- typedef boost::asio::experimental::detail::detached_handler
- completion_handler_type;
-
- typedef void return_type;
-
- explicit async_result(completion_handler_type&)
- {
- }
-
- void get()
- {
- }
-};
-
-#endif // !defined(GENERATING_DOCUMENTATION)
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_EXPERIMENTAL_IMPL_DETACHED_HPP
diff --git a/boost/asio/generic/basic_endpoint.hpp b/boost/asio/generic/basic_endpoint.hpp
index fc1c0ba290..048a960aa2 100644
--- a/boost/asio/generic/basic_endpoint.hpp
+++ b/boost/asio/generic/basic_endpoint.hpp
@@ -2,7 +2,7 @@
// generic/basic_endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/datagram_protocol.hpp b/boost/asio/generic/datagram_protocol.hpp
index e9ef54f530..51e95b5f3a 100644
--- a/boost/asio/generic/datagram_protocol.hpp
+++ b/boost/asio/generic/datagram_protocol.hpp
@@ -2,7 +2,7 @@
// generic/datagram_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/detail/endpoint.hpp b/boost/asio/generic/detail/endpoint.hpp
index c338d78da2..84d320e940 100644
--- a/boost/asio/generic/detail/endpoint.hpp
+++ b/boost/asio/generic/detail/endpoint.hpp
@@ -2,7 +2,7 @@
// generic/detail/endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/detail/impl/endpoint.ipp b/boost/asio/generic/detail/impl/endpoint.ipp
index 97db811f2e..aee0377a55 100644
--- a/boost/asio/generic/detail/impl/endpoint.ipp
+++ b/boost/asio/generic/detail/impl/endpoint.ipp
@@ -2,7 +2,7 @@
// generic/detail/impl/endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/raw_protocol.hpp b/boost/asio/generic/raw_protocol.hpp
index dca84e73f7..ae28faf689 100644
--- a/boost/asio/generic/raw_protocol.hpp
+++ b/boost/asio/generic/raw_protocol.hpp
@@ -2,7 +2,7 @@
// generic/raw_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/seq_packet_protocol.hpp b/boost/asio/generic/seq_packet_protocol.hpp
index e54f23e6d9..d9b719f993 100644
--- a/boost/asio/generic/seq_packet_protocol.hpp
+++ b/boost/asio/generic/seq_packet_protocol.hpp
@@ -2,7 +2,7 @@
// generic/seq_packet_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/generic/stream_protocol.hpp b/boost/asio/generic/stream_protocol.hpp
index 599f095dd0..ca5fbb21a1 100644
--- a/boost/asio/generic/stream_protocol.hpp
+++ b/boost/asio/generic/stream_protocol.hpp
@@ -2,7 +2,7 @@
// generic/stream_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/handler_alloc_hook.hpp b/boost/asio/handler_alloc_hook.hpp
index c9636b53ad..595e36bb0d 100644
--- a/boost/asio/handler_alloc_hook.hpp
+++ b/boost/asio/handler_alloc_hook.hpp
@@ -2,7 +2,7 @@
// handler_alloc_hook.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/handler_continuation_hook.hpp b/boost/asio/handler_continuation_hook.hpp
index 4f446b0953..05645cfddf 100644
--- a/boost/asio/handler_continuation_hook.hpp
+++ b/boost/asio/handler_continuation_hook.hpp
@@ -2,7 +2,7 @@
// handler_continuation_hook.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/handler_invoke_hook.hpp b/boost/asio/handler_invoke_hook.hpp
index a853bdfadd..7d3f0fd408 100644
--- a/boost/asio/handler_invoke_hook.hpp
+++ b/boost/asio/handler_invoke_hook.hpp
@@ -2,7 +2,7 @@
// handler_invoke_hook.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/handler_type.hpp b/boost/asio/handler_type.hpp
deleted file mode 100644
index 0c43189338..0000000000
--- a/boost/asio/handler_type.hpp
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// handler_type.hpp
-// ~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_HANDLER_TYPE_HPP
-#define BOOST_ASIO_HANDLER_TYPE_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/type_traits.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// (Deprecated: Use two-parameter version of async_result.) Default handler
-/// type traits provided for all completion token types.
-/**
- * The handler_type traits class is used for determining the concrete handler
- * type to be used for an asynchronous operation. It allows the handler type to
- * be determined at the point where the specific completion handler signature
- * is known.
- *
- * This template may be specialised for user-defined completion token types.
- */
-template <typename CompletionToken, typename Signature, typename = void>
-struct handler_type
-{
- /// The handler type for the specific signature.
- typedef typename conditional<
- is_same<CompletionToken, typename decay<CompletionToken>::type>::value,
- decay<CompletionToken>,
- handler_type<typename decay<CompletionToken>::type, Signature>
- >::type::type type;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // BOOST_ASIO_HANDLER_TYPE_HPP
diff --git a/boost/asio/high_resolution_timer.hpp b/boost/asio/high_resolution_timer.hpp
index f7383b7cc9..6050405401 100644
--- a/boost/asio/high_resolution_timer.hpp
+++ b/boost/asio/high_resolution_timer.hpp
@@ -2,7 +2,7 @@
// high_resolution_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/awaitable.hpp b/boost/asio/impl/awaitable.hpp
new file mode 100644
index 0000000000..b8cf5373a1
--- /dev/null
+++ b/boost/asio/impl/awaitable.hpp
@@ -0,0 +1,424 @@
+//
+// impl/awaitable.hpp
+// ~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_AWAITABLE_HPP
+#define BOOST_ASIO_IMPL_AWAITABLE_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/config.hpp>
+#include <exception>
+#include <new>
+#include <tuple>
+#include <utility>
+#include <boost/asio/detail/thread_context.hpp>
+#include <boost/asio/detail/thread_info_base.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/asio/this_coro.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+// An awaitable_thread represents a thread-of-execution that is composed of one
+// or more "stack frames", with each frame represented by an awaitable_frame.
+// All execution occurs in the context of the awaitable_thread's executor. An
+// awaitable_thread continues to "pump" the stack frames by repeatedly resuming
+// the top stack frame until the stack is empty, or until ownership of the
+// stack is transferred to another awaitable_thread object.
+//
+// +------------------------------------+
+// | top_of_stack_ |
+// | V
+// +--------------+---+ +-----------------+
+// | | | |
+// | awaitable_thread |<---------------------------+ awaitable_frame |
+// | | attached_thread_ | |
+// +--------------+---+ (Set only when +---+-------------+
+// | frames are being |
+// | actively pumped | caller_
+// | by a thread, and |
+// | then only for V
+// | the top frame.) +-----------------+
+// | | |
+// | | awaitable_frame |
+// | | |
+// | +---+-------------+
+// | |
+// | | caller_
+// | :
+// | :
+// | |
+// | V
+// | +-----------------+
+// | bottom_of_stack_ | |
+// +------------------------------->| awaitable_frame |
+// | |
+// +-----------------+
+
+template <typename Executor>
+class awaitable_frame_base
+{
+public:
+#if !defined(BOOST_ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)
+ void* operator new(std::size_t size)
+ {
+ return boost::asio::detail::thread_info_base::allocate(
+ boost::asio::detail::thread_info_base::awaitable_frame_tag(),
+ boost::asio::detail::thread_context::thread_call_stack::top(),
+ size);
+ }
+
+ void operator delete(void* pointer, std::size_t size)
+ {
+ boost::asio::detail::thread_info_base::deallocate(
+ boost::asio::detail::thread_info_base::awaitable_frame_tag(),
+ boost::asio::detail::thread_context::thread_call_stack::top(),
+ pointer, size);
+ }
+#endif // !defined(BOOST_ASIO_DISABLE_AWAITABLE_FRAME_RECYCLING)
+
+ // The frame starts in a suspended state until the awaitable_thread object
+ // pumps the stack.
+ auto initial_suspend() noexcept
+ {
+ return suspend_always();
+ }
+
+ // On final suspension the frame is popped from the top of the stack.
+ auto final_suspend() noexcept
+ {
+ struct result
+ {
+ awaitable_frame_base* this_;
+
+ bool await_ready() const noexcept
+ {
+ return false;
+ }
+
+ void await_suspend(coroutine_handle<void>) noexcept
+ {
+ this_->pop_frame();
+ }
+
+ void await_resume() const noexcept
+ {
+ }
+ };
+
+ return result{this};
+ }
+
+ void set_except(std::exception_ptr e) noexcept
+ {
+ pending_exception_ = e;
+ }
+
+ void set_error(const boost::system::error_code& ec)
+ {
+ this->set_except(std::make_exception_ptr(boost::system::system_error(ec)));
+ }
+
+ void unhandled_exception()
+ {
+ set_except(std::current_exception());
+ }
+
+ void rethrow_exception()
+ {
+ if (pending_exception_)
+ {
+ std::exception_ptr ex = std::exchange(pending_exception_, nullptr);
+ std::rethrow_exception(ex);
+ }
+ }
+
+ template <typename T>
+ auto await_transform(awaitable<T, Executor> a) const
+ {
+ return a;
+ }
+
+ // This await transformation obtains the associated executor of the thread of
+ // execution.
+ auto await_transform(this_coro::executor_t) noexcept
+ {
+ struct result
+ {
+ awaitable_frame_base* this_;
+
+ bool await_ready() const noexcept
+ {
+ return true;
+ }
+
+ void await_suspend(coroutine_handle<void>) noexcept
+ {
+ }
+
+ auto await_resume() const noexcept
+ {
+ return this_->attached_thread_->get_executor();
+ }
+ };
+
+ return result{this};
+ }
+
+ // This await transformation is used to run an async operation's initiation
+ // function object after the coroutine has been suspended. This ensures that
+ // immediate resumption of the coroutine in another thread does not cause a
+ // race condition.
+ template <typename Function>
+ auto await_transform(Function f,
+ typename enable_if<
+ is_convertible<
+ typename result_of<Function(awaitable_frame_base*)>::type,
+ awaitable_thread<Executor>*
+ >::value
+ >::type* = 0)
+ {
+ struct result
+ {
+ Function function_;
+ awaitable_frame_base* this_;
+
+ bool await_ready() const noexcept
+ {
+ return false;
+ }
+
+ void await_suspend(coroutine_handle<void>) noexcept
+ {
+ function_(this_);
+ }
+
+ void await_resume() const noexcept
+ {
+ }
+ };
+
+ return result{std::move(f), this};
+ }
+
+ void attach_thread(awaitable_thread<Executor>* handler) noexcept
+ {
+ attached_thread_ = handler;
+ }
+
+ awaitable_thread<Executor>* detach_thread() noexcept
+ {
+ return std::exchange(attached_thread_, nullptr);
+ }
+
+ void push_frame(awaitable_frame_base<Executor>* caller) noexcept
+ {
+ caller_ = caller;
+ attached_thread_ = caller_->attached_thread_;
+ attached_thread_->top_of_stack_ = this;
+ caller_->attached_thread_ = nullptr;
+ }
+
+ void pop_frame() noexcept
+ {
+ if (caller_)
+ caller_->attached_thread_ = attached_thread_;
+ attached_thread_->top_of_stack_ = caller_;
+ attached_thread_ = nullptr;
+ caller_ = nullptr;
+ }
+
+ void resume()
+ {
+ coro_.resume();
+ }
+
+ void destroy()
+ {
+ coro_.destroy();
+ }
+
+protected:
+ coroutine_handle<void> coro_ = nullptr;
+ awaitable_thread<Executor>* attached_thread_ = nullptr;
+ awaitable_frame_base<Executor>* caller_ = nullptr;
+ std::exception_ptr pending_exception_ = nullptr;
+};
+
+template <typename T, typename Executor>
+class awaitable_frame
+ : public awaitable_frame_base<Executor>
+{
+public:
+ awaitable_frame() noexcept
+ {
+ }
+
+ awaitable_frame(awaitable_frame&& other) noexcept
+ : awaitable_frame_base<Executor>(std::move(other))
+ {
+ }
+
+ ~awaitable_frame()
+ {
+ if (has_result_)
+ static_cast<T*>(static_cast<void*>(result_))->~T();
+ }
+
+ awaitable<T, Executor> get_return_object() noexcept
+ {
+ this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);
+ return awaitable<T, Executor>(this);
+ };
+
+ template <typename U>
+ void return_value(U&& u)
+ {
+ new (&result_) T(std::forward<U>(u));
+ has_result_ = true;
+ }
+
+ template <typename... Us>
+ void return_values(Us&&... us)
+ {
+ this->return_value(std::forward_as_tuple(std::forward<Us>(us)...));
+ }
+
+ T get()
+ {
+ this->caller_ = nullptr;
+ this->rethrow_exception();
+ return std::move(*static_cast<T*>(static_cast<void*>(result_)));
+ }
+
+private:
+ alignas(T) unsigned char result_[sizeof(T)];
+ bool has_result_ = false;
+};
+
+template <typename Executor>
+class awaitable_frame<void, Executor>
+ : public awaitable_frame_base<Executor>
+{
+public:
+ awaitable<void, Executor> get_return_object()
+ {
+ this->coro_ = coroutine_handle<awaitable_frame>::from_promise(*this);
+ return awaitable<void, Executor>(this);
+ };
+
+ void return_void()
+ {
+ }
+
+ void get()
+ {
+ this->caller_ = nullptr;
+ this->rethrow_exception();
+ }
+};
+
+template <typename Executor>
+class awaitable_thread
+{
+public:
+ typedef Executor executor_type;
+
+ // Construct from the entry point of a new thread of execution.
+ awaitable_thread(awaitable<void, Executor> p, const Executor& ex)
+ : bottom_of_stack_(std::move(p)),
+ top_of_stack_(bottom_of_stack_.frame_),
+ executor_(ex)
+ {
+ }
+
+ // Transfer ownership from another awaitable_thread.
+ awaitable_thread(awaitable_thread&& other) noexcept
+ : bottom_of_stack_(std::move(other.bottom_of_stack_)),
+ top_of_stack_(std::exchange(other.top_of_stack_, nullptr)),
+ executor_(std::move(other.executor_))
+ {
+ }
+
+ // Clean up with a last ditch effort to ensure the thread is unwound within
+ // the context of the executor.
+ ~awaitable_thread()
+ {
+ if (bottom_of_stack_.valid())
+ {
+ // Coroutine "stack unwinding" must be performed through the executor.
+ (post)(executor_,
+ [a = std::move(bottom_of_stack_)]() mutable
+ {
+ awaitable<void, Executor>(std::move(a));
+ });
+ }
+ }
+
+ executor_type get_executor() const noexcept
+ {
+ return executor_;
+ }
+
+ // Launch a new thread of execution.
+ void launch()
+ {
+ top_of_stack_->attach_thread(this);
+ pump();
+ }
+
+protected:
+ template <typename> friend class awaitable_frame_base;
+
+ // Repeatedly resume the top stack frame until the stack is empty or until it
+ // has been transferred to another resumable_thread object.
+ void pump()
+ {
+ do top_of_stack_->resume(); while (top_of_stack_);
+ if (bottom_of_stack_.valid())
+ {
+ awaitable<void, Executor> a(std::move(bottom_of_stack_));
+ a.frame_->rethrow_exception();
+ }
+ }
+
+ awaitable<void, Executor> bottom_of_stack_;
+ awaitable_frame_base<Executor>* top_of_stack_;
+ executor_type executor_;
+};
+
+} // namespace detail
+} // namespace asio
+} // namespace boost
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+namespace std { namespace experimental {
+
+template <typename T, typename Executor, typename... Args>
+struct coroutine_traits<boost::asio::awaitable<T, Executor>, Args...>
+{
+ typedef boost::asio::detail::awaitable_frame<T, Executor> promise_type;
+};
+
+}} // namespace std::experimental
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_AWAITABLE_HPP
diff --git a/boost/asio/impl/buffered_read_stream.hpp b/boost/asio/impl/buffered_read_stream.hpp
index 2e1c55842b..6a51d8ee56 100644
--- a/boost/asio/impl/buffered_read_stream.hpp
+++ b/boost/asio/impl/buffered_read_stream.hpp
@@ -2,7 +2,7 @@
// impl/buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,6 +21,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -138,6 +139,28 @@ namespace detail
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_buffered_fill
+ {
+ template <typename ReadHandler, typename Stream>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ buffered_stream_storage* storage, Stream* next_layer) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ std::size_t previous_size = storage->size();
+ storage->resize(storage->capacity());
+ next_layer->async_read_some(
+ buffer(
+ storage->data() + previous_size,
+ storage->size() - previous_size),
+ buffered_fill_handler<typename decay<ReadHandler>::type>(
+ *storage, previous_size, handler2.value));
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -177,24 +200,9 @@ BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
buffered_read_stream<Stream>::async_fill(
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- std::size_t previous_size = storage_.size();
- storage_.resize(storage_.capacity());
- next_layer_.async_read_some(
- buffer(
- storage_.data() + previous_size,
- storage_.size() - previous_size),
- detail::buffered_fill_handler<BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void (boost::system::error_code, std::size_t))>(
- storage_, previous_size, init.completion_handler));
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_buffered_fill(), handler, &storage_, &next_layer_);
}
template <typename Stream>
@@ -327,6 +335,38 @@ namespace detail
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_buffered_read_some
+ {
+ template <typename ReadHandler, typename Stream,
+ typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ buffered_stream_storage* storage, Stream* next_layer,
+ const MutableBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ using boost::asio::buffer_size;
+ non_const_lvalue<ReadHandler> handler2(handler);
+ if (buffer_size(buffers) == 0 || !storage->empty())
+ {
+ next_layer->async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
+ buffered_read_some_handler<MutableBufferSequence,
+ typename decay<ReadHandler>::type>(
+ *storage, buffers, handler2.value));
+ }
+ else
+ {
+ initiate_async_buffered_fill()(
+ buffered_read_some_handler<MutableBufferSequence,
+ typename decay<ReadHandler>::type>(
+ *storage, buffers, handler2.value),
+ storage, next_layer);
+ }
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -375,31 +415,10 @@ buffered_read_stream<Stream>::async_read_some(
const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- using boost::asio::buffer_size;
- if (buffer_size(buffers) == 0 || !storage_.empty())
- {
- next_layer_.async_read_some(BOOST_ASIO_MUTABLE_BUFFER(0, 0),
- detail::buffered_read_some_handler<
- MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void (boost::system::error_code, std::size_t))>(
- storage_, buffers, init.completion_handler));
- }
- else
- {
- this->async_fill(detail::buffered_read_some_handler<
- MutableBufferSequence, BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void (boost::system::error_code, std::size_t))>(
- storage_, buffers, init.completion_handler));
- }
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_buffered_read_some(),
+ handler, &storage_, &next_layer_, buffers);
}
template <typename Stream>
diff --git a/boost/asio/impl/buffered_write_stream.hpp b/boost/asio/impl/buffered_write_stream.hpp
index c5ebf7537b..05d4406347 100644
--- a/boost/asio/impl/buffered_write_stream.hpp
+++ b/boost/asio/impl/buffered_write_stream.hpp
@@ -2,7 +2,7 @@
// impl/buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -21,6 +21,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -124,6 +125,23 @@ namespace detail
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_buffered_flush
+ {
+ template <typename WriteHandler, typename Stream>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ buffered_stream_storage* storage, Stream* next_layer) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ async_write(*next_layer, buffer(storage->data(), storage->size()),
+ buffered_flush_handler<typename decay<WriteHandler>::type>(
+ *storage, handler2.value));
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -163,19 +181,10 @@ BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
buffered_write_stream<Stream>::async_flush(
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- async_write(next_layer_, buffer(storage_.data(), storage_.size()),
- detail::buffered_flush_handler<BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- storage_, init.completion_handler));
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_buffered_flush(),
+ handler, &storage_, &next_layer_);
}
template <typename Stream>
@@ -314,6 +323,38 @@ namespace detail
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_buffered_write_some
+ {
+ template <typename WriteHandler, typename Stream,
+ typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ buffered_stream_storage* storage, Stream* next_layer,
+ const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ using boost::asio::buffer_size;
+ non_const_lvalue<WriteHandler> handler2(handler);
+ if (buffer_size(buffers) == 0 || storage->size() < storage->capacity())
+ {
+ next_layer->async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
+ buffered_write_some_handler<ConstBufferSequence,
+ typename decay<WriteHandler>::type>(
+ *storage, buffers, handler2.value));
+ }
+ else
+ {
+ initiate_async_buffered_flush()(
+ buffered_write_some_handler<ConstBufferSequence,
+ typename decay<WriteHandler>::type>(
+ *storage, buffers, handler2.value),
+ storage, next_layer);
+ }
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -362,32 +403,10 @@ buffered_write_stream<Stream>::async_write_some(
const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- using boost::asio::buffer_size;
- if (buffer_size(buffers) == 0
- || storage_.size() < storage_.capacity())
- {
- next_layer_.async_write_some(BOOST_ASIO_CONST_BUFFER(0, 0),
- detail::buffered_write_some_handler<
- ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- storage_, buffers, init.completion_handler));
- }
- else
- {
- this->async_flush(detail::buffered_write_some_handler<
- ConstBufferSequence, BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- storage_, buffers, init.completion_handler));
- }
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_buffered_write_some(),
+ handler, &storage_, &next_layer_, buffers);
}
template <typename Stream>
diff --git a/boost/asio/impl/co_spawn.hpp b/boost/asio/impl/co_spawn.hpp
new file mode 100644
index 0000000000..19770cd865
--- /dev/null
+++ b/boost/asio/impl/co_spawn.hpp
@@ -0,0 +1,140 @@
+//
+// impl/co_spawn.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_CO_SPAWN_HPP
+#define BOOST_ASIO_IMPL_CO_SPAWN_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/awaitable.hpp>
+#include <boost/asio/dispatch.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/use_awaitable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename T, typename Executor, typename F, typename Handler>
+awaitable<void, Executor> co_spawn_entry_point(
+ awaitable<T, Executor>*, Executor ex, F f, Handler handler)
+{
+ auto spawn_work = make_work_guard(ex);
+ auto handler_work = make_work_guard(handler, ex);
+
+ (void) co_await (post)(spawn_work.get_executor(),
+ use_awaitable_t<Executor>{});
+
+ bool done = false;
+ try
+ {
+ T t = co_await f();
+
+ done = true;
+
+ (dispatch)(handler_work.get_executor(),
+ [handler = std::move(handler), t = std::move(t)]() mutable
+ {
+ handler(std::exception_ptr(), std::move(t));
+ });
+ }
+ catch (...)
+ {
+ if (done)
+ throw;
+
+ (dispatch)(handler_work.get_executor(),
+ [handler = std::move(handler), e = std::current_exception()]() mutable
+ {
+ handler(e, T());
+ });
+ }
+}
+
+template <typename Executor, typename F, typename Handler>
+awaitable<void, Executor> co_spawn_entry_point(
+ awaitable<void, Executor>*, Executor ex, F f, Handler handler)
+{
+ auto spawn_work = make_work_guard(ex);
+ auto handler_work = make_work_guard(handler, ex);
+
+ (void) co_await (post)(spawn_work.get_executor(),
+ use_awaitable_t<Executor>{});
+
+ std::exception_ptr e = nullptr;
+ try
+ {
+ co_await f();
+ }
+ catch (...)
+ {
+ e = std::current_exception();
+ }
+
+ (dispatch)(handler_work.get_executor(),
+ [handler = std::move(handler), e]() mutable
+ {
+ handler(e);
+ });
+}
+
+struct initiate_co_spawn
+{
+ template <typename Handler, typename Executor, typename F>
+ void operator()(Handler&& handler, const Executor& ex, F&& f) const
+ {
+ typedef typename result_of<F()>::type awaitable_type;
+ typedef typename awaitable_type::executor_type executor_type;
+
+ executor_type ex2(ex);
+ auto a = (co_spawn_entry_point)(static_cast<awaitable_type*>(nullptr),
+ ex2, std::forward<F>(f), std::forward<Handler>(handler));
+ awaitable_handler<executor_type, void>(std::move(a), ex2).launch();
+ }
+};
+
+} // namespace detail
+
+template <typename Executor, typename F, typename CompletionToken>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ typename detail::awaitable_signature<typename result_of<F()>::type>::type)
+co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
+ typename enable_if<
+ is_executor<Executor>::value
+ >::type*)
+{
+ return async_initiate<CompletionToken,
+ typename detail::awaitable_signature<typename result_of<F()>::type>>(
+ detail::initiate_co_spawn(), token, ex, std::forward<F>(f));
+}
+
+template <typename ExecutionContext, typename F, typename CompletionToken>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken,
+ typename detail::awaitable_signature<typename result_of<F()>::type>::type)
+co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type*)
+{
+ return (co_spawn)(ctx.get_executor(), std::forward<F>(f),
+ std::forward<CompletionToken>(token));
+}
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_CO_SPAWN_HPP
diff --git a/boost/asio/impl/compose.hpp b/boost/asio/impl/compose.hpp
new file mode 100644
index 0000000000..76fe54d066
--- /dev/null
+++ b/boost/asio/impl/compose.hpp
@@ -0,0 +1,421 @@
+//
+// impl/compose.hpp
+// ~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_COMPOSE_HPP
+#define BOOST_ASIO_IMPL_COMPOSE_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/handler_alloc_helpers.hpp>
+#include <boost/asio/detail/handler_cont_helpers.hpp>
+#include <boost/asio/detail/handler_invoke_helpers.hpp>
+#include <boost/asio/detail/type_traits.hpp>
+#include <boost/asio/detail/variadic_templates.hpp>
+#include <boost/asio/executor_work_guard.hpp>
+#include <boost/asio/is_executor.hpp>
+#include <boost/asio/system_executor.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+namespace detail
+{
+ template <typename>
+ struct composed_work;
+
+ template <>
+ struct composed_work<void()>
+ {
+ composed_work() BOOST_ASIO_NOEXCEPT
+ : head_(system_executor())
+ {
+ }
+
+ void reset()
+ {
+ head_.reset();
+ }
+
+ typedef system_executor head_type;
+ executor_work_guard<system_executor> head_;
+ };
+
+ inline composed_work<void()> make_composed_work()
+ {
+ return composed_work<void()>();
+ }
+
+ template <typename Head>
+ struct composed_work<void(Head)>
+ {
+ explicit composed_work(const Head& ex) BOOST_ASIO_NOEXCEPT
+ : head_(ex)
+ {
+ }
+
+ void reset()
+ {
+ head_.reset();
+ }
+
+ typedef Head head_type;
+ executor_work_guard<Head> head_;
+ };
+
+ template <typename Head>
+ inline composed_work<void(Head)> make_composed_work(const Head& head)
+ {
+ return composed_work<void(Head)>(head);
+ }
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Head, typename... Tail>
+ struct composed_work<void(Head, Tail...)>
+ {
+ explicit composed_work(const Head& head,
+ const Tail&... tail) BOOST_ASIO_NOEXCEPT
+ : head_(head),
+ tail_(tail...)
+ {
+ }
+
+ void reset()
+ {
+ head_.reset();
+ tail_.reset();
+ }
+
+ typedef Head head_type;
+ executor_work_guard<Head> head_;
+ composed_work<void(Tail...)> tail_;
+ };
+
+ template <typename Head, typename... Tail>
+ inline composed_work<void(Head, Tail...)>
+ make_composed_work(const Head& head, const Tail&... tail)
+ {
+ return composed_work<void(Head, Tail...)>(head, tail...);
+ }
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#define BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF(n) \
+ template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ struct composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
+ { \
+ explicit composed_work(const Head& head, \
+ BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) BOOST_ASIO_NOEXCEPT \
+ : head_(head), \
+ tail_(BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)) \
+ { \
+ } \
+ \
+ void reset() \
+ { \
+ head_.reset(); \
+ tail_.reset(); \
+ } \
+ \
+ typedef Head head_type; \
+ executor_work_guard<Head> head_; \
+ composed_work<void(BOOST_ASIO_VARIADIC_TARGS(n))> tail_; \
+ }; \
+ \
+ template <typename Head, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ inline composed_work<void(Head, BOOST_ASIO_VARIADIC_TARGS(n))> \
+ make_composed_work(const Head& head, BOOST_ASIO_VARIADIC_CONSTREF_PARAMS(n)) \
+ { \
+ return composed_work< \
+ void(Head, BOOST_ASIO_VARIADIC_TARGS(n))>( \
+ head, BOOST_ASIO_VARIADIC_BYVAL_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF)
+#undef BOOST_ASIO_PRIVATE_COMPOSED_WORK_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ template <typename Impl, typename Work, typename Handler, typename Signature>
+ class composed_op;
+
+ template <typename Impl, typename Work, typename Handler,
+ typename R, typename... Args>
+ class composed_op<Impl, Work, Handler, R(Args...)>
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ template <typename Impl, typename Work, typename Handler, typename Signature>
+ class composed_op
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ {
+ public:
+ composed_op(BOOST_ASIO_MOVE_ARG(Impl) impl,
+ BOOST_ASIO_MOVE_ARG(Work) work,
+ BOOST_ASIO_MOVE_ARG(Handler) handler)
+ : impl_(BOOST_ASIO_MOVE_CAST(Impl)(impl)),
+ work_(BOOST_ASIO_MOVE_CAST(Work)(work)),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ invocations_(0)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ composed_op(composed_op&& other)
+ : impl_(BOOST_ASIO_MOVE_CAST(Impl)(other.impl_)),
+ work_(BOOST_ASIO_MOVE_CAST(Work)(other.work_)),
+ handler_(BOOST_ASIO_MOVE_CAST(Handler)(other.handler_)),
+ invocations_(other.invocations_)
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ typedef typename associated_executor<Handler,
+ typename Work::head_type>::type executor_type;
+
+ executor_type get_executor() const BOOST_ASIO_NOEXCEPT
+ {
+ return (get_associated_executor)(handler_, work_.head_.get_executor());
+ }
+
+ typedef typename associated_allocator<Handler,
+ std::allocator<void> >::type allocator_type;
+
+ allocator_type get_allocator() const BOOST_ASIO_NOEXCEPT
+ {
+ return (get_associated_allocator)(handler_, std::allocator<void>());
+ }
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template<typename... T>
+ void operator()(BOOST_ASIO_MOVE_ARG(T)... t)
+ {
+ if (invocations_ < ~unsigned(0))
+ ++invocations_;
+ impl_(*this, BOOST_ASIO_MOVE_CAST(T)(t)...);
+ }
+
+ void complete(Args... args)
+ {
+ this->work_.reset();
+ this->handler_(BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ void operator()()
+ {
+ if (invocations_ < ~unsigned(0))
+ ++invocations_;
+ impl_(*this);
+ }
+
+ void complete()
+ {
+ this->work_.reset();
+ this->handler_();
+ }
+
+#define BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF(n) \
+ template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ void operator()(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ if (invocations_ < ~unsigned(0)) \
+ ++invocations_; \
+ impl_(*this, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ \
+ template<BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ void complete(BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ this->work_.reset(); \
+ this->handler_(BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF)
+#undef BOOST_ASIO_PRIVATE_COMPOSED_OP_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ //private:
+ Impl impl_;
+ Work work_;
+ Handler handler_;
+ unsigned invocations_;
+ };
+
+ template <typename Impl, typename Work, typename Handler, typename Signature>
+ inline void* asio_handler_allocate(std::size_t size,
+ composed_op<Impl, Work, Handler, Signature>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename Impl, typename Work, typename Handler, typename Signature>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ composed_op<Impl, Work, Handler, Signature>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename Impl, typename Work, typename Handler, typename Signature>
+ inline bool asio_handler_is_continuation(
+ composed_op<Impl, Work, Handler, Signature>* this_handler)
+ {
+ return this_handler->invocations_ > 1 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename Impl,
+ typename Work, typename Handler, typename Signature>
+ inline void asio_handler_invoke(Function& function,
+ composed_op<Impl, Work, Handler, Signature>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename Impl,
+ typename Work, typename Handler, typename Signature>
+ inline void asio_handler_invoke(const Function& function,
+ composed_op<Impl, Work, Handler, Signature>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Signature>
+ struct initiate_composed_op
+ {
+ template <typename Handler, typename Impl, typename Work>
+ void operator()(BOOST_ASIO_MOVE_ARG(Handler) handler,
+ BOOST_ASIO_MOVE_ARG(Impl) impl,
+ BOOST_ASIO_MOVE_ARG(Work) work) const
+ {
+ composed_op<typename decay<Impl>::type, typename decay<Work>::type,
+ typename decay<Handler>::type, Signature>(
+ BOOST_ASIO_MOVE_CAST(Impl)(impl), BOOST_ASIO_MOVE_CAST(Work)(work),
+ BOOST_ASIO_MOVE_CAST(Handler)(handler))();
+ }
+ };
+
+ template <typename IoObject>
+ inline typename IoObject::executor_type
+ get_composed_io_executor(IoObject& io_object)
+ {
+ return io_object.get_executor();
+ }
+
+ template <typename Executor>
+ inline const Executor& get_composed_io_executor(const Executor& ex,
+ typename enable_if<is_executor<Executor>::value>::type* = 0)
+ {
+ return ex;
+ }
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken, typename Signature,
+ typename Implementation, typename... IoObjectsOrExecutors>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
+async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors)
+{
+ return async_initiate<CompletionToken, Signature>(
+ detail::initiate_composed_op<Signature>(), token,
+ BOOST_ASIO_MOVE_CAST(Implementation)(implementation),
+ detail::make_composed_work(
+ detail::get_composed_io_executor(
+ BOOST_ASIO_MOVE_CAST(IoObjectsOrExecutors)(
+ io_objects_or_executors))...));
+}
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+template <typename CompletionToken, typename Signature, typename Implementation>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
+async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation,
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
+{
+ return async_initiate<CompletionToken, Signature>(
+ detail::initiate_composed_op<Signature>(), token,
+ BOOST_ASIO_MOVE_CAST(Implementation)(implementation),
+ detail::make_composed_work());
+}
+
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n) \
+ BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_##n
+
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1 \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1))
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2 \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2))
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3 \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3))
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4 \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4))
+# define BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5 \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T1)(x1)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T2)(x2)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T3)(x3)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T4)(x4)), \
+ detail::get_composed_io_executor(BOOST_ASIO_MOVE_CAST(T5)(x5))
+
+#define BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
+ template <typename CompletionToken, typename Signature, \
+ typename Implementation, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \
+ async_compose(BOOST_ASIO_MOVE_ARG(Implementation) implementation, \
+ BOOST_ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ return async_initiate<CompletionToken, Signature>( \
+ detail::initiate_composed_op<Signature>(), token, \
+ BOOST_ASIO_MOVE_CAST(Implementation)(implementation), \
+ detail::make_composed_work( \
+ BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR(n))); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
+#undef BOOST_ASIO_PRIVATE_ASYNC_COMPOSE_DEF
+
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_1
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_2
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_3
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_4
+#undef BOOST_ASIO_PRIVATE_GET_COMPOSED_IO_EXECUTOR_5
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_COMPOSE_HPP
diff --git a/boost/asio/impl/connect.hpp b/boost/asio/impl/connect.hpp
index 497f25884c..51e5e6cb16 100644
--- a/boost/asio/impl/connect.hpp
+++ b/boost/asio/impl/connect.hpp
@@ -2,7 +2,7 @@
// impl/connect.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -23,6 +23,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
#include <boost/asio/post.hpp>
@@ -101,9 +102,8 @@ namespace detail
}
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename EndpointSequence>
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
@@ -114,9 +114,8 @@ typename Protocol::endpoint connect(
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename EndpointSequence>
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
@@ -127,8 +126,8 @@ typename Protocol::endpoint connect(
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
boost::system::error_code ec;
@@ -137,8 +136,8 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s, Iterator begin,
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+inline Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
@@ -146,8 +145,8 @@ inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end)
{
boost::system::error_code ec;
@@ -156,17 +155,16 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator>
-inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+template <typename Protocol, typename Executor, typename Iterator>
+inline Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, boost::system::error_code& ec)
{
return connect(s, begin, end, detail::default_connect_condition(), ec);
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
@@ -178,10 +176,9 @@ typename Protocol::endpoint connect(
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
-typename Protocol::endpoint connect(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
boost::system::error_code& ec,
typename enable_if<is_endpoint_sequence<
@@ -193,9 +190,9 @@ typename Protocol::endpoint connect(
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, ConnectCondition connect_condition,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
@@ -205,9 +202,9 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+inline Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, ConnectCondition connect_condition,
boost::system::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
@@ -216,10 +213,10 @@ inline Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end, ConnectCondition connect_condition)
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ Iterator end, ConnectCondition connect_condition)
{
boost::system::error_code ec;
Iterator result = connect(s, begin, end, connect_condition, ec);
@@ -227,10 +224,10 @@ Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
return result;
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
-Iterator connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end, ConnectCondition connect_condition,
+Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ Iterator end, ConnectCondition connect_condition,
boost::system::error_code& ec)
{
ec = boost::system::error_code();
@@ -295,13 +292,12 @@ namespace detail
}
};
- template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler>
+ template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler>
class range_connect_op : base_from_connect_condition<ConnectCondition>
{
public:
- range_connect_op(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& sock,
+ range_connect_op(basic_socket<Protocol, Executor>& sock,
const EndpointSequence& endpoints,
const ConnectCondition& connect_condition,
RangeConnectHandler& handler)
@@ -338,10 +334,18 @@ namespace detail
void operator()(boost::system::error_code ec, int start = 0)
{
- typename EndpointSequence::const_iterator begin = endpoints_.begin();
- typename EndpointSequence::const_iterator iter = begin;
+ this->process(ec, start,
+ const_cast<const EndpointSequence&>(endpoints_).begin(),
+ const_cast<const EndpointSequence&>(endpoints_).end());
+ }
+
+ //private:
+ template <typename Iterator>
+ void process(boost::system::error_code ec,
+ int start, Iterator begin, Iterator end)
+ {
+ Iterator iter = begin;
std::advance(iter, index_);
- typename EndpointSequence::const_iterator end = endpoints_.end();
switch (start_ = start)
{
@@ -392,75 +396,92 @@ namespace detail
}
}
- //private:
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
+ basic_socket<Protocol, Executor>& socket_;
EndpointSequence endpoints_;
std::size_t index_;
int start_;
RangeConnectHandler handler_;
};
- template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler>
+ template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler>
inline void* asio_handler_allocate(std::size_t size,
- range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
+ range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, RangeConnectHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler>
+ template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
+ range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, RangeConnectHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler>
+ template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler>
inline bool asio_handler_is_continuation(
- range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
+ range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, RangeConnectHandler>* this_handler)
{
return boost_asio_handler_cont_helpers::is_continuation(
this_handler->handler_);
}
- template <typename Function, typename Protocol
- BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
- typename ConnectCondition, typename RangeConnectHandler>
+ template <typename Function, typename Executor, typename Protocol,
+ typename EndpointSequence, typename ConnectCondition,
+ typename RangeConnectHandler>
inline void asio_handler_invoke(Function& function,
- range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
+ range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, RangeConnectHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
- template <typename Function, typename Protocol
- BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
- typename ConnectCondition, typename RangeConnectHandler>
+ template <typename Function, typename Executor, typename Protocol,
+ typename EndpointSequence, typename ConnectCondition,
+ typename RangeConnectHandler>
inline void asio_handler_invoke(const Function& function,
- range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
+ range_connect_op<Protocol, Executor, EndpointSequence,
ConnectCondition, RangeConnectHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
- template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ struct initiate_async_range_connect
+ {
+ template <typename RangeConnectHandler, typename Protocol,
+ typename Executor, typename EndpointSequence, typename ConnectCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
+ basic_socket<Protocol, Executor>* s, const EndpointSequence& endpoints,
+ const ConnectCondition& connect_condition) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for an
+ // RangeConnectHandler.
+ BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(RangeConnectHandler,
+ handler, typename Protocol::endpoint) type_check;
+
+ non_const_lvalue<RangeConnectHandler> handler2(handler);
+ range_connect_op<Protocol, Executor, EndpointSequence, ConnectCondition,
+ typename decay<RangeConnectHandler>::type>(*s, endpoints,
+ connect_condition, handler2.value)(boost::system::error_code(), 1);
+ }
+ };
+
+ template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
class iterator_connect_op : base_from_connect_condition<ConnectCondition>
{
public:
- iterator_connect_op(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& sock,
+ iterator_connect_op(basic_socket<Protocol, Executor>& sock,
const Iterator& begin, const Iterator& end,
const ConnectCondition& connect_condition,
IteratorConnectHandler& handler)
@@ -544,82 +565,101 @@ namespace detail
}
//private:
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket_;
+ basic_socket<Protocol, Executor>& socket_;
Iterator iter_;
Iterator end_;
int start_;
IteratorConnectHandler handler_;
};
- template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
inline void* asio_handler_allocate(std::size_t size,
- iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
+ iterator_connect_op<Protocol, Executor, Iterator,
ConnectCondition, IteratorConnectHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
+ iterator_connect_op<Protocol, Executor, Iterator,
ConnectCondition, IteratorConnectHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+ template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
inline bool asio_handler_is_continuation(
- iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
+ iterator_connect_op<Protocol, Executor, Iterator,
ConnectCondition, IteratorConnectHandler>* this_handler)
{
return boost_asio_handler_cont_helpers::is_continuation(
this_handler->handler_);
}
- template <typename Function, typename Protocol
- BOOST_ASIO_SVC_TPARAM, typename Iterator,
- typename ConnectCondition, typename IteratorConnectHandler>
+ template <typename Function, typename Executor, typename Protocol,
+ typename Iterator, typename ConnectCondition,
+ typename IteratorConnectHandler>
inline void asio_handler_invoke(Function& function,
- iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
+ iterator_connect_op<Protocol, Executor, Iterator,
ConnectCondition, IteratorConnectHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
- template <typename Function, typename Protocol
- BOOST_ASIO_SVC_TPARAM, typename Iterator,
- typename ConnectCondition, typename IteratorConnectHandler>
+ template <typename Function, typename Executor, typename Protocol,
+ typename Iterator, typename ConnectCondition,
+ typename IteratorConnectHandler>
inline void asio_handler_invoke(const Function& function,
- iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
+ iterator_connect_op<Protocol, Executor, Iterator,
ConnectCondition, IteratorConnectHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_iterator_connect
+ {
+ template <typename IteratorConnectHandler, typename Protocol,
+ typename Executor, typename Iterator, typename ConnectCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+ basic_socket<Protocol, Executor>* s, Iterator begin,
+ Iterator end, const ConnectCondition& connect_condition) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for an
+ // IteratorConnectHandler.
+ BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
+ IteratorConnectHandler, handler, Iterator) type_check;
+
+ non_const_lvalue<IteratorConnectHandler> handler2(handler);
+ iterator_connect_op<Protocol, Executor, Iterator, ConnectCondition,
+ typename decay<IteratorConnectHandler>::type>(*s, begin, end,
+ connect_condition, handler2.value)(boost::system::error_code(), 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler, typename Allocator>
+template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler, typename Allocator>
struct associated_allocator<
- detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
- EndpointSequence, ConnectCondition, RangeConnectHandler>,
- Allocator>
+ detail::range_connect_op<Protocol, Executor, EndpointSequence,
+ ConnectCondition, RangeConnectHandler>, Allocator>
{
typedef typename associated_allocator<
RangeConnectHandler, Allocator>::type type;
static type get(
- const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
- EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
+ const detail::range_connect_op<Protocol, Executor, EndpointSequence,
+ ConnectCondition, RangeConnectHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<RangeConnectHandler,
@@ -627,40 +667,38 @@ struct associated_allocator<
}
};
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename EndpointSequence, typename ConnectCondition,
- typename RangeConnectHandler, typename Executor>
+template <typename Protocol, typename Executor, typename EndpointSequence,
+ typename ConnectCondition, typename RangeConnectHandler, typename Executor1>
struct associated_executor<
- detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
- EndpointSequence, ConnectCondition, RangeConnectHandler>,
- Executor>
+ detail::range_connect_op<Protocol, Executor, EndpointSequence,
+ ConnectCondition, RangeConnectHandler>, Executor1>
{
typedef typename associated_executor<
- RangeConnectHandler, Executor>::type type;
+ RangeConnectHandler, Executor1>::type type;
static type get(
- const detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG,
- EndpointSequence, ConnectCondition, RangeConnectHandler>& h,
- const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ const detail::range_connect_op<Protocol, Executor, EndpointSequence,
+ ConnectCondition, RangeConnectHandler>& h,
+ const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<RangeConnectHandler,
- Executor>::get(h.handler_, ex);
+ Executor1>::get(h.handler_, ex);
}
};
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename Iterator, typename ConnectCondition,
- typename IteratorConnectHandler, typename Allocator>
+template <typename Protocol, typename Executor, typename Iterator,
+ typename ConnectCondition, typename IteratorConnectHandler,
+ typename Allocator>
struct associated_allocator<
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- ConnectCondition, IteratorConnectHandler>,
+ detail::iterator_connect_op<Protocol, Executor,
+ Iterator, ConnectCondition, IteratorConnectHandler>,
Allocator>
{
typedef typename associated_allocator<
IteratorConnectHandler, Allocator>::type type;
static type get(
- const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
+ const detail::iterator_connect_op<Protocol, Executor,
Iterator, ConnectCondition, IteratorConnectHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
@@ -669,189 +707,119 @@ struct associated_allocator<
}
};
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
- typename Iterator, typename ConnectCondition,
- typename IteratorConnectHandler, typename Executor>
+template <typename Protocol, typename Executor, typename Iterator,
+ typename ConnectCondition, typename IteratorConnectHandler,
+ typename Executor1>
struct associated_executor<
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- ConnectCondition, IteratorConnectHandler>,
- Executor>
+ detail::iterator_connect_op<Protocol, Executor,
+ Iterator, ConnectCondition, IteratorConnectHandler>,
+ Executor1>
{
typedef typename associated_executor<
- IteratorConnectHandler, Executor>::type type;
+ IteratorConnectHandler, Executor1>::type type;
static type get(
- const detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG,
+ const detail::iterator_connect_op<Protocol, Executor,
Iterator, ConnectCondition, IteratorConnectHandler>& h,
- const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ const Executor1& ex = Executor1()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<IteratorConnectHandler,
- Executor>::get(h.handler_, ex);
+ Executor1>::get(h.handler_, ex);
}
};
#endif // !defined(GENERATING_DOCUMENTATION)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename EndpointSequence, typename RangeConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a RangeConnectHandler.
- BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(
- RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
-
- async_completion<RangeConnectHandler,
- void (boost::system::error_code, typename Protocol::endpoint)>
- init(handler);
-
- detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
- detail::default_connect_condition,
- BOOST_ASIO_HANDLER_TYPE(RangeConnectHandler,
- void (boost::system::error_code, typename Protocol::endpoint))>(s,
- endpoints, detail::default_connect_condition(),
- init.completion_handler)(boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<RangeConnectHandler,
+ void (boost::system::error_code, typename Protocol::endpoint)>(
+ detail::initiate_async_range_connect(), handler,
+ &s, endpoints, detail::default_connect_condition());
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a IteratorConnectHandler.
- BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
- IteratorConnectHandler, handler, Iterator) type_check;
-
- async_completion<IteratorConnectHandler,
- void (boost::system::error_code, Iterator)> init(handler);
-
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- detail::default_connect_condition, BOOST_ASIO_HANDLER_TYPE(
- IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
- begin, Iterator(), detail::default_connect_condition(),
- init.completion_handler)(boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<IteratorConnectHandler,
+ void (boost::system::error_code, Iterator)>(
+ detail::initiate_async_iterator_connect(), handler,
+ &s, begin, Iterator(), detail::default_connect_condition());
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM,
+template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a IteratorConnectHandler.
- BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
- IteratorConnectHandler, handler, Iterator) type_check;
-
- async_completion<IteratorConnectHandler,
- void (boost::system::error_code, Iterator)> init(handler);
-
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- detail::default_connect_condition, BOOST_ASIO_HANDLER_TYPE(
- IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
- begin, end, detail::default_connect_condition(),
- init.completion_handler)(boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<IteratorConnectHandler,
+ void (boost::system::error_code, Iterator)>(
+ detail::initiate_async_iterator_connect(), handler,
+ &s, begin, end, detail::default_connect_condition());
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename EndpointSequence,
+template <typename Protocol, typename Executor, typename EndpointSequence,
typename ConnectCondition, typename RangeConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (boost::system::error_code, typename Protocol::endpoint))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
+async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a RangeConnectHandler.
- BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK(
- RangeConnectHandler, handler, typename Protocol::endpoint) type_check;
-
- async_completion<RangeConnectHandler,
- void (boost::system::error_code, typename Protocol::endpoint)>
- init(handler);
-
- detail::range_connect_op<Protocol BOOST_ASIO_SVC_TARG, EndpointSequence,
- ConnectCondition, BOOST_ASIO_HANDLER_TYPE(RangeConnectHandler,
- void (boost::system::error_code, typename Protocol::endpoint))>(s,
- endpoints, connect_condition, init.completion_handler)(
- boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<RangeConnectHandler,
+ void (boost::system::error_code, typename Protocol::endpoint)>(
+ detail::initiate_async_range_connect(),
+ handler, &s, endpoints, connect_condition);
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, ConnectCondition connect_condition,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a IteratorConnectHandler.
- BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
- IteratorConnectHandler, handler, Iterator) type_check;
-
- async_completion<IteratorConnectHandler,
- void (boost::system::error_code, Iterator)> init(handler);
-
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- ConnectCondition, BOOST_ASIO_HANDLER_TYPE(
- IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
- begin, Iterator(), connect_condition, init.completion_handler)(
- boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<IteratorConnectHandler,
+ void (boost::system::error_code, Iterator)>(
+ detail::initiate_async_iterator_connect(),
+ handler, &s, begin, Iterator(), connect_condition);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-template <typename Protocol BOOST_ASIO_SVC_TPARAM, typename Iterator,
+template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (boost::system::error_code, Iterator))
-async_connect(basic_socket<Protocol BOOST_ASIO_SVC_TARG>& s,
- Iterator begin, Iterator end, ConnectCondition connect_condition,
+async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
+ Iterator end, ConnectCondition connect_condition,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a IteratorConnectHandler.
- BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK(
- IteratorConnectHandler, handler, Iterator) type_check;
-
- async_completion<IteratorConnectHandler,
- void (boost::system::error_code, Iterator)> init(handler);
-
- detail::iterator_connect_op<Protocol BOOST_ASIO_SVC_TARG, Iterator,
- ConnectCondition, BOOST_ASIO_HANDLER_TYPE(
- IteratorConnectHandler, void (boost::system::error_code, Iterator))>(s,
- begin, end, connect_condition, init.completion_handler)(
- boost::system::error_code(), 1);
-
- return init.result.get();
+ return async_initiate<IteratorConnectHandler,
+ void (boost::system::error_code, Iterator)>(
+ detail::initiate_async_iterator_connect(),
+ handler, &s, begin, end, connect_condition);
}
} // namespace asio
diff --git a/boost/asio/impl/defer.hpp b/boost/asio/impl/defer.hpp
index 7cc86da45c..856a33c788 100644
--- a/boost/asio/impl/defer.hpp
+++ b/boost/asio/impl/defer.hpp
@@ -2,7 +2,7 @@
// impl/defer.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,24 +24,46 @@
namespace boost {
namespace asio {
+namespace detail {
-template <typename CompletionToken>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
- BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+struct initiate_defer
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
+ template <typename CompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
+
+ typename associated_executor<DecayedHandler>::type ex(
+ (get_associated_executor)(handler));
- async_completion<CompletionToken, void()> init(token);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- typename associated_executor<handler>::type ex(
- (get_associated_executor)(init.completion_handler));
+ ex.defer(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
+ template <typename CompletionHandler, typename Executor>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
+ BOOST_ASIO_MOVE_ARG(Executor) ex) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
- ex.defer(BOOST_ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- return init.result.get();
+ ex.defer(detail::work_dispatcher<DecayedHandler>(
+ BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
+};
+
+} // namespace detail
+
+template <typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
+ BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+{
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_defer(), token);
}
template <typename Executor, typename CompletionToken>
@@ -49,16 +71,8 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
-
- async_completion<CompletionToken, void()> init(token);
-
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
-
- ex.defer(detail::work_dispatcher<handler>(init.completion_handler), alloc);
-
- return init.result.get();
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_defer(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>
diff --git a/boost/asio/impl/detached.hpp b/boost/asio/impl/detached.hpp
new file mode 100644
index 0000000000..ae2c882fba
--- /dev/null
+++ b/boost/asio/impl/detached.hpp
@@ -0,0 +1,132 @@
+//
+// impl/detached.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_DETACHED_HPP
+#define BOOST_ASIO_IMPL_DETACHED_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/async_result.hpp>
+#include <boost/asio/detail/variadic_templates.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+ // Class to adapt a detached_t as a completion handler.
+ class detached_handler
+ {
+ public:
+ typedef void result_type;
+
+ detached_handler(detached_t)
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename... Args>
+ void operator()(Args...)
+ {
+ }
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ void operator()()
+ {
+ }
+
+#define BOOST_ASIO_PRIVATE_DETACHED_DEF(n) \
+ template <BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ void operator()(BOOST_ASIO_VARIADIC_TARGS(n)) \
+ { \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_DETACHED_DEF)
+#undef BOOST_ASIO_PRIVATE_DETACHED_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+ };
+
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename Signature>
+struct async_result<detached_t, Signature>
+{
+ typedef boost::asio::detail::detached_handler completion_handler_type;
+
+ typedef void return_type;
+
+ explicit async_result(completion_handler_type&)
+ {
+ }
+
+ void get()
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Initiation, typename RawCompletionToken, typename... Args>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken),
+ BOOST_ASIO_MOVE_ARG(Args)... args)
+ {
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ detail::detached_handler(detached_t()),
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Initiation, typename RawCompletionToken>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken))
+ {
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)(
+ detail::detached_handler(detached_t()));
+ }
+
+#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
+ template <typename Initiation, typename RawCompletionToken, \
+ BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ static return_type initiate( \
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken), \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation)( \
+ detail::detached_handler(detached_t()), \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
+#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_DETACHED_HPP
diff --git a/boost/asio/impl/dispatch.hpp b/boost/asio/impl/dispatch.hpp
index 8bdce85180..bcba2ee401 100644
--- a/boost/asio/impl/dispatch.hpp
+++ b/boost/asio/impl/dispatch.hpp
@@ -2,7 +2,7 @@
// impl/dispatch.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,24 +24,46 @@
namespace boost {
namespace asio {
+namespace detail {
-template <typename CompletionToken>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
- BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+struct initiate_dispatch
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
+ template <typename CompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
+
+ typename associated_executor<DecayedHandler>::type ex(
+ (get_associated_executor)(handler));
- async_completion<CompletionToken, void()> init(token);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- typename associated_executor<handler>::type ex(
- (get_associated_executor)(init.completion_handler));
+ ex.dispatch(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
+ template <typename CompletionHandler, typename Executor>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
+ BOOST_ASIO_MOVE_ARG(Executor) ex) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
- ex.dispatch(BOOST_ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- return init.result.get();
+ ex.dispatch(detail::work_dispatcher<DecayedHandler>(
+ BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
+};
+
+} // namespace detail
+
+template <typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
+ BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+{
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_dispatch(), token);
}
template <typename Executor, typename CompletionToken>
@@ -49,17 +71,8 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
-
- async_completion<CompletionToken, void()> init(token);
-
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
-
- ex.dispatch(detail::work_dispatcher<handler>(
- init.completion_handler), alloc);
-
- return init.result.get();
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_dispatch(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>
diff --git a/boost/asio/impl/error.ipp b/boost/asio/impl/error.ipp
index 49a10462bd..0dcb1257c7 100644
--- a/boost/asio/impl/error.ipp
+++ b/boost/asio/impl/error.ipp
@@ -2,7 +2,7 @@
// impl/error.ipp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/execution_context.hpp b/boost/asio/impl/execution_context.hpp
index eadf36b145..a1617f8c9c 100644
--- a/boost/asio/impl/execution_context.hpp
+++ b/boost/asio/impl/execution_context.hpp
@@ -2,7 +2,7 @@
// impl/execution_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,6 +24,8 @@
namespace boost {
namespace asio {
+#if !defined(GENERATING_DOCUMENTATION)
+
template <typename Service>
inline Service& use_service(execution_context& e)
{
@@ -33,8 +35,7 @@ inline Service& use_service(execution_context& e)
return e.service_registry_->template use_service<Service>();
}
-#if !defined(GENERATING_DOCUMENTATION)
-# if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Service, typename... Args>
Service& make_service(execution_context& e, BOOST_ASIO_MOVE_ARG(Args)... args)
@@ -47,7 +48,7 @@ Service& make_service(execution_context& e, BOOST_ASIO_MOVE_ARG(Args)... args)
return result;
}
-# else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Service>
Service& make_service(execution_context& e)
@@ -75,8 +76,7 @@ Service& make_service(execution_context& e)
BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_MAKE_SERVICE_DEF)
#undef BOOST_ASIO_PRIVATE_MAKE_SERVICE_DEF
-# endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-#endif // !defined(GENERATING_DOCUMENTATION)
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
template <typename Service>
inline void add_service(execution_context& e, Service* svc)
@@ -96,6 +96,8 @@ inline bool has_service(execution_context& e)
return e.service_registry_->template has_service<Service>();
}
+#endif // !defined(GENERATING_DOCUMENTATION)
+
inline execution_context& execution_context::service::context()
{
return owner_;
diff --git a/boost/asio/impl/execution_context.ipp b/boost/asio/impl/execution_context.ipp
index 219a66113d..30e7bb926f 100644
--- a/boost/asio/impl/execution_context.ipp
+++ b/boost/asio/impl/execution_context.ipp
@@ -2,7 +2,7 @@
// impl/execution_context.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/executor.hpp b/boost/asio/impl/executor.hpp
index 106763b042..b1c6cd748f 100644
--- a/boost/asio/impl/executor.hpp
+++ b/boost/asio/impl/executor.hpp
@@ -2,7 +2,7 @@
// impl/executor.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,7 +17,7 @@
#include <boost/asio/detail/config.hpp>
#include <boost/asio/detail/atomic_count.hpp>
-#include <boost/asio/detail/executor_op.hpp>
+#include <boost/asio/detail/executor_function.hpp>
#include <boost/asio/detail/global.hpp>
#include <boost/asio/detail/memory.hpp>
#include <boost/asio/detail/recycling_allocator.hpp>
@@ -41,36 +41,37 @@ public:
explicit function(F f, const Alloc& a)
{
// Allocate and construct an operation to wrap the function.
- typedef detail::executor_op<F, Alloc> op;
- typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
- op_ = new (p.v) op(BOOST_ASIO_MOVE_CAST(F)(f), a);
+ typedef detail::executor_function<F, Alloc> func_type;
+ typename func_type::ptr p = {
+ detail::addressof(a), func_type::ptr::allocate(a), 0 };
+ func_ = new (p.v) func_type(BOOST_ASIO_MOVE_CAST(F)(f), a);
p.v = 0;
}
- function(function&& other)
- : op_(other.op_)
+ function(function&& other) BOOST_ASIO_NOEXCEPT
+ : func_(other.func_)
{
- other.op_ = 0;
+ other.func_ = 0;
}
~function()
{
- if (op_)
- op_->destroy();
+ if (func_)
+ func_->destroy();
}
void operator()()
{
- if (op_)
+ if (func_)
{
- detail::scheduler_operation* op = op_;
- op_ = 0;
- op->complete(this, boost::system::error_code(), 0);
+ detail::executor_function_base* func = func_;
+ func_ = 0;
+ func->complete();
}
}
private:
- detail::scheduler_operation* op_;
+ detail::executor_function_base* func_;
};
#else // defined(BOOST_ASIO_HAS_MOVE)
diff --git a/boost/asio/impl/executor.ipp b/boost/asio/impl/executor.ipp
index 86114d93f1..289265d706 100644
--- a/boost/asio/impl/executor.ipp
+++ b/boost/asio/impl/executor.ipp
@@ -2,7 +2,7 @@
// impl/executor.ipp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/handler_alloc_hook.ipp b/boost/asio/impl/handler_alloc_hook.ipp
index 2b04ec104e..a580f71ffa 100644
--- a/boost/asio/impl/handler_alloc_hook.ipp
+++ b/boost/asio/impl/handler_alloc_hook.ipp
@@ -2,7 +2,7 @@
// impl/handler_alloc_hook.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/io_context.hpp b/boost/asio/impl/io_context.hpp
index 37f8ace42a..2cf8c4bc8d 100644
--- a/boost/asio/impl/io_context.hpp
+++ b/boost/asio/impl/io_context.hpp
@@ -2,7 +2,7 @@
// impl/io_context.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -19,6 +19,7 @@
#include <boost/asio/detail/executor_op.hpp>
#include <boost/asio/detail/fenced_block.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/recycling_allocator.hpp>
#include <boost/asio/detail/service_registry.hpp>
#include <boost/asio/detail/throw_error.hpp>
@@ -26,6 +27,8 @@
#include <boost/asio/detail/push_options.hpp>
+#if !defined(GENERATING_DOCUMENTATION)
+
namespace boost {
namespace asio {
@@ -49,6 +52,8 @@ inline detail::io_context_impl& use_service<detail::io_context_impl>(
} // namespace asio
} // namespace boost
+#endif // !defined(GENERATING_DOCUMENTATION)
+
#include <boost/asio/detail/pop_options.hpp>
#if defined(BOOST_ASIO_HAS_IOCP)
@@ -130,70 +135,87 @@ inline void io_context::reset()
restart();
}
+struct io_context::initiate_dispatch
+{
+ template <typename LegacyCompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
+ io_context* self) const
+ {
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a LegacyCompletionHandler.
+ BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
+ LegacyCompletionHandler, handler) type_check;
+
+ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
+ if (self->impl_.can_dispatch())
+ {
+ detail::fenced_block b(detail::fenced_block::full);
+ boost_asio_handler_invoke_helpers::invoke(
+ handler2.value, handler2.value);
+ }
+ else
+ {
+ // Allocate and construct an operation to wrap the handler.
+ typedef detail::completion_handler<
+ typename decay<LegacyCompletionHandler>::type> op;
+ typename op::ptr p = { detail::addressof(handler2.value),
+ op::ptr::allocate(handler2.value), 0 };
+ p.p = new (p.v) op(handler2.value);
+
+ BOOST_ASIO_HANDLER_CREATION((*self, *p.p,
+ "io_context", self, 0, "dispatch"));
+
+ self->impl_.do_dispatch(p.p);
+ p.v = p.p = 0;
+ }
+ }
+};
+
template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a LegacyCompletionHandler.
- BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
- LegacyCompletionHandler, handler) type_check;
-
- async_completion<LegacyCompletionHandler, void ()> init(handler);
+ return async_initiate<LegacyCompletionHandler, void ()>(
+ initiate_dispatch(), handler, this);
+}
- if (impl_.can_dispatch())
- {
- detail::fenced_block b(detail::fenced_block::full);
- boost_asio_handler_invoke_helpers::invoke(
- init.completion_handler, init.completion_handler);
- }
- else
+struct io_context::initiate_post
+{
+ template <typename LegacyCompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
+ io_context* self) const
{
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a LegacyCompletionHandler.
+ BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
+ LegacyCompletionHandler, handler) type_check;
+
+ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
+
+ bool is_continuation =
+ boost_asio_handler_cont_helpers::is_continuation(handler2.value);
+
// Allocate and construct an operation to wrap the handler.
typedef detail::completion_handler<
- typename handler_type<LegacyCompletionHandler, void ()>::type> op;
- typename op::ptr p = { detail::addressof(init.completion_handler),
- op::ptr::allocate(init.completion_handler), 0 };
- p.p = new (p.v) op(init.completion_handler);
+ typename decay<LegacyCompletionHandler>::type> op;
+ typename op::ptr p = { detail::addressof(handler2.value),
+ op::ptr::allocate(handler2.value), 0 };
+ p.p = new (p.v) op(handler2.value);
- BOOST_ASIO_HANDLER_CREATION((*this, *p.p,
- "io_context", this, 0, "dispatch"));
+ BOOST_ASIO_HANDLER_CREATION((*self, *p.p,
+ "io_context", self, 0, "post"));
- impl_.do_dispatch(p.p);
+ self->impl_.post_immediate_completion(p.p, is_continuation);
p.v = p.p = 0;
}
-
- return init.result.get();
-}
+};
template <typename LegacyCompletionHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
io_context::post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a LegacyCompletionHandler.
- BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
- LegacyCompletionHandler, handler) type_check;
-
- async_completion<LegacyCompletionHandler, void ()> init(handler);
-
- bool is_continuation =
- boost_asio_handler_cont_helpers::is_continuation(init.completion_handler);
-
- // Allocate and construct an operation to wrap the handler.
- typedef detail::completion_handler<
- typename handler_type<LegacyCompletionHandler, void ()>::type> op;
- typename op::ptr p = { detail::addressof(init.completion_handler),
- op::ptr::allocate(init.completion_handler), 0 };
- p.p = new (p.v) op(init.completion_handler);
-
- BOOST_ASIO_HANDLER_CREATION((*this, *p.p,
- "io_context", this, 0, "post"));
-
- impl_.post_immediate_completion(p.p, is_continuation);
- p.v = p.p = 0;
-
- return init.result.get();
+ return async_initiate<LegacyCompletionHandler, void ()>(
+ initiate_post(), handler, this);
}
template <typename Handler>
@@ -320,11 +342,6 @@ inline boost::asio::io_context& io_context::work::get_io_context()
{
return static_cast<boost::asio::io_context&>(io_context_impl_.context());
}
-
-inline boost::asio::io_context& io_context::work::get_io_service()
-{
- return static_cast<boost::asio::io_context&>(io_context_impl_.context());
-}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
inline boost::asio::io_context& io_context::service::get_io_context()
@@ -332,13 +349,6 @@ inline boost::asio::io_context& io_context::service::get_io_context()
return static_cast<boost::asio::io_context&>(context());
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-inline boost::asio::io_context& io_context::service::get_io_service()
-{
- return static_cast<boost::asio::io_context&>(context());
-}
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
} // namespace asio
} // namespace boost
diff --git a/boost/asio/impl/io_context.ipp b/boost/asio/impl/io_context.ipp
index 96a7de7415..5de07181d4 100644
--- a/boost/asio/impl/io_context.ipp
+++ b/boost/asio/impl/io_context.ipp
@@ -2,7 +2,7 @@
// impl/io_context.ipp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,13 +35,14 @@ namespace boost {
namespace asio {
io_context::io_context()
- : impl_(add_impl(new impl_type(*this, BOOST_ASIO_CONCURRENCY_HINT_DEFAULT)))
+ : impl_(add_impl(new impl_type(*this,
+ BOOST_ASIO_CONCURRENCY_HINT_DEFAULT, false)))
{
}
io_context::io_context(int concurrency_hint)
: impl_(add_impl(new impl_type(*this, concurrency_hint == 1
- ? BOOST_ASIO_CONCURRENCY_HINT_1 : concurrency_hint)))
+ ? BOOST_ASIO_CONCURRENCY_HINT_1 : concurrency_hint, false)))
{
}
diff --git a/boost/asio/impl/post.hpp b/boost/asio/impl/post.hpp
index d318f890ff..ac0831e532 100644
--- a/boost/asio/impl/post.hpp
+++ b/boost/asio/impl/post.hpp
@@ -2,7 +2,7 @@
// impl/post.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -24,24 +24,46 @@
namespace boost {
namespace asio {
+namespace detail {
-template <typename CompletionToken>
-BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
- BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+struct initiate_post
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
+ template <typename CompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
+
+ typename associated_executor<DecayedHandler>::type ex(
+ (get_associated_executor)(handler));
- async_completion<CompletionToken, void()> init(token);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- typename associated_executor<handler>::type ex(
- (get_associated_executor)(init.completion_handler));
+ ex.post(BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), alloc);
+ }
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
+ template <typename CompletionHandler, typename Executor>
+ void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
+ BOOST_ASIO_MOVE_ARG(Executor) ex) const
+ {
+ typedef typename decay<CompletionHandler>::type DecayedHandler;
- ex.post(BOOST_ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
+ typename associated_allocator<DecayedHandler>::type alloc(
+ (get_associated_allocator)(handler));
- return init.result.get();
+ ex.post(detail::work_dispatcher<DecayedHandler>(
+ BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
+};
+
+} // namespace detail
+
+template <typename CompletionToken>
+BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
+ BOOST_ASIO_MOVE_ARG(CompletionToken) token)
+{
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_post(), token);
}
template <typename Executor, typename CompletionToken>
@@ -49,16 +71,8 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
const Executor& ex, BOOST_ASIO_MOVE_ARG(CompletionToken) token,
typename enable_if<is_executor<Executor>::value>::type*)
{
- typedef BOOST_ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
-
- async_completion<CompletionToken, void()> init(token);
-
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
-
- ex.post(detail::work_dispatcher<handler>(init.completion_handler), alloc);
-
- return init.result.get();
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_post(), token, ex);
}
template <typename ExecutionContext, typename CompletionToken>
diff --git a/boost/asio/impl/read.hpp b/boost/asio/impl/read.hpp
index 9fbddc964e..6eabf0f616 100644
--- a/boost/asio/impl/read.hpp
+++ b/boost/asio/impl/read.hpp
@@ -2,7 +2,7 @@
// impl/read.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -29,6 +29,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
@@ -69,7 +70,8 @@ std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
>::type*)
{
return detail::read_buffer_sequence(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
+ boost::asio::buffer_sequence_begin(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncReadStream, typename MutableBufferSequence>
@@ -103,22 +105,26 @@ inline std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
>::type*)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = read(s, buffers, completion_condition, ec);
+ std::size_t bytes_transferred = read(s, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "read");
return bytes_transferred;
}
-template <typename SyncReadStream, typename DynamicBuffer,
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition, boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
ec = boost::system::error_code();
std::size_t total_transferred = 0;
@@ -141,45 +147,48 @@ std::size_t read(SyncReadStream& s,
return total_transferred;
}
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
inline std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), transfer_all(), ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), transfer_all(), ec);
boost::asio::detail::throw_error(ec, "read");
return bytes_transferred;
}
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
inline std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
- return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
transfer_all(), ec);
}
-template <typename SyncReadStream, typename DynamicBuffer,
+template <typename SyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition>
inline std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- completion_condition, ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "read");
return bytes_transferred;
}
@@ -193,7 +202,8 @@ inline std::size_t read(SyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, boost::system::error_code& ec)
{
- return read(s, basic_streambuf_ref<Allocator>(b), completion_condition, ec);
+ return read(s, basic_streambuf_ref<Allocator>(b),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncReadStream, typename Allocator>
@@ -217,11 +227,87 @@ inline std::size_t read(SyncReadStream& s,
boost::asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition)
{
- return read(s, basic_streambuf_ref<Allocator>(b), completion_condition);
+ return read(s, basic_streambuf_ref<Allocator>(b),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ DynamicBuffer_v2& b = buffers;
+
+ 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>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(max_size, b.max_size() - b.size()));
+ while (bytes_available > 0)
+ {
+ std::size_t pos = b.size();
+ b.grow(bytes_available);
+ std::size_t bytes_transferred = s.read_some(
+ b.data(pos, bytes_available), ec);
+ b.shrink(bytes_available - 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>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(max_size, b.max_size() - b.size()));
+ }
+ return total_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), transfer_all(), ec);
+ boost::asio::detail::throw_error(ec, "read");
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return read(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ transfer_all(), ec);
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+inline std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
+ boost::asio::detail::throw_error(ec, "read");
+ return bytes_transferred;
+}
namespace detail
{
@@ -233,7 +319,7 @@ namespace detail
{
public:
read_op(AsyncReadStream& stream, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, ReadHandler& handler)
+ CompletionCondition& completion_condition, ReadHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
stream_(stream),
@@ -254,9 +340,11 @@ namespace detail
}
read_op(read_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
stream_(other.stream_),
- buffers_(other.buffers_),
+ buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
start_(other.start_),
handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
{
@@ -287,9 +375,11 @@ namespace detail
}
//private:
+ typedef boost::asio::detail::consuming_buffers<mutable_buffer,
+ MutableBufferSequence, MutableBufferIterator> buffers_type;
+
AsyncReadStream& stream_;
- boost::asio::detail::consuming_buffers<mutable_buffer,
- MutableBufferSequence, MutableBufferIterator> buffers_;
+ buffers_type buffers_;
int start_;
ReadHandler handler_;
};
@@ -355,13 +445,33 @@ namespace detail
typename ReadHandler>
inline void start_read_buffer_sequence_op(AsyncReadStream& stream,
const MutableBufferSequence& buffers, const MutableBufferIterator&,
- CompletionCondition completion_condition, ReadHandler& handler)
+ CompletionCondition& completion_condition, ReadHandler& handler)
{
detail::read_op<AsyncReadStream, MutableBufferSequence,
MutableBufferIterator, CompletionCondition, ReadHandler>(
stream, buffers, completion_condition, handler)(
boost::system::error_code(), 0, 1);
}
+
+ struct initiate_async_read_buffer_sequence
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename MutableBufferSequence, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, const MutableBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ start_read_buffer_sequence_op(*s, buffers,
+ boost::asio::buffer_sequence_begin(buffers),
+ completion_cond2.value, handler2.value);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -417,18 +527,10 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_read_buffer_sequence_op(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition,
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_buffer_sequence(), handler, &s, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncReadStream, typename MutableBufferSequence,
@@ -441,32 +543,26 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_read_buffer_sequence_op(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), transfer_all(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_buffer_sequence(),
+ handler, &s, buffers, transfer_all());
}
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
namespace detail
{
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
- class read_dynbuf_op
+ class read_dynbuf_v1_op
: detail::base_from_completion_cond<CompletionCondition>
{
public:
template <typename BufferSequence>
- read_dynbuf_op(AsyncReadStream& stream,
+ read_dynbuf_v1_op(AsyncReadStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
- CompletionCondition completion_condition, ReadHandler& handler)
+ CompletionCondition& completion_condition, ReadHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
stream_(stream),
@@ -478,7 +574,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- read_dynbuf_op(const read_dynbuf_op& other)
+ read_dynbuf_v1_op(const read_dynbuf_v1_op& other)
: detail::base_from_completion_cond<CompletionCondition>(other),
stream_(other.stream_),
buffers_(other.buffers_),
@@ -488,10 +584,12 @@ namespace detail
{
}
- read_dynbuf_op(read_dynbuf_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ read_dynbuf_v1_op(read_dynbuf_v1_op&& other)
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
start_(other.start_),
total_transferred_(other.total_transferred_),
handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
@@ -515,7 +613,7 @@ namespace detail
for (;;)
{
stream_.async_read_some(buffers_.prepare(bytes_available),
- BOOST_ASIO_MOVE_CAST(read_dynbuf_op)(*this));
+ BOOST_ASIO_MOVE_CAST(read_dynbuf_v1_op)(*this));
return; default:
total_transferred_ += bytes_transferred;
buffers_.commit(bytes_transferred);
@@ -535,36 +633,36 @@ namespace detail
//private:
AsyncReadStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
int start_;
std::size_t total_transferred_;
ReadHandler handler_;
};
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
inline void* asio_handler_allocate(std::size_t size,
- read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
CompletionCondition, ReadHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
CompletionCondition, ReadHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
inline bool asio_handler_is_continuation(
- read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
CompletionCondition, ReadHandler>* this_handler)
{
return this_handler->start_ == 0 ? true
@@ -573,10 +671,10 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename CompletionCondition,
+ typename DynamicBuffer_v1, typename CompletionCondition,
typename ReadHandler>
inline void asio_handler_invoke(Function& function,
- read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
CompletionCondition, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
@@ -584,49 +682,71 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename CompletionCondition,
+ typename DynamicBuffer_v1, typename CompletionCondition,
typename ReadHandler>
inline void asio_handler_invoke(const Function& function,
- read_dynbuf_op<AsyncReadStream, DynamicBuffer,
+ read_dynbuf_v1_op<AsyncReadStream, DynamicBuffer_v1,
CompletionCondition, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_dynbuf_v1
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v1, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ read_dynbuf_v1_op<AsyncReadStream, typename decay<DynamicBuffer_v1>::type,
+ CompletionCondition, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ completion_cond2.value, handler2.value)(
+ boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler, typename Allocator>
struct associated_allocator<
- detail::read_dynbuf_op<AsyncReadStream,
- DynamicBuffer, CompletionCondition, ReadHandler>,
+ detail::read_dynbuf_v1_op<AsyncReadStream,
+ DynamicBuffer_v1, CompletionCondition, ReadHandler>,
Allocator>
{
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
static type get(
- const detail::read_dynbuf_op<AsyncReadStream,
- DynamicBuffer, CompletionCondition, ReadHandler>& h,
+ const detail::read_dynbuf_v1_op<AsyncReadStream,
+ DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler, typename Executor>
struct associated_executor<
- detail::read_dynbuf_op<AsyncReadStream,
- DynamicBuffer, CompletionCondition, ReadHandler>,
+ detail::read_dynbuf_v1_op<AsyncReadStream,
+ DynamicBuffer_v1, CompletionCondition, ReadHandler>,
Executor>
{
typedef typename associated_executor<ReadHandler, Executor>::type type;
static type get(
- const detail::read_dynbuf_op<AsyncReadStream,
- DynamicBuffer, CompletionCondition, ReadHandler>& h,
+ const detail::read_dynbuf_v1_op<AsyncReadStream,
+ DynamicBuffer_v1, CompletionCondition, ReadHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -636,49 +756,44 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
return async_read(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
}
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
// If you get an error on the following line it means that your handler does
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_dynbuf_op<AsyncReadStream,
- typename decay<DynamicBuffer>::type,
- CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
- ReadHandler, void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- completion_condition, init.completion_handler)(
- boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_dynbuf_v1(), handler, &s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -703,11 +818,260 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
return async_read(s, basic_streambuf_ref<Allocator>(b),
- completion_condition, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
+ BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+ class read_dynbuf_v2_op
+ : detail::base_from_completion_cond<CompletionCondition>
+ {
+ public:
+ template <typename BufferSequence>
+ read_dynbuf_v2_op(AsyncReadStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ CompletionCondition& completion_condition, ReadHandler& handler)
+ : detail::base_from_completion_cond<
+ CompletionCondition>(completion_condition),
+ stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ start_(0),
+ total_transferred_(0),
+ bytes_available_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ read_dynbuf_v2_op(const read_dynbuf_v2_op& other)
+ : detail::base_from_completion_cond<CompletionCondition>(other),
+ stream_(other.stream_),
+ buffers_(other.buffers_),
+ start_(other.start_),
+ total_transferred_(other.total_transferred_),
+ bytes_available_(other.bytes_available_),
+ handler_(other.handler_)
+ {
+ }
+
+ read_dynbuf_v2_op(read_dynbuf_v2_op&& other)
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
+ stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ start_(other.start_),
+ total_transferred_(other.total_transferred_),
+ bytes_available_(other.bytes_available_),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ std::size_t max_size, pos;
+ switch (start_ = start)
+ {
+ case 1:
+ max_size = this->check_for_completion(ec, total_transferred_);
+ bytes_available_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(max_size,
+ buffers_.max_size() - buffers_.size()));
+ for (;;)
+ {
+ pos = buffers_.size();
+ buffers_.grow(bytes_available_);
+ stream_.async_read_some(buffers_.data(pos, bytes_available_),
+ BOOST_ASIO_MOVE_CAST(read_dynbuf_v2_op)(*this));
+ return; default:
+ total_transferred_ += bytes_transferred;
+ buffers_.shrink(bytes_available_ - bytes_transferred);
+ max_size = this->check_for_completion(ec, total_transferred_);
+ bytes_available_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(max_size,
+ buffers_.max_size() - buffers_.size()));
+ if ((!ec && bytes_transferred == 0) || bytes_available_ == 0)
+ break;
+ }
+
+ handler_(ec, static_cast<const std::size_t&>(total_transferred_));
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ int start_;
+ std::size_t total_transferred_;
+ std::size_t bytes_available_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+ inline bool asio_handler_is_continuation(
+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ return this_handler->start_ == 0 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename CompletionCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(Function& function,
+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename CompletionCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_dynbuf_v2_op<AsyncReadStream, DynamicBuffer_v2,
+ CompletionCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_read_dynbuf_v2
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ read_dynbuf_v2_op<AsyncReadStream, typename decay<DynamicBuffer_v2>::type,
+ CompletionCondition, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ completion_cond2.value, handler2.value)(
+ boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler, typename Allocator>
+struct associated_allocator<
+ detail::read_dynbuf_v2_op<AsyncReadStream,
+ DynamicBuffer_v2, CompletionCondition, ReadHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+ static type get(
+ const detail::read_dynbuf_v2_op<AsyncReadStream,
+ DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler, typename Executor>
+struct associated_executor<
+ detail::read_dynbuf_v2_op<AsyncReadStream,
+ DynamicBuffer_v2, CompletionCondition, ReadHandler>,
+ Executor>
+{
+ typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+ static type get(
+ const detail::read_dynbuf_v2_op<AsyncReadStream,
+ DynamicBuffer_v2, CompletionCondition, ReadHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_read(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ transfer_all(), BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+}
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ // If you get an error on the following line it means that your handler does
+ // not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_dynbuf_v2(), handler, &s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
+}
} // namespace asio
} // namespace boost
diff --git a/boost/asio/impl/read_at.hpp b/boost/asio/impl/read_at.hpp
index e3c31c543e..8152ef99a4 100644
--- a/boost/asio/impl/read_at.hpp
+++ b/boost/asio/impl/read_at.hpp
@@ -2,7 +2,7 @@
// impl/read_at.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -29,6 +29,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
@@ -71,7 +72,8 @@ std::size_t read_at(SyncRandomAccessReadDevice& d,
CompletionCondition completion_condition, boost::system::error_code& ec)
{
return detail::read_at_buffer_sequence(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
+ boost::asio::buffer_sequence_begin(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncRandomAccessReadDevice, typename MutableBufferSequence>
@@ -100,8 +102,8 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d,
CompletionCondition completion_condition)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, buffers, completion_condition, ec);
+ std::size_t bytes_transferred = read_at(d, offset, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "read_at");
return bytes_transferred;
}
@@ -159,8 +161,8 @@ inline std::size_t read_at(SyncRandomAccessReadDevice& d,
CompletionCondition completion_condition)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = read_at(
- d, offset, b, completion_condition, ec);
+ std::size_t bytes_transferred = read_at(d, offset, b,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "read_at");
return bytes_transferred;
}
@@ -179,7 +181,7 @@ namespace detail
public:
read_at_op(AsyncRandomAccessReadDevice& device,
uint64_t offset, const MutableBufferSequence& buffers,
- CompletionCondition completion_condition, ReadHandler& handler)
+ CompletionCondition& completion_condition, ReadHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
device_(device),
@@ -202,10 +204,12 @@ namespace detail
}
read_at_op(read_at_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
device_(other.device_),
offset_(other.offset_),
- buffers_(other.buffers_),
+ buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
start_(other.start_),
handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
{
@@ -237,10 +241,12 @@ namespace detail
}
//private:
+ typedef boost::asio::detail::consuming_buffers<mutable_buffer,
+ MutableBufferSequence, MutableBufferIterator> buffers_type;
+
AsyncRandomAccessReadDevice& device_;
uint64_t offset_;
- boost::asio::detail::consuming_buffers<mutable_buffer,
- MutableBufferSequence, MutableBufferIterator> buffers_;
+ buffers_type buffers_;
int start_;
ReadHandler handler_;
};
@@ -306,7 +312,7 @@ namespace detail
typename CompletionCondition, typename ReadHandler>
inline void start_read_at_buffer_sequence_op(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers,
- const MutableBufferIterator&, CompletionCondition completion_condition,
+ const MutableBufferIterator&, CompletionCondition& completion_condition,
ReadHandler& handler)
{
detail::read_at_op<AsyncRandomAccessReadDevice, MutableBufferSequence,
@@ -314,6 +320,27 @@ namespace detail
d, offset, buffers, completion_condition, handler)(
boost::system::error_code(), 0, 1);
}
+
+ struct initiate_async_read_at_buffer_sequence
+ {
+ template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
+ typename MutableBufferSequence, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncRandomAccessReadDevice* d, uint64_t offset,
+ const MutableBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ start_read_at_buffer_sequence_op(*d, offset, buffers,
+ boost::asio::buffer_sequence_begin(buffers),
+ completion_cond2.value, handler2.value);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -369,18 +396,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_read_at_buffer_sequence_op(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition,
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_at_buffer_sequence(), handler, &d, offset,
+ buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncRandomAccessReadDevice, typename MutableBufferSequence,
@@ -391,18 +410,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_read_at_buffer_sequence_op(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), transfer_all(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_at_buffer_sequence(),
+ handler, &d, offset, buffers, transfer_all());
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -418,7 +429,7 @@ namespace detail
public:
read_at_streambuf_op(AsyncRandomAccessReadDevice& device,
uint64_t offset, basic_streambuf<Allocator>& streambuf,
- CompletionCondition completion_condition, ReadHandler& handler)
+ CompletionCondition& completion_condition, ReadHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
device_(device),
@@ -443,7 +454,9 @@ namespace detail
}
read_at_streambuf_op(read_at_streambuf_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
device_(other.device_),
offset_(other.offset_),
streambuf_(other.streambuf_),
@@ -540,6 +553,28 @@ namespace detail
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_at_streambuf
+ {
+ template <typename ReadHandler, typename AsyncRandomAccessReadDevice,
+ typename Allocator, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncRandomAccessReadDevice* d, uint64_t offset,
+ basic_streambuf<Allocator>* b,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
+ CompletionCondition, typename decay<ReadHandler>::type>(
+ *d, offset, *b, completion_cond2.value, handler2.value)(
+ boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -591,20 +626,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
- CompletionCondition, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- d, offset, b, completion_condition, init.completion_handler)(
- boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_at_streambuf(), handler, &d, offset,
+ &b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncRandomAccessReadDevice, typename Allocator,
@@ -615,20 +640,10 @@ async_read_at(AsyncRandomAccessReadDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_at_streambuf_op<AsyncRandomAccessReadDevice, Allocator,
- detail::transfer_all_t, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- d, offset, b, transfer_all(), init.completion_handler)(
- boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_at_streambuf(),
+ handler, &d, offset, &b, transfer_all());
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
diff --git a/boost/asio/impl/read_until.hpp b/boost/asio/impl/read_until.hpp
index 8bc959557a..63b86f8f2e 100644
--- a/boost/asio/impl/read_until.hpp
+++ b/boost/asio/impl/read_until.hpp
@@ -2,7 +2,7 @@
// impl/read_until.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -29,6 +29,7 @@
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
#include <boost/asio/detail/limits.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -36,30 +37,75 @@
namespace boost {
namespace asio {
-template <typename SyncReadStream, typename DynamicBuffer>
+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
+
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v1>
inline std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers, char delim)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read_until(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), delim, ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);
boost::asio::detail::throw_error(ec, "read_until");
return bytes_transferred;
}
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- char delim, boost::system::error_code& ec)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ char delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
std::size_t search_position = 0;
for (;;)
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type buffers_type;
+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = b.data();
iterator begin = iterator::begin(data_buffers);
@@ -97,66 +143,39 @@ std::size_t read_until(SyncReadStream& s,
}
}
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
inline std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- BOOST_ASIO_STRING_VIEW_PARAM delim)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read_until(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), delim, ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim, ec);
boost::asio::detail::throw_error(ec, "read_until");
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 DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
std::size_t search_position = 0;
for (;;)
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type buffers_type;
+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = b.data();
iterator begin = iterator::begin(data_buffers);
@@ -206,31 +225,39 @@ std::size_t read_until(SyncReadStream& s,
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if defined(BOOST_ASIO_HAS_BOOST_REGEX)
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
inline std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- const boost::regex& expr)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const boost::regex& expr,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read_until(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers), expr, ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr, ec);
boost::asio::detail::throw_error(ec, "read_until");
return bytes_transferred;
}
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- const boost::regex& expr, boost::system::error_code& ec)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const boost::regex& expr, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
std::size_t search_position = 0;
for (;;)
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type buffers_type;
+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = b.data();
iterator begin = iterator::begin(data_buffers);
@@ -282,35 +309,43 @@ std::size_t read_until(SyncReadStream& s,
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
template <typename SyncReadStream,
- typename DynamicBuffer, typename MatchCondition>
+ typename DynamicBuffer_v1, typename MatchCondition>
inline std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition,
- typename enable_if<is_match_condition<MatchCondition>::value>::type*)
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = read_until(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
match_condition, ec);
boost::asio::detail::throw_error(ec, "read_until");
return bytes_transferred;
}
template <typename SyncReadStream,
- typename DynamicBuffer, typename MatchCondition>
+ typename DynamicBuffer_v1, typename MatchCondition>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition, boost::system::error_code& ec,
- typename enable_if<is_match_condition<MatchCondition>::value>::type*)
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
std::size_t search_position = 0;
for (;;)
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type buffers_type;
+ typedef typename DynamicBuffer_v1::const_buffers_type buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = b.data();
iterator begin = iterator::begin(data_buffers);
@@ -424,16 +459,332 @@ inline std::size_t read_until(SyncReadStream& s,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read_until(SyncReadStream& s,
+ DynamicBuffer_v2 buffers, char delim,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);
+ boost::asio::detail::throw_error(ec, "read_until");
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ char delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ DynamicBuffer_v2& b = buffers;
+
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ iterator iter = std::find(start_pos, 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 = std::min<std::size_t>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(65536, b.max_size() - b.size()));
+ std::size_t pos = b.size();
+ b.grow(bytes_to_read);
+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);
+ b.shrink(bytes_to_read - bytes_transferred);
+ if (ec)
+ return 0;
+ }
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read_until(SyncReadStream& s,
+ DynamicBuffer_v2 buffers, BOOST_ASIO_STRING_VIEW_PARAM delim,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim, ec);
+ boost::asio::detail::throw_error(ec, "read_until");
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ DynamicBuffer_v2& b = buffers;
+
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = detail::partial_search(
+ start_pos, 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 = std::min<std::size_t>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(65536, b.max_size() - b.size()));
+ std::size_t pos = b.size();
+ b.grow(bytes_to_read);
+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);
+ b.shrink(bytes_to_read - bytes_transferred);
+ if (ec)
+ return 0;
+ }
+}
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+#if defined(BOOST_ASIO_HAS_BOOST_REGEX)
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+inline std::size_t read_until(SyncReadStream& s,
+ DynamicBuffer_v2 buffers, const boost::regex& expr,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr, ec);
+ boost::asio::detail::throw_error(ec, "read_until");
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ const boost::regex& expr, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ DynamicBuffer_v2& b = buffers;
+
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ boost::match_results<iterator,
+ typename std::vector<boost::sub_match<iterator> >::allocator_type>
+ match_results;
+ if (regex_search(start_pos, 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 = std::min<std::size_t>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(65536, b.max_size() - b.size()));
+ std::size_t pos = b.size();
+ b.grow(bytes_to_read);
+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);
+ b.shrink(bytes_to_read - bytes_transferred);
+ if (ec)
+ return 0;
+ }
+}
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
+
+template <typename SyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition>
+inline std::size_t read_until(SyncReadStream& s,
+ DynamicBuffer_v2 buffers, MatchCondition match_condition,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = read_until(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ match_condition, ec);
+ boost::asio::detail::throw_error(ec, "read_until");
+ return bytes_transferred;
+}
+
+template <typename SyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ MatchCondition match_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ DynamicBuffer_v2& b = buffers;
+
+ std::size_t search_position = 0;
+ for (;;)
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(b).data(0, b.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = match_condition(start_pos, 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 = std::min<std::size_t>(
+ std::max<std::size_t>(512, b.capacity() - b.size()),
+ std::min<std::size_t>(65536, b.max_size() - b.size()));
+ std::size_t pos = b.size();
+ b.grow(bytes_to_read);
+ std::size_t bytes_transferred = s.read_some(b.data(pos, bytes_to_read), ec);
+ b.shrink(bytes_to_read - bytes_transferred);
+ if (ec)
+ return 0;
+ }
+}
+
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
namespace detail
{
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
- class read_until_delim_op
+ typename DynamicBuffer_v1, typename ReadHandler>
+ class read_until_delim_op_v1
{
public:
template <typename BufferSequence>
- read_until_delim_op(AsyncReadStream& stream,
+ read_until_delim_op_v1(AsyncReadStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
char delim, ReadHandler& handler)
: stream_(stream),
@@ -446,7 +797,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- read_until_delim_op(const read_until_delim_op& other)
+ read_until_delim_op_v1(const read_until_delim_op_v1& other)
: stream_(other.stream_),
buffers_(other.buffers_),
delim_(other.delim_),
@@ -456,9 +807,9 @@ namespace detail
{
}
- read_until_delim_op(read_until_delim_op&& other)
+ read_until_delim_op_v1(read_until_delim_op_v1&& other)
: stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
delim_(other.delim_),
start_(other.start_),
search_position_(other.search_position_),
@@ -479,7 +830,7 @@ namespace detail
{
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type
+ typedef typename DynamicBuffer_v1::const_buffers_type
buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = buffers_.data();
@@ -520,9 +871,9 @@ namespace detail
if (!start && bytes_to_read == 0)
break;
- // Start a new asynchronous read operation to obtain more data.
+ // Start a new asynchronous read op_v1eration to obtain more data.
stream_.async_read_some(buffers_.prepare(bytes_to_read),
- BOOST_ASIO_MOVE_CAST(read_until_delim_op)(*this));
+ BOOST_ASIO_MOVE_CAST(read_until_delim_op_v1)(*this));
return; default:
buffers_.commit(bytes_transferred);
if (ec || bytes_transferred == 0)
@@ -543,7 +894,7 @@ namespace detail
//private:
AsyncReadStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
char delim_;
int start_;
std::size_t search_position_;
@@ -551,30 +902,30 @@ namespace detail
};
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void* asio_handler_allocate(std::size_t size,
- read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline bool asio_handler_is_continuation(
- read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
return this_handler->start_ == 0 ? true
: boost_asio_handler_cont_helpers::is_continuation(
@@ -582,58 +933,79 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_invoke(Function& function,
- read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_invoke(const Function& function,
- read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_until_delim_v1
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v1>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ char delim) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_delim_op_v1<AsyncReadStream,
+ typename decay<DynamicBuffer_v1>::type,
+ typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ delim, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename ReadHandler, typename Allocator>
struct associated_allocator<
- detail::read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>,
+ detail::read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>,
Allocator>
{
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
static type get(
- const detail::read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>& h,
+ const detail::read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename ReadHandler, typename Executor>
struct associated_executor<
- detail::read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>,
+ detail::read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>,
Executor>
{
typedef typename associated_executor<ReadHandler, Executor>::type type;
static type get(
- const detail::read_until_delim_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>& h,
+ const detail::read_until_delim_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -643,39 +1015,32 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_until_delim_op<AsyncReadStream,
- typename decay<DynamicBuffer>::type,
- BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- delim, init.completion_handler)(boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_delim_v1(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), delim);
}
namespace detail
{
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
- class read_until_delim_string_op
+ typename DynamicBuffer_v1, typename ReadHandler>
+ class read_until_delim_string_op_v1
{
public:
template <typename BufferSequence>
- read_until_delim_string_op(AsyncReadStream& stream,
+ read_until_delim_string_op_v1(AsyncReadStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
const std::string& delim, ReadHandler& handler)
: stream_(stream),
@@ -688,7 +1053,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- read_until_delim_string_op(const read_until_delim_string_op& other)
+ read_until_delim_string_op_v1(const read_until_delim_string_op_v1& other)
: stream_(other.stream_),
buffers_(other.buffers_),
delim_(other.delim_),
@@ -698,9 +1063,9 @@ namespace detail
{
}
- read_until_delim_string_op(read_until_delim_string_op&& other)
+ read_until_delim_string_op_v1(read_until_delim_string_op_v1&& other)
: stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
delim_(BOOST_ASIO_MOVE_CAST(std::string)(other.delim_)),
start_(other.start_),
search_position_(other.search_position_),
@@ -721,7 +1086,7 @@ namespace detail
{
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type
+ typedef typename DynamicBuffer_v1::const_buffers_type
buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = buffers_.data();
@@ -773,9 +1138,9 @@ namespace detail
if (!start && bytes_to_read == 0)
break;
- // Start a new asynchronous read operation to obtain more data.
+ // Start a new asynchronous read op_v1eration to obtain more data.
stream_.async_read_some(buffers_.prepare(bytes_to_read),
- BOOST_ASIO_MOVE_CAST(read_until_delim_string_op)(*this));
+ BOOST_ASIO_MOVE_CAST(read_until_delim_string_op_v1)(*this));
return; default:
buffers_.commit(bytes_transferred);
if (ec || bytes_transferred == 0)
@@ -796,7 +1161,7 @@ namespace detail
//private:
AsyncReadStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
std::string delim_;
int start_;
std::size_t search_position_;
@@ -804,30 +1169,30 @@ namespace detail
};
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void* asio_handler_allocate(std::size_t size,
- read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline bool asio_handler_is_continuation(
- read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
return this_handler->start_ == 0 ? true
: boost_asio_handler_cont_helpers::is_continuation(
@@ -835,58 +1200,79 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_invoke(Function& function,
- read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
inline void asio_handler_invoke(const Function& function,
- read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>* this_handler)
+ read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_until_delim_string_v1
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v1>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const std::string& delim) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_delim_string_op_v1<AsyncReadStream,
+ typename decay<DynamicBuffer_v1>::type,
+ typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ delim, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename ReadHandler, typename Allocator>
struct associated_allocator<
- detail::read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>,
+ detail::read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>,
Allocator>
{
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
static type get(
- const detail::read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>& h,
+ const detail::read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename ReadHandler, typename Executor>
struct associated_executor<
- detail::read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>,
+ detail::read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>,
Executor>
{
typedef typename associated_executor<ReadHandler, Executor>::type type;
static type get(
- const detail::read_until_delim_string_op<AsyncReadStream,
- DynamicBuffer, ReadHandler>& h,
+ const detail::read_until_delim_string_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, ReadHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -896,30 +1282,23 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_STRING_VIEW_PARAM delim,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_until_delim_string_op<AsyncReadStream,
- typename decay<DynamicBuffer>::type,
- BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- static_cast<std::string>(delim),
- init.completion_handler)(boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_delim_string_v1(),
+ handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ static_cast<std::string>(delim));
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -927,13 +1306,13 @@ async_read_until(AsyncReadStream& s,
namespace detail
{
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler>
- class read_until_expr_op
+ class read_until_expr_op_v1
{
public:
template <typename BufferSequence>
- read_until_expr_op(AsyncReadStream& stream,
+ read_until_expr_op_v1(AsyncReadStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
const boost::regex& expr, ReadHandler& handler)
: stream_(stream),
@@ -946,7 +1325,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- read_until_expr_op(const read_until_expr_op& other)
+ read_until_expr_op_v1(const read_until_expr_op_v1& other)
: stream_(other.stream_),
buffers_(other.buffers_),
expr_(other.expr_),
@@ -956,9 +1335,9 @@ namespace detail
{
}
- read_until_expr_op(read_until_expr_op&& other)
+ read_until_expr_op_v1(read_until_expr_op_v1&& other)
: stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
expr_(other.expr_),
start_(other.start_),
search_position_(other.search_position_),
@@ -979,7 +1358,7 @@ namespace detail
{
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type
+ typedef typename DynamicBuffer_v1::const_buffers_type
buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = buffers_.data();
@@ -1034,9 +1413,9 @@ namespace detail
if (!start && bytes_to_read == 0)
break;
- // Start a new asynchronous read operation to obtain more data.
+ // Start a new asynchronous read op_v1eration to obtain more data.
stream_.async_read_some(buffers_.prepare(bytes_to_read),
- BOOST_ASIO_MOVE_CAST(read_until_expr_op)(*this));
+ BOOST_ASIO_MOVE_CAST(read_until_expr_op_v1)(*this));
return; default:
buffers_.commit(bytes_transferred);
if (ec || bytes_transferred == 0)
@@ -1057,38 +1436,38 @@ namespace detail
//private:
AsyncReadStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
RegEx expr_;
int start_;
std::size_t search_position_;
ReadHandler handler_;
};
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler>
inline void* asio_handler_allocate(std::size_t size,
- read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>* this_handler)
+ read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>* this_handler)
+ read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler>
inline bool asio_handler_is_continuation(
- read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>* this_handler)
+ read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)
{
return this_handler->start_ == 0 ? true
: boost_asio_handler_cont_helpers::is_continuation(
@@ -1096,58 +1475,79 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename RegEx, typename ReadHandler>
+ typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>
inline void asio_handler_invoke(Function& function,
- read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>* this_handler)
+ read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename RegEx, typename ReadHandler>
+ typename DynamicBuffer_v1, typename RegEx, typename ReadHandler>
inline void asio_handler_invoke(const Function& function,
- read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>* this_handler)
+ read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_until_expr_v1
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v1, typename RegEx>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const RegEx& expr) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_expr_op_v1<AsyncReadStream,
+ typename decay<DynamicBuffer_v1>::type,
+ RegEx, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ expr, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler, typename Allocator>
struct associated_allocator<
- detail::read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>,
+ detail::read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>,
Allocator>
{
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
static type get(
- const detail::read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>& h,
+ const detail::read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename RegEx, typename ReadHandler, typename Executor>
struct associated_executor<
- detail::read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>,
+ detail::read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>,
Executor>
{
typedef typename associated_executor<ReadHandler, Executor>::type type;
static type get(
- const detail::read_until_expr_op<AsyncReadStream,
- DynamicBuffer, RegEx, ReadHandler>& h,
+ const detail::read_until_expr_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, RegEx, ReadHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -1157,42 +1557,35 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
const boost::regex& expr,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_until_expr_op<AsyncReadStream,
- typename decay<DynamicBuffer>::type,
- boost::regex, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- expr, init.completion_handler)(boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_expr_v1(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), expr);
}
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
namespace detail
{
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
- class read_until_match_op
+ class read_until_match_op_v1
{
public:
template <typename BufferSequence>
- read_until_match_op(AsyncReadStream& stream,
+ read_until_match_op_v1(AsyncReadStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
MatchCondition match_condition, ReadHandler& handler)
: stream_(stream),
@@ -1205,7 +1598,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- read_until_match_op(const read_until_match_op& other)
+ read_until_match_op_v1(const read_until_match_op_v1& other)
: stream_(other.stream_),
buffers_(other.buffers_),
match_condition_(other.match_condition_),
@@ -1215,9 +1608,9 @@ namespace detail
{
}
- read_until_match_op(read_until_match_op&& other)
+ read_until_match_op_v1(read_until_match_op_v1&& other)
: stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
match_condition_(other.match_condition_),
start_(other.start_),
search_position_(other.search_position_),
@@ -1238,7 +1631,7 @@ namespace detail
{
{
// Determine the range of the data to be searched.
- typedef typename DynamicBuffer::const_buffers_type
+ typedef typename DynamicBuffer_v1::const_buffers_type
buffers_type;
typedef buffers_iterator<buffers_type> iterator;
buffers_type data_buffers = buffers_.data();
@@ -1289,9 +1682,9 @@ namespace detail
if (!start && bytes_to_read == 0)
break;
- // Start a new asynchronous read operation to obtain more data.
+ // Start a new asynchronous read op_v1eration to obtain more data.
stream_.async_read_some(buffers_.prepare(bytes_to_read),
- BOOST_ASIO_MOVE_CAST(read_until_match_op)(*this));
+ BOOST_ASIO_MOVE_CAST(read_until_match_op_v1)(*this));
return; default:
buffers_.commit(bytes_transferred);
if (ec || bytes_transferred == 0)
@@ -1312,37 +1705,37 @@ namespace detail
//private:
AsyncReadStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
MatchCondition match_condition_;
int start_;
std::size_t search_position_;
ReadHandler handler_;
};
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
inline void* asio_handler_allocate(std::size_t size,
- read_until_match_op<AsyncReadStream, DynamicBuffer,
+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,
MatchCondition, ReadHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- read_until_match_op<AsyncReadStream, DynamicBuffer,
+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,
MatchCondition, ReadHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename AsyncReadStream, typename DynamicBuffer,
+ template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
inline bool asio_handler_is_continuation(
- read_until_match_op<AsyncReadStream, DynamicBuffer,
+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,
MatchCondition, ReadHandler>* this_handler)
{
return this_handler->start_ == 0 ? true
@@ -1351,10 +1744,10 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename MatchCondition,
+ typename DynamicBuffer_v1, typename MatchCondition,
typename ReadHandler>
inline void asio_handler_invoke(Function& function,
- read_until_match_op<AsyncReadStream, DynamicBuffer,
+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,
MatchCondition, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
@@ -1362,49 +1755,70 @@ namespace detail
}
template <typename Function, typename AsyncReadStream,
- typename DynamicBuffer, typename MatchCondition,
+ typename DynamicBuffer_v1, typename MatchCondition,
typename ReadHandler>
inline void asio_handler_invoke(const Function& function,
- read_until_match_op<AsyncReadStream, DynamicBuffer,
+ read_until_match_op_v1<AsyncReadStream, DynamicBuffer_v1,
MatchCondition, ReadHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_read_until_match_v1
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v1, typename MatchCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ MatchCondition match_condition) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_match_op_v1<AsyncReadStream,
+ typename decay<DynamicBuffer_v1>::type,
+ MatchCondition, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ match_condition, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler, typename Allocator>
struct associated_allocator<
- detail::read_until_match_op<AsyncReadStream,
- DynamicBuffer, MatchCondition, ReadHandler>,
+ detail::read_until_match_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, MatchCondition, ReadHandler>,
Allocator>
{
typedef typename associated_allocator<ReadHandler, Allocator>::type type;
static type get(
- const detail::read_until_match_op<AsyncReadStream,
- DynamicBuffer, MatchCondition, ReadHandler>& h,
+ const detail::read_until_match_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, MatchCondition, ReadHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler, typename Executor>
struct associated_executor<
- detail::read_until_match_op<AsyncReadStream,
- DynamicBuffer, MatchCondition, ReadHandler>,
+ detail::read_until_match_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, MatchCondition, ReadHandler>,
Executor>
{
typedef typename associated_executor<ReadHandler, Executor>::type type;
static type get(
- const detail::read_until_match_op<AsyncReadStream,
- DynamicBuffer, MatchCondition, ReadHandler>& h,
+ const detail::read_until_match_op_v1<AsyncReadStream,
+ DynamicBuffer_v1, MatchCondition, ReadHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
@@ -1413,31 +1827,23 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
- typename enable_if<is_match_condition<MatchCondition>::value>::type*)
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::read_until_match_op<AsyncReadStream,
- typename decay<DynamicBuffer>::type,
- MatchCondition, BOOST_ASIO_HANDLER_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- match_condition, init.completion_handler)(
- boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_match_v1(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers), match_condition);
}
#if !defined(BOOST_ASIO_NO_IOSTREAM)
@@ -1495,6 +1901,1102 @@ async_read_until(AsyncReadStream& s,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+namespace detail
+{
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ class read_until_delim_op_v2
+ {
+ public:
+ template <typename BufferSequence>
+ read_until_delim_op_v2(AsyncReadStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ char delim, ReadHandler& handler)
+ : stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ delim_(delim),
+ start_(0),
+ search_position_(0),
+ bytes_to_read_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ read_until_delim_op_v2(const read_until_delim_op_v2& other)
+ : stream_(other.stream_),
+ buffers_(other.buffers_),
+ delim_(other.delim_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(other.handler_)
+ {
+ }
+
+ read_until_delim_op_v2(read_until_delim_op_v2&& other)
+ : stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ delim_(other.delim_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ 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 pos;
+ switch (start_ = start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type
+ buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(buffers_).data(
+ 0, buffers_.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position_;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ iterator iter = std::find(start_pos, 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 (buffers_.size() == buffers_.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_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(65536,
+ buffers_.max_size() - buffers_.size()));
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read_ == 0)
+ break;
+
+ // Start a new asynchronous read op_v2eration to obtain more data.
+ pos = buffers_.size();
+ buffers_.grow(bytes_to_read_);
+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),
+ BOOST_ASIO_MOVE_CAST(read_until_delim_op_v2)(*this));
+ return; default:
+ buffers_.shrink(bytes_to_read_ - bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ const boost::system::error_code result_ec =
+ (search_position_ == not_found)
+ ? error::not_found : ec;
+
+ const std::size_t result_n =
+ (ec || search_position_ == not_found)
+ ? 0 : search_position_;
+
+ handler_(result_ec, result_n);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ char delim_;
+ int start_;
+ std::size_t search_position_;
+ std::size_t bytes_to_read_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline bool asio_handler_is_continuation(
+ read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ return this_handler->start_ == 0 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_invoke(Function& function,
+ read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_read_until_delim_v2
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v2>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ char delim) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_delim_op_v2<AsyncReadStream,
+ typename decay<DynamicBuffer_v2>::type,
+ typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ delim, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename ReadHandler, typename Allocator>
+struct associated_allocator<
+ detail::read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+ static type get(
+ const detail::read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename ReadHandler, typename Executor>
+struct associated_executor<
+ detail::read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>,
+ Executor>
+{
+ typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+ static type get(
+ const detail::read_until_delim_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_delim_v2(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), delim);
+}
+
+namespace detail
+{
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ class read_until_delim_string_op_v2
+ {
+ public:
+ template <typename BufferSequence>
+ read_until_delim_string_op_v2(AsyncReadStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ const std::string& delim, ReadHandler& handler)
+ : stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ delim_(delim),
+ start_(0),
+ search_position_(0),
+ bytes_to_read_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ read_until_delim_string_op_v2(const read_until_delim_string_op_v2& other)
+ : stream_(other.stream_),
+ buffers_(other.buffers_),
+ delim_(other.delim_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(other.handler_)
+ {
+ }
+
+ read_until_delim_string_op_v2(read_until_delim_string_op_v2&& other)
+ : stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ delim_(BOOST_ASIO_MOVE_CAST(std::string)(other.delim_)),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ 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 pos;
+ switch (start_ = start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type
+ buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(buffers_).data(
+ 0, buffers_.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position_;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = detail::partial_search(
+ start_pos, 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 (buffers_.size() == buffers_.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_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(65536,
+ buffers_.max_size() - buffers_.size()));
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read_ == 0)
+ break;
+
+ // Start a new asynchronous read op_v2eration to obtain more data.
+ pos = buffers_.size();
+ buffers_.grow(bytes_to_read_);
+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),
+ BOOST_ASIO_MOVE_CAST(read_until_delim_string_op_v2)(*this));
+ return; default:
+ buffers_.shrink(bytes_to_read_ - bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ const boost::system::error_code result_ec =
+ (search_position_ == not_found)
+ ? error::not_found : ec;
+
+ const std::size_t result_n =
+ (ec || search_position_ == not_found)
+ ? 0 : search_position_;
+
+ handler_(result_ec, result_n);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ std::string delim_;
+ int start_;
+ std::size_t search_position_;
+ std::size_t bytes_to_read_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline bool asio_handler_is_continuation(
+ read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ return this_handler->start_ == 0 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_invoke(Function& function,
+ read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_read_until_delim_string_v2
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v2>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ const std::string& delim) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_delim_string_op_v2<AsyncReadStream,
+ typename decay<DynamicBuffer_v2>::type,
+ typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ delim, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename ReadHandler, typename Allocator>
+struct associated_allocator<
+ detail::read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+ static type get(
+ const detail::read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename ReadHandler, typename Executor>
+struct associated_executor<
+ detail::read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>,
+ Executor>
+{
+ typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+ static type get(
+ const detail::read_until_delim_string_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, ReadHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s,
+ DynamicBuffer_v2 buffers, BOOST_ASIO_STRING_VIEW_PARAM delim,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_delim_string_v2(),
+ handler, &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ static_cast<std::string>(delim));
+}
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+#if defined(BOOST_ASIO_HAS_BOOST_REGEX)
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler>
+ class read_until_expr_op_v2
+ {
+ public:
+ template <typename BufferSequence>
+ read_until_expr_op_v2(AsyncReadStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ const boost::regex& expr, ReadHandler& handler)
+ : stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ expr_(expr),
+ start_(0),
+ search_position_(0),
+ bytes_to_read_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ read_until_expr_op_v2(const read_until_expr_op_v2& other)
+ : stream_(other.stream_),
+ buffers_(other.buffers_),
+ expr_(other.expr_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(other.handler_)
+ {
+ }
+
+ read_until_expr_op_v2(read_until_expr_op_v2&& other)
+ : stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ expr_(other.expr_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ 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 pos;
+ switch (start_ = start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type
+ buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(buffers_).data(
+ 0, buffers_.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position_;
+ iterator end = iterator::end(data_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_pos, 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 (buffers_.size() == buffers_.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_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(65536,
+ buffers_.max_size() - buffers_.size()));
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read_ == 0)
+ break;
+
+ // Start a new asynchronous read op_v2eration to obtain more data.
+ pos = buffers_.size();
+ buffers_.grow(bytes_to_read_);
+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),
+ BOOST_ASIO_MOVE_CAST(read_until_expr_op_v2)(*this));
+ return; default:
+ buffers_.shrink(bytes_to_read_ - bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ const boost::system::error_code result_ec =
+ (search_position_ == not_found)
+ ? error::not_found : ec;
+
+ const std::size_t result_n =
+ (ec || search_position_ == not_found)
+ ? 0 : search_position_;
+
+ handler_(result_ec, result_n);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ RegEx expr_;
+ int start_;
+ std::size_t search_position_;
+ std::size_t bytes_to_read_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler>
+ inline bool asio_handler_is_continuation(
+ read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)
+ {
+ return this_handler->start_ == 0 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>
+ inline void asio_handler_invoke(Function& function,
+ read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename RegEx, typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_read_until_expr_v2
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename RegEx>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ const RegEx& expr) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_expr_op_v2<AsyncReadStream,
+ typename decay<DynamicBuffer_v2>::type,
+ RegEx, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ expr, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler, typename Allocator>
+struct associated_allocator<
+ detail::read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+ static type get(
+ const detail::read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename RegEx, typename ReadHandler, typename Executor>
+struct associated_executor<
+ detail::read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>,
+ Executor>
+{
+ typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+ static type get(
+ const detail::read_until_expr_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, RegEx, ReadHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ const boost::regex& expr, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_expr_v2(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), expr);
+}
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
+
+namespace detail
+{
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+ class read_until_match_op_v2
+ {
+ public:
+ template <typename BufferSequence>
+ read_until_match_op_v2(AsyncReadStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ MatchCondition match_condition, ReadHandler& handler)
+ : stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ match_condition_(match_condition),
+ start_(0),
+ search_position_(0),
+ bytes_to_read_(0),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ read_until_match_op_v2(const read_until_match_op_v2& other)
+ : stream_(other.stream_),
+ buffers_(other.buffers_),
+ match_condition_(other.match_condition_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(other.handler_)
+ {
+ }
+
+ read_until_match_op_v2(read_until_match_op_v2&& other)
+ : stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ match_condition_(other.match_condition_),
+ start_(other.start_),
+ search_position_(other.search_position_),
+ bytes_to_read_(other.bytes_to_read_),
+ handler_(BOOST_ASIO_MOVE_CAST(ReadHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ 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 pos;
+ switch (start_ = start)
+ {
+ case 1:
+ for (;;)
+ {
+ {
+ // Determine the range of the data to be searched.
+ typedef typename DynamicBuffer_v2::const_buffers_type
+ buffers_type;
+ typedef buffers_iterator<buffers_type> iterator;
+ buffers_type data_buffers =
+ const_cast<const DynamicBuffer_v2&>(buffers_).data(
+ 0, buffers_.size());
+ iterator begin = iterator::begin(data_buffers);
+ iterator start_pos = begin + search_position_;
+ iterator end = iterator::end(data_buffers);
+
+ // Look for a match.
+ std::pair<iterator, bool> result = match_condition_(start_pos, 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 (buffers_.size() == buffers_.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_ = std::min<std::size_t>(
+ std::max<std::size_t>(512,
+ buffers_.capacity() - buffers_.size()),
+ std::min<std::size_t>(65536,
+ buffers_.max_size() - buffers_.size()));
+ }
+ }
+
+ // Check if we're done.
+ if (!start && bytes_to_read_ == 0)
+ break;
+
+ // Start a new asynchronous read op_v2eration to obtain more data.
+ pos = buffers_.size();
+ buffers_.grow(bytes_to_read_);
+ stream_.async_read_some(buffers_.data(pos, bytes_to_read_),
+ BOOST_ASIO_MOVE_CAST(read_until_match_op_v2)(*this));
+ return; default:
+ buffers_.shrink(bytes_to_read_ - bytes_transferred);
+ if (ec || bytes_transferred == 0)
+ break;
+ }
+
+ const boost::system::error_code result_ec =
+ (search_position_ == not_found)
+ ? error::not_found : ec;
+
+ const std::size_t result_n =
+ (ec || search_position_ == not_found)
+ ? 0 : search_position_;
+
+ handler_(result_ec, result_n);
+ }
+ }
+
+ //private:
+ AsyncReadStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ MatchCondition match_condition_;
+ int start_;
+ std::size_t search_position_;
+ std::size_t bytes_to_read_;
+ ReadHandler handler_;
+ };
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,
+ MatchCondition, ReadHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,
+ MatchCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+ inline bool asio_handler_is_continuation(
+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,
+ MatchCondition, ReadHandler>* this_handler)
+ {
+ return this_handler->start_ == 0 ? true
+ : boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(Function& function,
+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,
+ MatchCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition,
+ typename ReadHandler>
+ inline void asio_handler_invoke(const Function& function,
+ read_until_match_op_v2<AsyncReadStream, DynamicBuffer_v2,
+ MatchCondition, ReadHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_read_until_match_v2
+ {
+ template <typename ReadHandler, typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ AsyncReadStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ MatchCondition match_condition) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ non_const_lvalue<ReadHandler> handler2(handler);
+ read_until_match_op_v2<AsyncReadStream,
+ typename decay<DynamicBuffer_v2>::type,
+ MatchCondition, typename decay<ReadHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ match_condition, handler2.value)(boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler, typename Allocator>
+struct associated_allocator<
+ detail::read_until_match_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, MatchCondition, ReadHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<ReadHandler, Allocator>::type type;
+
+ static type get(
+ const detail::read_until_match_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, MatchCondition, ReadHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<ReadHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler, typename Executor>
+struct associated_executor<
+ detail::read_until_match_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, MatchCondition, ReadHandler>,
+ Executor>
+{
+ typedef typename associated_executor<ReadHandler, Executor>::type type;
+
+ static type get(
+ const detail::read_until_match_op_v2<AsyncReadStream,
+ DynamicBuffer_v2, MatchCondition, ReadHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<ReadHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_read_until_match_v2(), handler,
+ &s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers), match_condition);
+}
+
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
} // namespace asio
} // namespace boost
diff --git a/boost/asio/experimental/impl/redirect_error.hpp b/boost/asio/impl/redirect_error.hpp
index 00ffcc7848..eb0d82998a 100644
--- a/boost/asio/experimental/impl/redirect_error.hpp
+++ b/boost/asio/impl/redirect_error.hpp
@@ -1,15 +1,15 @@
+
+// impl/redirect_error.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// experimental/impl/redirect_error.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP
-#define BOOST_ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP
+#ifndef BOOST_ASIO_IMPL_REDIRECT_ERROR_HPP
+#define BOOST_ASIO_IMPL_REDIRECT_ERROR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -24,14 +24,12 @@
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/detail/variadic_templates.hpp>
-#include <boost/asio/handler_type.hpp>
#include <boost/system/system_error.hpp>
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
-namespace experimental {
namespace detail {
// Class to adapt a redirect_error_t as a completion handler.
@@ -39,6 +37,8 @@ template <typename Handler>
class redirect_error_handler
{
public:
+ typedef void result_type;
+
template <typename CompletionToken>
redirect_error_handler(redirect_error_t<CompletionToken> e)
: ec_(e.ec_),
@@ -46,6 +46,14 @@ public:
{
}
+ template <typename RedirectedHandler>
+ redirect_error_handler(boost::system::error_code& ec,
+ BOOST_ASIO_MOVE_ARG(RedirectedHandler) h)
+ : ec_(ec),
+ handler_(BOOST_ASIO_MOVE_CAST(RedirectedHandler)(h))
+ {
+ }
+
void operator()()
{
handler_();
@@ -212,60 +220,131 @@ struct redirect_error_signature<R(const boost::system::error_code&)>
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
} // namespace detail
-} // namespace experimental
#if !defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature>
-struct async_result<experimental::redirect_error_t<CompletionToken>, Signature>
- : async_result<CompletionToken,
- typename experimental::detail::redirect_error_signature<Signature>::type>
+struct async_result<redirect_error_t<CompletionToken>, Signature>
{
- typedef experimental::detail::redirect_error_handler<
- typename async_result<CompletionToken,
- typename experimental::detail::redirect_error_signature<Signature>::type>
- ::completion_handler_type> completion_handler_type;
-
- explicit async_result(completion_handler_type& h)
- : async_result<CompletionToken,
- typename experimental::detail::redirect_error_signature<
- Signature>::type>(h.handler_)
+ typedef typename async_result<CompletionToken,
+ typename detail::redirect_error_signature<Signature>::type>
+ ::return_type return_type;
+
+ template <typename Initiation>
+ struct init_wrapper
{
- }
-};
+ template <typename Init>
+ init_wrapper(boost::system::error_code& ec, BOOST_ASIO_MOVE_ARG(Init) init)
+ : ec_(ec),
+ initiation_(BOOST_ASIO_MOVE_CAST(Init)(init))
+ {
+ }
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-template <typename CompletionToken, typename Signature>
-struct handler_type<experimental::redirect_error_t<CompletionToken>, Signature>
-{
- typedef experimental::detail::redirect_error_handler<
- typename async_result<CompletionToken,
- typename experimental::detail::redirect_error_signature<Signature>::type>
- ::completion_handler_type> type;
-};
+ template <typename Handler, typename... Args>
+ void operator()(
+ BOOST_ASIO_MOVE_ARG(Handler) handler,
+ BOOST_ASIO_MOVE_ARG(Args)... args)
+ {
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
+ detail::redirect_error_handler<
+ typename decay<Handler>::type>(
+ ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)),
+ BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
-template <typename Handler>
-struct async_result<experimental::detail::redirect_error_handler<Handler> >
- : async_result<Handler>
-{
- explicit async_result(
- experimental::detail::redirect_error_handler<Handler>& h)
- : async_result<Handler>(h.handler_)
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Handler>
+ void operator()(
+ BOOST_ASIO_MOVE_ARG(Handler) handler)
+ {
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)(
+ detail::redirect_error_handler<
+ typename decay<Handler>::type>(
+ ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)));
+ }
+
+#define BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF(n) \
+ template <typename Handler, BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ void operator()( \
+ BOOST_ASIO_MOVE_ARG(Handler) handler, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ BOOST_ASIO_MOVE_CAST(Initiation)(initiation_)( \
+ detail::redirect_error_handler< \
+ typename decay<Handler>::type>( \
+ ec_, BOOST_ASIO_MOVE_CAST(Handler)(handler)), \
+ BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF)
+#undef BOOST_ASIO_PRIVATE_INIT_WRAPPER_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ boost::system::error_code& ec_;
+ Initiation initiation_;
+ };
+
+#if defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Initiation, typename RawCompletionToken, typename... Args>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token,
+ BOOST_ASIO_MOVE_ARG(Args)... args)
{
+ return async_initiate<CompletionToken,
+ typename detail::redirect_error_signature<Signature>::type>(
+ init_wrapper<typename decay<Initiation>::type>(
+ token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
+ token.token_, BOOST_ASIO_MOVE_CAST(Args)(args)...);
+ }
+
+#else // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+
+ template <typename Initiation, typename RawCompletionToken>
+ static return_type initiate(
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation,
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token)
+ {
+ return async_initiate<CompletionToken,
+ typename detail::redirect_error_signature<Signature>::type>(
+ init_wrapper<typename decay<Initiation>::type>(
+ token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)),
+ token.token_);
}
-};
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+#define BOOST_ASIO_PRIVATE_INITIATE_DEF(n) \
+ template <typename Initiation, typename RawCompletionToken, \
+ BOOST_ASIO_VARIADIC_TPARAMS(n)> \
+ static return_type initiate( \
+ BOOST_ASIO_MOVE_ARG(Initiation) initiation, \
+ BOOST_ASIO_MOVE_ARG(RawCompletionToken) token, \
+ BOOST_ASIO_VARIADIC_MOVE_PARAMS(n)) \
+ { \
+ return async_initiate<CompletionToken, \
+ typename detail::redirect_error_signature<Signature>::type>( \
+ init_wrapper<typename decay<Initiation>::type>( \
+ token.ec_, BOOST_ASIO_MOVE_CAST(Initiation)(initiation)), \
+ token.token_, BOOST_ASIO_VARIADIC_MOVE_ARGS(n)); \
+ } \
+ /**/
+ BOOST_ASIO_VARIADIC_GENERATE(BOOST_ASIO_PRIVATE_INITIATE_DEF)
+#undef BOOST_ASIO_PRIVATE_INITIATE_DEF
+
+#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
+};
template <typename Handler, typename Executor>
-struct associated_executor<
- experimental::detail::redirect_error_handler<Handler>, Executor>
+struct associated_executor<detail::redirect_error_handler<Handler>, Executor>
{
typedef typename associated_executor<Handler, Executor>::type type;
static type get(
- const experimental::detail::redirect_error_handler<Handler>& h,
+ const detail::redirect_error_handler<Handler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<Handler, Executor>::get(h.handler_, ex);
@@ -273,13 +352,12 @@ struct associated_executor<
};
template <typename Handler, typename Allocator>
-struct associated_allocator<
- experimental::detail::redirect_error_handler<Handler>, Allocator>
+struct associated_allocator<detail::redirect_error_handler<Handler>, Allocator>
{
typedef typename associated_allocator<Handler, Allocator>::type type;
static type get(
- const experimental::detail::redirect_error_handler<Handler>& h,
+ const detail::redirect_error_handler<Handler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<Handler, Allocator>::get(h.handler_, a);
@@ -293,4 +371,4 @@ struct associated_allocator<
#include <boost/asio/detail/pop_options.hpp>
-#endif // BOOST_ASIO_EXPERIMENTAL_IMPL_REDIRECT_ERROR_HPP
+#endif // BOOST_ASIO_IMPL_REDIRECT_ERROR_HPP
diff --git a/boost/asio/impl/serial_port_base.hpp b/boost/asio/impl/serial_port_base.hpp
index 7f2dfe88df..c456e30800 100644
--- a/boost/asio/impl/serial_port_base.hpp
+++ b/boost/asio/impl/serial_port_base.hpp
@@ -2,7 +2,7 @@
// impl/serial_port_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/impl/serial_port_base.ipp b/boost/asio/impl/serial_port_base.ipp
index 9954f77d2e..c7ff51876a 100644
--- a/boost/asio/impl/serial_port_base.ipp
+++ b/boost/asio/impl/serial_port_base.ipp
@@ -2,7 +2,7 @@
// impl/serial_port_base.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/impl/spawn.hpp b/boost/asio/impl/spawn.hpp
index c2da5ce09a..cf4ce5622f 100644
--- a/boost/asio/impl/spawn.hpp
+++ b/boost/asio/impl/spawn.hpp
@@ -2,7 +2,7 @@
// impl/spawn.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -278,51 +278,6 @@ public:
}
};
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_yield_context<Handler>, ReturnType()>
-{
- typedef detail::coro_handler<Handler, void> type;
-};
-
-template <typename Handler, typename ReturnType, typename Arg1>
-struct handler_type<basic_yield_context<Handler>, ReturnType(Arg1)>
-{
- typedef detail::coro_handler<Handler, typename decay<Arg1>::type> type;
-};
-
-template <typename Handler, typename ReturnType>
-struct handler_type<basic_yield_context<Handler>,
- ReturnType(boost::system::error_code)>
-{
- typedef detail::coro_handler<Handler, void> type;
-};
-
-template <typename Handler, typename ReturnType, typename Arg2>
-struct handler_type<basic_yield_context<Handler>,
- ReturnType(boost::system::error_code, Arg2)>
-{
- typedef detail::coro_handler<Handler, typename decay<Arg2>::type> type;
-};
-
-template <typename Handler, typename T>
-class async_result<detail::coro_handler<Handler, T> >
- : public detail::coro_async_result<Handler, T>
-{
-public:
- typedef typename detail::coro_async_result<Handler, T>::return_type type;
-
- explicit async_result(
- typename detail::coro_async_result<Handler,
- T>::completion_handler_type& h)
- : detail::coro_async_result<Handler, T>(h)
- {
- }
-};
-
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
template <typename Handler, typename T, typename Allocator>
struct associated_allocator<detail::coro_handler<Handler, T>, Allocator>
{
diff --git a/boost/asio/impl/src.cpp b/boost/asio/impl/src.cpp
index 3823acfaf3..8f43dbf0ca 100644
--- a/boost/asio/impl/src.cpp
+++ b/boost/asio/impl/src.cpp
@@ -2,7 +2,7 @@
// impl/src.cpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/src.hpp b/boost/asio/impl/src.hpp
index b891a453fe..7f155ad25c 100644
--- a/boost/asio/impl/src.hpp
+++ b/boost/asio/impl/src.hpp
@@ -2,7 +2,7 @@
// impl/src.hpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/system_context.hpp b/boost/asio/impl/system_context.hpp
index dab5d4d085..2a6b61f312 100644
--- a/boost/asio/impl/system_context.hpp
+++ b/boost/asio/impl/system_context.hpp
@@ -2,7 +2,7 @@
// impl/system_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/system_context.ipp b/boost/asio/impl/system_context.ipp
index e56632c816..0ec6fad171 100644
--- a/boost/asio/impl/system_context.ipp
+++ b/boost/asio/impl/system_context.ipp
@@ -2,7 +2,7 @@
// impl/system_context.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,7 +35,7 @@ struct system_context::thread_function
};
system_context::system_context()
- : scheduler_(use_service<detail::scheduler>(*this))
+ : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))
{
scheduler_.work_started();
@@ -67,6 +67,13 @@ void system_context::join()
threads_.join();
}
+detail::scheduler& system_context::add_scheduler(detail::scheduler* s)
+{
+ detail::scoped_ptr<detail::scheduler> scoped_impl(s);
+ boost::asio::add_service<detail::scheduler>(*this, scoped_impl.get());
+ return *scoped_impl.release();
+}
+
} // namespace asio
} // namespace boost
diff --git a/boost/asio/impl/system_executor.hpp b/boost/asio/impl/system_executor.hpp
index c59e780d3f..25c51a6560 100644
--- a/boost/asio/impl/system_executor.hpp
+++ b/boost/asio/impl/system_executor.hpp
@@ -2,7 +2,7 @@
// impl/system_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/thread_pool.hpp b/boost/asio/impl/thread_pool.hpp
index ed8d768cd0..31d8b37ee0 100644
--- a/boost/asio/impl/thread_pool.hpp
+++ b/boost/asio/impl/thread_pool.hpp
@@ -2,7 +2,7 @@
// impl/thread_pool.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/impl/thread_pool.ipp b/boost/asio/impl/thread_pool.ipp
index e0952eb657..d59b6ef15f 100644
--- a/boost/asio/impl/thread_pool.ipp
+++ b/boost/asio/impl/thread_pool.ipp
@@ -2,7 +2,7 @@
// impl/thread_pool.ipp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -35,7 +35,7 @@ struct thread_pool::thread_function
};
thread_pool::thread_pool()
- : scheduler_(use_service<detail::scheduler>(*this))
+ : scheduler_(add_scheduler(new detail::scheduler(*this, 0, false)))
{
scheduler_.work_started();
@@ -45,7 +45,8 @@ thread_pool::thread_pool()
}
thread_pool::thread_pool(std::size_t num_threads)
- : scheduler_(use_service<detail::scheduler>(*this))
+ : scheduler_(add_scheduler(new detail::scheduler(
+ *this, num_threads == 1 ? 1 : 0, false)))
{
scheduler_.work_started();
@@ -66,8 +67,18 @@ void thread_pool::stop()
void thread_pool::join()
{
- scheduler_.work_finished();
- threads_.join();
+ if (!threads_.empty())
+ {
+ scheduler_.work_finished();
+ threads_.join();
+ }
+}
+
+detail::scheduler& thread_pool::add_scheduler(detail::scheduler* s)
+{
+ detail::scoped_ptr<detail::scheduler> scoped_impl(s);
+ boost::asio::add_service<detail::scheduler>(*this, scoped_impl.get());
+ return *scoped_impl.release();
}
} // namespace asio
diff --git a/boost/asio/impl/use_awaitable.hpp b/boost/asio/impl/use_awaitable.hpp
new file mode 100644
index 0000000000..0d7ad0a42b
--- /dev/null
+++ b/boost/asio/impl/use_awaitable.hpp
@@ -0,0 +1,278 @@
+//
+// impl/use_awaitable.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_USE_AWAITABLE_HPP
+#define BOOST_ASIO_IMPL_USE_AWAITABLE_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/async_result.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace detail {
+
+template <typename Executor, typename T>
+class awaitable_handler_base
+ : public awaitable_thread<Executor>
+{
+public:
+ typedef void result_type;
+ typedef awaitable<T, Executor> awaitable_type;
+
+ // Construct from the entry point of a new thread of execution.
+ awaitable_handler_base(awaitable<void, Executor> a, const Executor& ex)
+ : awaitable_thread<Executor>(std::move(a), ex)
+ {
+ }
+
+ // Transfer ownership from another awaitable_thread.
+ explicit awaitable_handler_base(awaitable_thread<Executor>* h)
+ : awaitable_thread<Executor>(std::move(*h))
+ {
+ }
+
+protected:
+ awaitable_frame<T, Executor>* frame() noexcept
+ {
+ return static_cast<awaitable_frame<T, Executor>*>(this->top_of_stack_);
+ }
+};
+
+template <typename, typename...>
+class awaitable_handler;
+
+template <typename Executor>
+class awaitable_handler<Executor, void>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()()
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_void();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor>
+class awaitable_handler<Executor, boost::system::error_code>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()(const boost::system::error_code& ec)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_void();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor>
+class awaitable_handler<Executor, std::exception_ptr>
+ : public awaitable_handler_base<Executor, void>
+{
+public:
+ using awaitable_handler_base<Executor, void>::awaitable_handler_base;
+
+ void operator()(std::exception_ptr ex)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_void();
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, boost::system::error_code, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(const boost::system::error_code& ec, Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename T>
+class awaitable_handler<Executor, std::exception_ptr, T>
+ : public awaitable_handler_base<Executor, T>
+{
+public:
+ using awaitable_handler_base<Executor, T>::awaitable_handler_base;
+
+ template <typename Arg>
+ void operator()(std::exception_ptr ex, Arg&& arg)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_value(std::forward<Arg>(arg));
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler<Executor, boost::system::error_code, Ts...>
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(const boost::system::error_code& ec, Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ if (ec)
+ this->frame()->set_error(ec);
+ else
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+template <typename Executor, typename... Ts>
+class awaitable_handler<Executor, std::exception_ptr, Ts...>
+ : public awaitable_handler_base<Executor, std::tuple<Ts...>>
+{
+public:
+ using awaitable_handler_base<Executor,
+ std::tuple<Ts...>>::awaitable_handler_base;
+
+ template <typename... Args>
+ void operator()(std::exception_ptr ex, Args&&... args)
+ {
+ this->frame()->attach_thread(this);
+ if (ex)
+ this->frame()->set_except(ex);
+ else
+ this->frame()->return_values(std::forward<Args>(args)...);
+ this->frame()->pop_frame();
+ this->pump();
+ }
+};
+
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename Executor, typename R, typename... Args>
+class async_result<use_awaitable_t<Executor>, R(Args...)>
+{
+public:
+ typedef typename detail::awaitable_handler<
+ Executor, typename decay<Args>::type...> handler_type;
+ typedef typename handler_type::awaitable_type return_type;
+
+#if defined(_MSC_VER)
+ template <typename T>
+ static T dummy_return()
+ {
+ return std::move(*static_cast<T*>(nullptr));
+ }
+
+ template <>
+ static void dummy_return()
+ {
+ }
+#endif // defined(_MSC_VER)
+
+ template <typename Initiation, typename... InitArgs>
+ static return_type initiate(Initiation initiation,
+ use_awaitable_t<Executor>, InitArgs... args)
+ {
+ co_await [&](auto* frame)
+ {
+ handler_type handler(frame->detach_thread());
+ std::move(initiation)(std::move(handler), std::move(args)...);
+ return static_cast<handler_type*>(nullptr);
+ };
+
+ for (;;) {} // Never reached.
+#if defined(_MSC_VER)
+ co_return dummy_return<typename return_type::value_type>();
+#endif // defined(_MSC_VER)
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_IMPL_USE_AWAITABLE_HPP
diff --git a/boost/asio/impl/use_future.hpp b/boost/asio/impl/use_future.hpp
index fd75a7c8e8..83fb74aecb 100644
--- a/boost/asio/impl/use_future.hpp
+++ b/boost/asio/impl/use_future.hpp
@@ -2,7 +2,7 @@
// impl/use_future.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -879,56 +879,6 @@ public:
#endif // defined(BOOST_ASIO_HAS_VARIADIC_TEMPLATES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
-
-template <typename Allocator, typename Signature>
-struct handler_type<use_future_t<Allocator>, Signature>
-{
- typedef typename async_result<use_future_t<Allocator>,
- Signature>::completion_handler_type type;
-};
-
-template <typename Signature, typename Allocator>
-class async_result<detail::promise_handler<Signature, Allocator> >
- : public detail::promise_async_result<Signature, Allocator>
-{
-public:
- typedef typename detail::promise_async_result<
- Signature, Allocator>::return_type type;
-
- explicit async_result(
- typename detail::promise_async_result<
- Signature, Allocator>::completion_handler_type& h)
- : detail::promise_async_result<Signature, Allocator>(h)
- {
- }
-};
-
-template <typename Function, typename Allocator, typename Signature>
-struct handler_type<detail::packaged_token<Function, Allocator>, Signature>
-{
- typedef typename async_result<detail::packaged_token<Function, Allocator>,
- Signature>::completion_handler_type type;
-};
-
-template <typename Function, typename Allocator, typename Result>
-class async_result<detail::packaged_handler<Function, Allocator, Result> >
- : public detail::packaged_async_result<Function, Allocator, Result>
-{
-public:
- typedef typename detail::packaged_async_result<
- Function, Allocator, Result>::return_type type;
-
- explicit async_result(
- typename detail::packaged_async_result<
- Function, Allocator, Result>::completion_handler_type& h)
- : detail::packaged_async_result<Function, Allocator, Result>(h)
- {
- }
-};
-
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
#endif // !defined(GENERATING_DOCUMENTATION)
} // namespace asio
diff --git a/boost/asio/impl/write.hpp b/boost/asio/impl/write.hpp
index 0be48b89f4..96243591ec 100644
--- a/boost/asio/impl/write.hpp
+++ b/boost/asio/impl/write.hpp
@@ -2,7 +2,7 @@
// impl/write.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,6 +28,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -67,7 +68,8 @@ inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
>::type*)
{
return detail::write_buffer_sequence(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
+ boost::asio::buffer_sequence_begin(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncWriteStream, typename ConstBufferSequence>
@@ -101,68 +103,76 @@ inline std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
>::type*)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = write(s, buffers, completion_condition, ec);
+ std::size_t bytes_transferred = write(s, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "write");
return bytes_transferred;
}
-template <typename SyncWriteStream, typename DynamicBuffer,
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition, boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
- typename decay<DynamicBuffer>::type b(
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers));
+ typename decay<DynamicBuffer_v1>::type b(
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers));
- std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);
+ std::size_t bytes_transferred = write(s, b.data(),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
b.consume(bytes_transferred);
return bytes_transferred;
}
-template <typename SyncWriteStream, typename DynamicBuffer>
+template <typename SyncWriteStream, typename DynamicBuffer_v1>
inline std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = write(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
transfer_all(), ec);
boost::asio::detail::throw_error(ec, "write");
return bytes_transferred;
}
-template <typename SyncWriteStream, typename DynamicBuffer>
+template <typename SyncWriteStream, typename DynamicBuffer_v1>
inline std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
- return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
transfer_all(), ec);
}
-template <typename SyncWriteStream, typename DynamicBuffer,
+template <typename SyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition>
inline std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
boost::system::error_code ec;
std::size_t bytes_transferred = write(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- completion_condition, ec);
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "write");
return bytes_transferred;
}
@@ -176,7 +186,8 @@ inline std::size_t write(SyncWriteStream& s,
boost::asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition, boost::system::error_code& ec)
{
- return write(s, basic_streambuf_ref<Allocator>(b), completion_condition, ec);
+ return write(s, basic_streambuf_ref<Allocator>(b),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncWriteStream, typename Allocator>
@@ -200,11 +211,68 @@ inline std::size_t write(SyncWriteStream& s,
boost::asio::basic_streambuf<Allocator>& b,
CompletionCondition completion_condition)
{
- return write(s, basic_streambuf_ref<Allocator>(b), completion_condition);
+ return write(s, basic_streambuf_ref<Allocator>(b),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+template <typename SyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ std::size_t bytes_transferred = write(s, buffers.data(0, buffers.size()),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
+ buffers.consume(bytes_transferred);
+ return bytes_transferred;
+}
+
+template <typename SyncWriteStream, typename DynamicBuffer_v2>
+inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ transfer_all(), ec);
+ boost::asio::detail::throw_error(ec, "write");
+ return bytes_transferred;
+}
+
+template <typename SyncWriteStream, typename DynamicBuffer_v2>
+inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return write(s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ transfer_all(), ec);
+}
+
+template <typename SyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+inline std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ boost::system::error_code ec;
+ std::size_t bytes_transferred = write(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
+ boost::asio::detail::throw_error(ec, "write");
+ return bytes_transferred;
+}
namespace detail
{
@@ -216,7 +284,7 @@ namespace detail
{
public:
write_op(AsyncWriteStream& stream, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, WriteHandler& handler)
+ CompletionCondition& completion_condition, WriteHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
stream_(stream),
@@ -237,9 +305,11 @@ namespace detail
}
write_op(write_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
stream_(other.stream_),
- buffers_(other.buffers_),
+ buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
start_(other.start_),
handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
{
@@ -270,9 +340,11 @@ namespace detail
}
//private:
+ typedef boost::asio::detail::consuming_buffers<const_buffer,
+ ConstBufferSequence, ConstBufferIterator> buffers_type;
+
AsyncWriteStream& stream_;
- boost::asio::detail::consuming_buffers<const_buffer,
- ConstBufferSequence, ConstBufferIterator> buffers_;
+ buffers_type buffers_;
int start_;
WriteHandler handler_;
};
@@ -338,7 +410,7 @@ namespace detail
typename WriteHandler>
inline void start_write_buffer_sequence_op(AsyncWriteStream& stream,
const ConstBufferSequence& buffers, const ConstBufferIterator&,
- CompletionCondition completion_condition, WriteHandler& handler)
+ CompletionCondition& completion_condition, WriteHandler& handler)
{
detail::write_op<AsyncWriteStream, ConstBufferSequence,
ConstBufferIterator, CompletionCondition, WriteHandler>(
@@ -346,6 +418,25 @@ namespace detail
boost::system::error_code(), 0, 1);
}
+ struct initiate_async_write_buffer_sequence
+ {
+ template <typename WriteHandler, typename AsyncWriteStream,
+ typename ConstBufferSequence, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ AsyncWriteStream* s, const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ start_write_buffer_sequence_op(*s, buffers,
+ boost::asio::buffer_sequence_begin(buffers),
+ completion_cond2.value, handler2.value);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -401,18 +492,10 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_write_buffer_sequence_op(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition,
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_buffer_sequence(), handler, &s, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncWriteStream, typename ConstBufferSequence,
@@ -425,31 +508,25 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_write_buffer_sequence_op(s, buffers,
- boost::asio::buffer_sequence_begin(buffers), transfer_all(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_buffer_sequence(),
+ handler, &s, buffers, transfer_all());
}
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
namespace detail
{
- template <typename AsyncWriteStream, typename DynamicBuffer,
+ template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
- class write_dynbuf_op
+ class write_dynbuf_v1_op
{
public:
template <typename BufferSequence>
- write_dynbuf_op(AsyncWriteStream& stream,
+ write_dynbuf_v1_op(AsyncWriteStream& stream,
BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
- CompletionCondition completion_condition, WriteHandler& handler)
+ CompletionCondition& completion_condition, WriteHandler& handler)
: stream_(stream),
buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
completion_condition_(
@@ -459,7 +536,7 @@ namespace detail
}
#if defined(BOOST_ASIO_HAS_MOVE)
- write_dynbuf_op(const write_dynbuf_op& other)
+ write_dynbuf_v1_op(const write_dynbuf_v1_op& other)
: stream_(other.stream_),
buffers_(other.buffers_),
completion_condition_(other.completion_condition_),
@@ -467,9 +544,9 @@ namespace detail
{
}
- write_dynbuf_op(write_dynbuf_op&& other)
+ write_dynbuf_v1_op(write_dynbuf_v1_op&& other)
: stream_(other.stream_),
- buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer)(other.buffers_)),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(other.buffers_)),
completion_condition_(
BOOST_ASIO_MOVE_CAST(CompletionCondition)(
other.completion_condition_)),
@@ -484,8 +561,9 @@ namespace detail
switch (start)
{
case 1:
- async_write(stream_, buffers_.data(), completion_condition_,
- BOOST_ASIO_MOVE_CAST(write_dynbuf_op)(*this));
+ async_write(stream_, buffers_.data(),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
+ BOOST_ASIO_MOVE_CAST(write_dynbuf_v1_op)(*this));
return; default:
buffers_.consume(bytes_transferred);
handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
@@ -494,35 +572,35 @@ namespace detail
//private:
AsyncWriteStream& stream_;
- DynamicBuffer buffers_;
+ DynamicBuffer_v1 buffers_;
CompletionCondition completion_condition_;
WriteHandler handler_;
};
- template <typename AsyncWriteStream, typename DynamicBuffer,
+ template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
inline void* asio_handler_allocate(std::size_t size,
- write_dynbuf_op<AsyncWriteStream, DynamicBuffer,
+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
CompletionCondition, WriteHandler>* this_handler)
{
return boost_asio_handler_alloc_helpers::allocate(
size, this_handler->handler_);
}
- template <typename AsyncWriteStream, typename DynamicBuffer,
+ template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
inline void asio_handler_deallocate(void* pointer, std::size_t size,
- write_dynbuf_op<AsyncWriteStream, DynamicBuffer,
+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
CompletionCondition, WriteHandler>* this_handler)
{
boost_asio_handler_alloc_helpers::deallocate(
pointer, size, this_handler->handler_);
}
- template <typename AsyncWriteStream, typename DynamicBuffer,
+ template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
inline bool asio_handler_is_continuation(
- write_dynbuf_op<AsyncWriteStream, DynamicBuffer,
+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
CompletionCondition, WriteHandler>* this_handler)
{
return boost_asio_handler_cont_helpers::is_continuation(
@@ -530,10 +608,10 @@ namespace detail
}
template <typename Function, typename AsyncWriteStream,
- typename DynamicBuffer, typename CompletionCondition,
+ typename DynamicBuffer_v1, typename CompletionCondition,
typename WriteHandler>
inline void asio_handler_invoke(Function& function,
- write_dynbuf_op<AsyncWriteStream, DynamicBuffer,
+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
CompletionCondition, WriteHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
@@ -541,49 +619,72 @@ namespace detail
}
template <typename Function, typename AsyncWriteStream,
- typename DynamicBuffer, typename CompletionCondition,
+ typename DynamicBuffer_v1, typename CompletionCondition,
typename WriteHandler>
inline void asio_handler_invoke(const Function& function,
- write_dynbuf_op<AsyncWriteStream, DynamicBuffer,
+ write_dynbuf_v1_op<AsyncWriteStream, DynamicBuffer_v1,
CompletionCondition, WriteHandler>* this_handler)
{
boost_asio_handler_invoke_helpers::invoke(
function, this_handler->handler_);
}
+
+ struct initiate_async_write_dynbuf_v1
+ {
+ template <typename WriteHandler, typename AsyncWriteStream,
+ typename DynamicBuffer_v1, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ AsyncWriteStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ write_dynbuf_v1_op<AsyncWriteStream,
+ typename decay<DynamicBuffer_v1>::type,
+ CompletionCondition, typename decay<WriteHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ completion_cond2.value, handler2.value)(
+ boost::system::error_code(), 0, 1);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
-template <typename AsyncWriteStream, typename DynamicBuffer,
+template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler, typename Allocator>
struct associated_allocator<
- detail::write_dynbuf_op<AsyncWriteStream,
- DynamicBuffer, CompletionCondition, WriteHandler>,
+ detail::write_dynbuf_v1_op<AsyncWriteStream,
+ DynamicBuffer_v1, CompletionCondition, WriteHandler>,
Allocator>
{
typedef typename associated_allocator<WriteHandler, Allocator>::type type;
static type get(
- const detail::write_dynbuf_op<AsyncWriteStream,
- DynamicBuffer, CompletionCondition, WriteHandler>& h,
+ const detail::write_dynbuf_v1_op<AsyncWriteStream,
+ DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
{
return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
}
};
-template <typename AsyncWriteStream, typename DynamicBuffer,
+template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler, typename Executor>
struct associated_executor<
- detail::write_dynbuf_op<AsyncWriteStream,
- DynamicBuffer, CompletionCondition, WriteHandler>,
+ detail::write_dynbuf_v1_op<AsyncWriteStream,
+ DynamicBuffer_v1, CompletionCondition, WriteHandler>,
Executor>
{
typedef typename associated_executor<WriteHandler, Executor>::type type;
static type get(
- const detail::write_dynbuf_op<AsyncWriteStream,
- DynamicBuffer, CompletionCondition, WriteHandler>& h,
+ const detail::write_dynbuf_v1_op<AsyncWriteStream,
+ DynamicBuffer_v1, CompletionCondition, WriteHandler>& h,
const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
{
return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
@@ -593,49 +694,40 @@ struct associated_executor<
#endif // !defined(GENERATING_DOCUMENTATION)
template <typename AsyncWriteStream,
- typename DynamicBuffer, typename WriteHandler>
+ typename DynamicBuffer_v1, typename WriteHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
return async_write(s,
- BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
}
-template <typename AsyncWriteStream, typename DynamicBuffer,
+template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type*)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::write_dynbuf_op<AsyncWriteStream,
- typename decay<DynamicBuffer>::type,
- CompletionCondition, BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- s, BOOST_ASIO_MOVE_CAST(DynamicBuffer)(buffers),
- completion_condition, init.completion_handler)(
- boost::system::error_code(), 0, 1);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_dynbuf_v1(), handler, &s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v1)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -662,11 +754,223 @@ async_write(AsyncWriteStream& s,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
return async_write(s, basic_streambuf_ref<Allocator>(b),
- completion_condition, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
+ BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+namespace detail
+{
+ template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+ class write_dynbuf_v2_op
+ {
+ public:
+ template <typename BufferSequence>
+ write_dynbuf_v2_op(AsyncWriteStream& stream,
+ BOOST_ASIO_MOVE_ARG(BufferSequence) buffers,
+ CompletionCondition& completion_condition, WriteHandler& handler)
+ : stream_(stream),
+ buffers_(BOOST_ASIO_MOVE_CAST(BufferSequence)(buffers)),
+ completion_condition_(
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition)),
+ handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))
+ {
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+ write_dynbuf_v2_op(const write_dynbuf_v2_op& other)
+ : stream_(other.stream_),
+ buffers_(other.buffers_),
+ completion_condition_(other.completion_condition_),
+ handler_(other.handler_)
+ {
+ }
+
+ write_dynbuf_v2_op(write_dynbuf_v2_op&& other)
+ : stream_(other.stream_),
+ buffers_(BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(other.buffers_)),
+ completion_condition_(
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(
+ other.completion_condition_)),
+ handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
+ {
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred, int start = 0)
+ {
+ switch (start)
+ {
+ case 1:
+ async_write(stream_, buffers_.data(0, buffers_.size()),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition_),
+ BOOST_ASIO_MOVE_CAST(write_dynbuf_v2_op)(*this));
+ return; default:
+ buffers_.consume(bytes_transferred);
+ handler_(ec, static_cast<const std::size_t&>(bytes_transferred));
+ }
+ }
+
+ //private:
+ AsyncWriteStream& stream_;
+ DynamicBuffer_v2 buffers_;
+ CompletionCondition completion_condition_;
+ WriteHandler handler_;
+ };
+
+ template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+ inline void* asio_handler_allocate(std::size_t size,
+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_alloc_helpers::allocate(
+ size, this_handler->handler_);
+ }
+
+ template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+ inline void asio_handler_deallocate(void* pointer, std::size_t size,
+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_alloc_helpers::deallocate(
+ pointer, size, this_handler->handler_);
+ }
+
+ template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+ inline bool asio_handler_is_continuation(
+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ return boost_asio_handler_cont_helpers::is_continuation(
+ this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncWriteStream,
+ typename DynamicBuffer_v2, typename CompletionCondition,
+ typename WriteHandler>
+ inline void asio_handler_invoke(Function& function,
+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ template <typename Function, typename AsyncWriteStream,
+ typename DynamicBuffer_v2, typename CompletionCondition,
+ typename WriteHandler>
+ inline void asio_handler_invoke(const Function& function,
+ write_dynbuf_v2_op<AsyncWriteStream, DynamicBuffer_v2,
+ CompletionCondition, WriteHandler>* this_handler)
+ {
+ boost_asio_handler_invoke_helpers::invoke(
+ function, this_handler->handler_);
+ }
+
+ struct initiate_async_write_dynbuf_v2
+ {
+ template <typename WriteHandler, typename AsyncWriteStream,
+ typename DynamicBuffer_v2, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ AsyncWriteStream* s, BOOST_ASIO_MOVE_ARG(DynamicBuffer_v2) buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ write_dynbuf_v2_op<AsyncWriteStream,
+ typename decay<DynamicBuffer_v2>::type,
+ CompletionCondition, typename decay<WriteHandler>::type>(
+ *s, BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ completion_cond2.value, handler2.value)(
+ boost::system::error_code(), 0, 1);
+ }
+ };
+} // namespace detail
+
+#if !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler, typename Allocator>
+struct associated_allocator<
+ detail::write_dynbuf_v2_op<AsyncWriteStream,
+ DynamicBuffer_v2, CompletionCondition, WriteHandler>,
+ Allocator>
+{
+ typedef typename associated_allocator<WriteHandler, Allocator>::type type;
+
+ static type get(
+ const detail::write_dynbuf_v2_op<AsyncWriteStream,
+ DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
+ const Allocator& a = Allocator()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_allocator<WriteHandler, Allocator>::get(h.handler_, a);
+ }
+};
+
+template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler, typename Executor>
+struct associated_executor<
+ detail::write_dynbuf_v2_op<AsyncWriteStream,
+ DynamicBuffer_v2, CompletionCondition, WriteHandler>,
+ Executor>
+{
+ typedef typename associated_executor<WriteHandler, Executor>::type type;
+
+ static type get(
+ const detail::write_dynbuf_v2_op<AsyncWriteStream,
+ DynamicBuffer_v2, CompletionCondition, WriteHandler>& h,
+ const Executor& ex = Executor()) BOOST_ASIO_NOEXCEPT
+ {
+ return associated_executor<WriteHandler, Executor>::get(h.handler_, ex);
+ }
+};
+
+#endif // !defined(GENERATING_DOCUMENTATION)
+
+template <typename AsyncWriteStream,
+ typename DynamicBuffer_v2, typename WriteHandler>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_write(s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+}
+
+template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+inline BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type*)
+{
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_dynbuf_v2(), handler, &s,
+ BOOST_ASIO_MOVE_CAST(DynamicBuffer_v2)(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
+}
} // namespace asio
} // namespace boost
diff --git a/boost/asio/impl/write_at.hpp b/boost/asio/impl/write_at.hpp
index 6b597d2085..3cad9c5b50 100644
--- a/boost/asio/impl/write_at.hpp
+++ b/boost/asio/impl/write_at.hpp
@@ -2,7 +2,7 @@
// impl/write_at.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -28,6 +28,7 @@
#include <boost/asio/detail/handler_cont_helpers.hpp>
#include <boost/asio/detail/handler_invoke_helpers.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -69,7 +70,8 @@ std::size_t write_at(SyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition, boost::system::error_code& ec)
{
return detail::write_at_buffer_sequence(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition, ec);
+ boost::asio::buffer_sequence_begin(buffers),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
}
template <typename SyncRandomAccessWriteDevice, typename ConstBufferSequence>
@@ -98,8 +100,8 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(
- d, offset, buffers, completion_condition, ec);
+ std::size_t bytes_transferred = write_at(d, offset, buffers,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "write_at");
return bytes_transferred;
}
@@ -113,8 +115,8 @@ std::size_t write_at(SyncRandomAccessWriteDevice& d,
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);
+ std::size_t bytes_transferred = write_at(d, offset, b.data(),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
b.consume(bytes_transferred);
return bytes_transferred;
}
@@ -144,8 +146,8 @@ inline std::size_t write_at(SyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition)
{
boost::system::error_code ec;
- std::size_t bytes_transferred = write_at(
- d, offset, b, completion_condition, ec);
+ std::size_t bytes_transferred = write_at(d, offset, b,
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition), ec);
boost::asio::detail::throw_error(ec, "write_at");
return bytes_transferred;
}
@@ -164,7 +166,7 @@ namespace detail
public:
write_at_op(AsyncRandomAccessWriteDevice& device,
uint64_t offset, const ConstBufferSequence& buffers,
- CompletionCondition completion_condition, WriteHandler& handler)
+ CompletionCondition& completion_condition, WriteHandler& handler)
: detail::base_from_completion_cond<
CompletionCondition>(completion_condition),
device_(device),
@@ -187,10 +189,12 @@ namespace detail
}
write_at_op(write_at_op&& other)
- : detail::base_from_completion_cond<CompletionCondition>(other),
+ : detail::base_from_completion_cond<CompletionCondition>(
+ BOOST_ASIO_MOVE_CAST(detail::base_from_completion_cond<
+ CompletionCondition>)(other)),
device_(other.device_),
offset_(other.offset_),
- buffers_(other.buffers_),
+ buffers_(BOOST_ASIO_MOVE_CAST(buffers_type)(other.buffers_)),
start_(other.start_),
handler_(BOOST_ASIO_MOVE_CAST(WriteHandler)(other.handler_))
{
@@ -222,10 +226,12 @@ namespace detail
}
//private:
+ typedef boost::asio::detail::consuming_buffers<const_buffer,
+ ConstBufferSequence, ConstBufferIterator> buffers_type;
+
AsyncRandomAccessWriteDevice& device_;
uint64_t offset_;
- boost::asio::detail::consuming_buffers<const_buffer,
- ConstBufferSequence, ConstBufferIterator> buffers_;
+ buffers_type buffers_;
int start_;
WriteHandler handler_;
};
@@ -291,7 +297,7 @@ namespace detail
typename CompletionCondition, typename WriteHandler>
inline void start_write_at_buffer_sequence_op(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers,
- const ConstBufferIterator&, CompletionCondition completion_condition,
+ const ConstBufferIterator&, CompletionCondition& completion_condition,
WriteHandler& handler)
{
detail::write_at_op<AsyncRandomAccessWriteDevice, ConstBufferSequence,
@@ -299,6 +305,27 @@ namespace detail
d, offset, buffers, completion_condition, handler)(
boost::system::error_code(), 0, 1);
}
+
+ struct initiate_async_write_at_buffer_sequence
+ {
+ template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
+ typename ConstBufferSequence, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ AsyncRandomAccessWriteDevice* d, uint64_t offset,
+ const ConstBufferSequence& buffers,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_cond) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ non_const_lvalue<CompletionCondition> completion_cond2(completion_cond);
+ start_write_at_buffer_sequence_op(*d, offset, buffers,
+ boost::asio::buffer_sequence_begin(buffers),
+ completion_cond2.value, handler2.value);
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -354,18 +381,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_write_at_buffer_sequence_op(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), completion_condition,
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_at_buffer_sequence(), handler, &d, offset,
+ buffers, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncRandomAccessWriteDevice, typename ConstBufferSequence,
@@ -376,18 +395,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::start_write_at_buffer_sequence_op(d, offset, buffers,
- boost::asio::buffer_sequence_begin(buffers), transfer_all(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_at_buffer_sequence(),
+ handler, &d, offset, buffers, transfer_all());
}
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -473,13 +484,26 @@ namespace detail
function, this_handler->handler_);
}
- template <typename Allocator, typename WriteHandler>
- inline write_at_streambuf_op<Allocator, WriteHandler>
- make_write_at_streambuf_op(
- boost::asio::basic_streambuf<Allocator>& b, WriteHandler handler)
+ struct initiate_async_write_at_streambuf
{
- return write_at_streambuf_op<Allocator, WriteHandler>(b, handler);
- }
+ template <typename WriteHandler, typename AsyncRandomAccessWriteDevice,
+ typename Allocator, typename CompletionCondition>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ AsyncRandomAccessWriteDevice* d, uint64_t offset,
+ basic_streambuf<Allocator>* b,
+ BOOST_ASIO_MOVE_ARG(CompletionCondition) completion_condition) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ non_const_lvalue<WriteHandler> handler2(handler);
+ async_write_at(*d, offset, b->data(),
+ BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition),
+ write_at_streambuf_op<Allocator, typename decay<WriteHandler>::type>(
+ *b, handler2.value));
+ }
+ };
} // namespace detail
#if !defined(GENERATING_DOCUMENTATION)
@@ -525,19 +549,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- async_write_at(d, offset, b.data(), completion_condition,
- detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- b, init.completion_handler));
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_at_streambuf(), handler, &d, offset,
+ &b, BOOST_ASIO_MOVE_CAST(CompletionCondition)(completion_condition));
}
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
@@ -548,19 +563,10 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
uint64_t offset, boost::asio::basic_streambuf<Allocator>& b,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- async_write_at(d, offset, b.data(), transfer_all(),
- detail::write_at_streambuf_op<Allocator, BOOST_ASIO_HANDLER_TYPE(
- WriteHandler, void (boost::system::error_code, std::size_t))>(
- b, init.completion_handler));
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ detail::initiate_async_write_at_streambuf(),
+ handler, &d, offset, &b, transfer_all());
}
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
diff --git a/boost/asio/io_context.hpp b/boost/asio/io_context.hpp
index 51377467ea..1fb3864451 100644
--- a/boost/asio/io_context.hpp
+++ b/boost/asio/io_context.hpp
@@ -2,7 +2,7 @@
// io_context.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -595,6 +595,11 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
private:
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ struct initiate_dispatch;
+ struct initiate_post;
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
// Helper function to add the implementation.
BOOST_ASIO_DECL impl_type& add_impl(impl_type* impl);
@@ -769,10 +774,6 @@ public:
/// Get the io_context associated with the work.
boost::asio::io_context& get_io_context();
- /// (Deprecated: Use get_io_context().) Get the io_context associated with the
- /// work.
- boost::asio::io_context& get_io_service();
-
private:
// Prevent assignment.
void operator=(const work& other);
@@ -790,11 +791,6 @@ public:
/// Get the io_context object that owns the service.
boost::asio::io_context& get_io_context();
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// Get the io_context object that owns the service.
- boost::asio::io_context& get_io_service();
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
private:
/// Destroy all user-defined handler objects owned by the service.
BOOST_ASIO_DECL virtual void shutdown();
diff --git a/boost/asio/io_context_strand.hpp b/boost/asio/io_context_strand.hpp
index 144e308a21..a9a9b522cd 100644
--- a/boost/asio/io_context_strand.hpp
+++ b/boost/asio/io_context_strand.hpp
@@ -2,7 +2,7 @@
// io_context_strand.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -114,36 +114,6 @@ public:
{
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use context().) Get the io_context associated with the
- /// strand.
- /**
- * This function may be used to obtain the io_context object that the strand
- * uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the strand will use to
- * dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return service_.get_io_context();
- }
-
- /// (Deprecated: Use context().) Get the io_context associated with the
- /// strand.
- /**
- * This function may be used to obtain the io_context object that the strand
- * uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the strand will use to
- * dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return service_.get_io_context();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Obtain the underlying execution context.
boost::asio::io_context& context() const BOOST_ASIO_NOEXCEPT
{
@@ -216,16 +186,8 @@ public:
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
dispatch(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a LegacyCompletionHandler.
- BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
- LegacyCompletionHandler, handler) type_check;
-
- async_completion<LegacyCompletionHandler, void ()> init(handler);
-
- service_.dispatch(impl_, init.completion_handler);
-
- return init.result.get();
+ return async_initiate<LegacyCompletionHandler, void ()>(
+ initiate_dispatch(), handler, this);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -271,16 +233,8 @@ public:
BOOST_ASIO_INITFN_RESULT_TYPE(LegacyCompletionHandler, void ())
post(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a LegacyCompletionHandler.
- BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
- LegacyCompletionHandler, handler) type_check;
-
- async_completion<LegacyCompletionHandler, void ()> init(handler);
-
- service_.post(impl_, init.completion_handler);
-
- return init.result.get();
+ return async_initiate<LegacyCompletionHandler, void ()>(
+ initiate_post(), handler, this);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -372,6 +326,42 @@ public:
}
private:
+#if !defined(BOOST_ASIO_NO_DEPRECATED)
+ struct initiate_dispatch
+ {
+ template <typename LegacyCompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
+ strand* self) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for a
+ // LegacyCompletionHandler.
+ BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
+ LegacyCompletionHandler, handler) type_check;
+
+ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
+ self->service_.dispatch(self->impl_, handler2.value);
+ }
+ };
+
+ struct initiate_post
+ {
+ template <typename LegacyCompletionHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(LegacyCompletionHandler) handler,
+ strand* self) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for a
+ // LegacyCompletionHandler.
+ BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK(
+ LegacyCompletionHandler, handler) type_check;
+
+ detail::non_const_lvalue<LegacyCompletionHandler> handler2(handler);
+ self->service_.post(self->impl_, handler2.value);
+ }
+ };
+#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
+
boost::asio::detail::strand_service& service_;
mutable boost::asio::detail::strand_service::implementation_type impl_;
};
diff --git a/boost/asio/io_service.hpp b/boost/asio/io_service.hpp
index 76af8e0cbd..31f9e9849d 100644
--- a/boost/asio/io_service.hpp
+++ b/boost/asio/io_service.hpp
@@ -2,7 +2,7 @@
// io_service.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/io_service_strand.hpp b/boost/asio/io_service_strand.hpp
index bb38c276c6..93b811b2ec 100644
--- a/boost/asio/io_service_strand.hpp
+++ b/boost/asio/io_service_strand.hpp
@@ -2,7 +2,7 @@
// io_service_strand.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/address.hpp b/boost/asio/ip/address.hpp
index 9b0cbdd3ee..fd6ce95850 100644
--- a/boost/asio/ip/address.hpp
+++ b/boost/asio/ip/address.hpp
@@ -2,7 +2,7 @@
// ip/address.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -48,46 +48,48 @@ class address
{
public:
/// Default constructor.
- BOOST_ASIO_DECL address();
+ BOOST_ASIO_DECL address() BOOST_ASIO_NOEXCEPT;
/// Construct an address from an IPv4 address.
- BOOST_ASIO_DECL address(const boost::asio::ip::address_v4& ipv4_address);
+ BOOST_ASIO_DECL address(
+ const boost::asio::ip::address_v4& ipv4_address) BOOST_ASIO_NOEXCEPT;
/// Construct an address from an IPv6 address.
- BOOST_ASIO_DECL address(const boost::asio::ip::address_v6& ipv6_address);
+ BOOST_ASIO_DECL address(
+ const boost::asio::ip::address_v6& ipv6_address) BOOST_ASIO_NOEXCEPT;
/// Copy constructor.
- BOOST_ASIO_DECL address(const address& other);
+ BOOST_ASIO_DECL address(const address& other) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move constructor.
- BOOST_ASIO_DECL address(address&& other);
+ BOOST_ASIO_DECL address(address&& other) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// Assign from another address.
- BOOST_ASIO_DECL address& operator=(const address& other);
+ BOOST_ASIO_DECL address& operator=(const address& other) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move-assign from another address.
- BOOST_ASIO_DECL address& operator=(address&& other);
+ BOOST_ASIO_DECL address& operator=(address&& other) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// Assign from an IPv4 address.
BOOST_ASIO_DECL address& operator=(
- const boost::asio::ip::address_v4& ipv4_address);
+ const boost::asio::ip::address_v4& ipv4_address) BOOST_ASIO_NOEXCEPT;
/// Assign from an IPv6 address.
BOOST_ASIO_DECL address& operator=(
- const boost::asio::ip::address_v6& ipv6_address);
+ const boost::asio::ip::address_v6& ipv6_address) BOOST_ASIO_NOEXCEPT;
/// Get whether the address is an IP version 4 address.
- bool is_v4() const
+ bool is_v4() const BOOST_ASIO_NOEXCEPT
{
return type_ == ipv4;
}
/// Get whether the address is an IP version 6 address.
- bool is_v6() const
+ bool is_v6() const BOOST_ASIO_NOEXCEPT
{
return type_ == ipv6;
}
@@ -128,40 +130,46 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Determine whether the address is a loopback address.
- BOOST_ASIO_DECL bool is_loopback() const;
+ BOOST_ASIO_DECL bool is_loopback() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is unspecified.
- BOOST_ASIO_DECL bool is_unspecified() const;
+ BOOST_ASIO_DECL bool is_unspecified() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a multicast address.
- BOOST_ASIO_DECL bool is_multicast() const;
+ BOOST_ASIO_DECL bool is_multicast() const BOOST_ASIO_NOEXCEPT;
/// Compare two addresses for equality.
- BOOST_ASIO_DECL friend bool operator==(const address& a1, const address& a2);
+ BOOST_ASIO_DECL friend bool operator==(const address& a1,
+ const address& a2) BOOST_ASIO_NOEXCEPT;
/// Compare two addresses for inequality.
- friend bool operator!=(const address& a1, const address& a2)
+ friend bool operator!=(const address& a1,
+ const address& a2) BOOST_ASIO_NOEXCEPT
{
return !(a1 == a2);
}
/// Compare addresses for ordering.
- BOOST_ASIO_DECL friend bool operator<(const address& a1, const address& a2);
+ BOOST_ASIO_DECL friend bool operator<(const address& a1,
+ const address& a2) BOOST_ASIO_NOEXCEPT;
/// Compare addresses for ordering.
- friend bool operator>(const address& a1, const address& a2)
+ friend bool operator>(const address& a1,
+ const address& a2) BOOST_ASIO_NOEXCEPT
{
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) BOOST_ASIO_NOEXCEPT
{
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) BOOST_ASIO_NOEXCEPT
{
return !(a1 < a2);
}
@@ -189,8 +197,8 @@ BOOST_ASIO_DECL address make_address(const char* str);
/**
* @relates address
*/
-BOOST_ASIO_DECL address make_address(
- const char* str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address make_address(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
/// Create an address from an IPv4 address string in dotted decimal form,
/// or from an IPv6 address in hexadecimal notation.
@@ -204,8 +212,8 @@ BOOST_ASIO_DECL address make_address(const std::string& str);
/**
* @relates address
*/
-BOOST_ASIO_DECL address make_address(
- const std::string& str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address make_address(const std::string& str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
|| defined(GENERATING_DOCUMENTATION)
@@ -222,8 +230,8 @@ BOOST_ASIO_DECL address make_address(string_view str);
/**
* @relates address
*/
-BOOST_ASIO_DECL address make_address(
- string_view str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address make_address(string_view str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/ip/address_v4.hpp b/boost/asio/ip/address_v4.hpp
index 68d724085d..b612fa0cd7 100644
--- a/boost/asio/ip/address_v4.hpp
+++ b/boost/asio/ip/address_v4.hpp
@@ -2,7 +2,7 @@
// ip/address_v4.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -61,7 +61,7 @@ public:
#endif
/// Default constructor.
- address_v4()
+ address_v4() BOOST_ASIO_NOEXCEPT
{
addr_.s_addr = 0;
}
@@ -73,21 +73,21 @@ public:
BOOST_ASIO_DECL explicit address_v4(uint_type addr);
/// Copy constructor.
- address_v4(const address_v4& other)
+ address_v4(const address_v4& other) BOOST_ASIO_NOEXCEPT
: addr_(other.addr_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move constructor.
- address_v4(address_v4&& other)
+ address_v4(address_v4&& other) BOOST_ASIO_NOEXCEPT
: addr_(other.addr_)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// Assign from another address.
- address_v4& operator=(const address_v4& other)
+ address_v4& operator=(const address_v4& other) BOOST_ASIO_NOEXCEPT
{
addr_ = other.addr_;
return *this;
@@ -95,7 +95,7 @@ public:
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move-assign from another address.
- address_v4& operator=(address_v4&& other)
+ address_v4& operator=(address_v4&& other) BOOST_ASIO_NOEXCEPT
{
addr_ = other.addr_;
return *this;
@@ -103,10 +103,10 @@ public:
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// Get the address in bytes, in network byte order.
- BOOST_ASIO_DECL bytes_type to_bytes() const;
+ BOOST_ASIO_DECL bytes_type to_bytes() const BOOST_ASIO_NOEXCEPT;
/// Get the address as an unsigned integer in host byte order
- BOOST_ASIO_DECL uint_type to_uint() const;
+ BOOST_ASIO_DECL uint_type to_uint() const BOOST_ASIO_NOEXCEPT;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// Get the address as an unsigned long in host byte order
@@ -141,10 +141,10 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Determine whether the address is a loopback address.
- BOOST_ASIO_DECL bool is_loopback() const;
+ BOOST_ASIO_DECL bool is_loopback() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is unspecified.
- BOOST_ASIO_DECL bool is_unspecified() const;
+ BOOST_ASIO_DECL bool is_unspecified() const BOOST_ASIO_NOEXCEPT;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use network_v4 class.) Determine whether the address is a
@@ -161,58 +161,64 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Determine whether the address is a multicast address.
- BOOST_ASIO_DECL bool is_multicast() const;
+ BOOST_ASIO_DECL bool is_multicast() const BOOST_ASIO_NOEXCEPT;
/// Compare two addresses for equality.
- friend bool operator==(const address_v4& a1, const address_v4& a2)
+ friend bool operator==(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.addr_.s_addr == a2.addr_.s_addr;
}
/// Compare two addresses for inequality.
- friend bool operator!=(const address_v4& a1, const address_v4& a2)
+ friend bool operator!=(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.addr_.s_addr != a2.addr_.s_addr;
}
/// Compare addresses for ordering.
- friend bool operator<(const address_v4& a1, const address_v4& a2)
+ friend bool operator<(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.to_uint() < a2.to_uint();
}
/// Compare addresses for ordering.
- friend bool operator>(const address_v4& a1, const address_v4& a2)
+ friend bool operator>(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.to_uint() > a2.to_uint();
}
/// Compare addresses for ordering.
- friend bool operator<=(const address_v4& a1, const address_v4& a2)
+ friend bool operator<=(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.to_uint() <= a2.to_uint();
}
/// Compare addresses for ordering.
- friend bool operator>=(const address_v4& a1, const address_v4& a2)
+ friend bool operator>=(const address_v4& a1,
+ const address_v4& a2) BOOST_ASIO_NOEXCEPT
{
return a1.to_uint() >= a2.to_uint();
}
/// Obtain an address object that represents any address.
- static address_v4 any()
+ static address_v4 any() BOOST_ASIO_NOEXCEPT
{
return address_v4();
}
/// Obtain an address object that represents the loopback address.
- static address_v4 loopback()
+ static address_v4 loopback() BOOST_ASIO_NOEXCEPT
{
return address_v4(0x7F000001);
}
/// Obtain an address object that represents the broadcast address.
- static address_v4 broadcast()
+ static address_v4 broadcast() BOOST_ASIO_NOEXCEPT
{
return address_v4(0xFFFFFFFF);
}
@@ -262,8 +268,8 @@ BOOST_ASIO_DECL address_v4 make_address_v4(const char* str);
/**
* @relates address_v4
*/
-BOOST_ASIO_DECL address_v4 make_address_v4(
- const char* str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v4 make_address_v4(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
/// Create an IPv4 address from an IP address string in dotted decimal form.
/**
@@ -275,8 +281,8 @@ BOOST_ASIO_DECL address_v4 make_address_v4(const std::string& str);
/**
* @relates address_v4
*/
-BOOST_ASIO_DECL address_v4 make_address_v4(
- const std::string& str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v4 make_address_v4(const std::string& str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
|| defined(GENERATING_DOCUMENTATION)
@@ -291,8 +297,8 @@ BOOST_ASIO_DECL address_v4 make_address_v4(string_view str);
/**
* @relates address_v4
*/
-BOOST_ASIO_DECL address_v4 make_address_v4(
- string_view str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v4 make_address_v4(string_view str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/ip/address_v4_iterator.hpp b/boost/asio/ip/address_v4_iterator.hpp
index 3574cda1e9..5a52fe0e1a 100644
--- a/boost/asio/ip/address_v4_iterator.hpp
+++ b/boost/asio/ip/address_v4_iterator.hpp
@@ -2,7 +2,7 @@
// ip/address_v4_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/address_v4_range.hpp b/boost/asio/ip/address_v4_range.hpp
index 261ead22ac..5e9c548bea 100644
--- a/boost/asio/ip/address_v4_range.hpp
+++ b/boost/asio/ip/address_v4_range.hpp
@@ -2,7 +2,7 @@
// ip/address_v4_range.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/address_v6.hpp b/boost/asio/ip/address_v6.hpp
index 8c4ac0a732..62dff45c54 100644
--- a/boost/asio/ip/address_v6.hpp
+++ b/boost/asio/ip/address_v6.hpp
@@ -2,7 +2,7 @@
// ip/address_v6.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -60,33 +60,34 @@ public:
#endif
/// Default constructor.
- BOOST_ASIO_DECL address_v6();
+ BOOST_ASIO_DECL address_v6() BOOST_ASIO_NOEXCEPT;
/// Construct an address from raw bytes and scope ID.
BOOST_ASIO_DECL explicit address_v6(const bytes_type& bytes,
unsigned long scope_id = 0);
/// Copy constructor.
- BOOST_ASIO_DECL address_v6(const address_v6& other);
+ BOOST_ASIO_DECL address_v6(const address_v6& other) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move constructor.
- BOOST_ASIO_DECL address_v6(address_v6&& other);
+ BOOST_ASIO_DECL address_v6(address_v6&& other) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// Assign from another address.
- BOOST_ASIO_DECL address_v6& operator=(const address_v6& other);
+ BOOST_ASIO_DECL address_v6& operator=(
+ const address_v6& other) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_MOVE)
/// Move-assign from another address.
- BOOST_ASIO_DECL address_v6& operator=(address_v6&& other);
+ BOOST_ASIO_DECL address_v6& operator=(address_v6&& other) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_MOVE)
/// The scope ID of the address.
/**
* Returns the scope ID associated with the IPv6 address.
*/
- unsigned long scope_id() const
+ unsigned long scope_id() const BOOST_ASIO_NOEXCEPT
{
return scope_id_;
}
@@ -95,13 +96,13 @@ public:
/**
* Modifies the scope ID associated with the IPv6 address.
*/
- void scope_id(unsigned long id)
+ void scope_id(unsigned long id) BOOST_ASIO_NOEXCEPT
{
scope_id_ = id;
}
/// Get the address in bytes, in network byte order.
- BOOST_ASIO_DECL bytes_type to_bytes() const;
+ BOOST_ASIO_DECL bytes_type to_bytes() const BOOST_ASIO_NOEXCEPT;
/// Get the address as a string.
BOOST_ASIO_DECL std::string to_string() const;
@@ -134,19 +135,19 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Determine whether the address is a loopback address.
- BOOST_ASIO_DECL bool is_loopback() const;
+ BOOST_ASIO_DECL bool is_loopback() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is unspecified.
- BOOST_ASIO_DECL bool is_unspecified() const;
+ BOOST_ASIO_DECL bool is_unspecified() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is link local.
- BOOST_ASIO_DECL bool is_link_local() const;
+ BOOST_ASIO_DECL bool is_link_local() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is site local.
- BOOST_ASIO_DECL bool is_site_local() const;
+ BOOST_ASIO_DECL bool is_site_local() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a mapped IPv4 address.
- BOOST_ASIO_DECL bool is_v4_mapped() const;
+ BOOST_ASIO_DECL bool is_v4_mapped() const BOOST_ASIO_NOEXCEPT;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: No replacement.) Determine whether the address is an
@@ -155,63 +156,67 @@ public:
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
/// Determine whether the address is a multicast address.
- BOOST_ASIO_DECL bool is_multicast() const;
+ BOOST_ASIO_DECL bool is_multicast() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a global multicast address.
- BOOST_ASIO_DECL bool is_multicast_global() const;
+ BOOST_ASIO_DECL bool is_multicast_global() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a link-local multicast address.
- BOOST_ASIO_DECL bool is_multicast_link_local() const;
+ BOOST_ASIO_DECL bool is_multicast_link_local() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a node-local multicast address.
- BOOST_ASIO_DECL bool is_multicast_node_local() const;
+ BOOST_ASIO_DECL bool is_multicast_node_local() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a org-local multicast address.
- BOOST_ASIO_DECL bool is_multicast_org_local() const;
+ BOOST_ASIO_DECL bool is_multicast_org_local() const BOOST_ASIO_NOEXCEPT;
/// Determine whether the address is a site-local multicast address.
- BOOST_ASIO_DECL bool is_multicast_site_local() const;
+ BOOST_ASIO_DECL bool is_multicast_site_local() const BOOST_ASIO_NOEXCEPT;
/// Compare two addresses for equality.
- BOOST_ASIO_DECL friend bool operator==(
- const address_v6& a1, const address_v6& a2);
+ BOOST_ASIO_DECL friend bool operator==(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT;
/// Compare two addresses for inequality.
- friend bool operator!=(const address_v6& a1, const address_v6& a2)
+ friend bool operator!=(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
return !(a1 == a2);
}
/// Compare addresses for ordering.
- BOOST_ASIO_DECL friend bool operator<(
- const address_v6& a1, const address_v6& a2);
+ BOOST_ASIO_DECL friend bool operator<(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT;
/// Compare addresses for ordering.
- friend bool operator>(const address_v6& a1, const address_v6& a2)
+ friend bool operator>(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
return a2 < a1;
}
/// Compare addresses for ordering.
- friend bool operator<=(const address_v6& a1, const address_v6& a2)
+ friend bool operator<=(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
return !(a2 < a1);
}
/// Compare addresses for ordering.
- friend bool operator>=(const address_v6& a1, const address_v6& a2)
+ friend bool operator>=(const address_v6& a1,
+ const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
return !(a1 < a2);
}
/// Obtain an address object that represents any address.
- static address_v6 any()
+ static address_v6 any() BOOST_ASIO_NOEXCEPT
{
return address_v6();
}
/// Obtain an address object that represents the loopback address.
- BOOST_ASIO_DECL static address_v6 loopback();
+ BOOST_ASIO_DECL static address_v6 loopback() BOOST_ASIO_NOEXCEPT;
#if !defined(BOOST_ASIO_NO_DEPRECATED)
/// (Deprecated: Use make_address_v6().) Create an IPv4-mapped IPv6 address.
@@ -251,8 +256,8 @@ BOOST_ASIO_DECL address_v6 make_address_v6(const char* str);
/**
* @relates address_v6
*/
-BOOST_ASIO_DECL address_v6 make_address_v6(
- const char* str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v6 make_address_v6(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
/// Createan IPv6 address from an IP address string.
/**
@@ -264,8 +269,8 @@ BOOST_ASIO_DECL address_v6 make_address_v6(const std::string& str);
/**
* @relates address_v6
*/
-BOOST_ASIO_DECL address_v6 make_address_v6(
- const std::string& str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v6 make_address_v6(const std::string& str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#if defined(BOOST_ASIO_HAS_STRING_VIEW) \
|| defined(GENERATING_DOCUMENTATION)
@@ -280,8 +285,8 @@ BOOST_ASIO_DECL address_v6 make_address_v6(string_view str);
/**
* @relates address_v6
*/
-BOOST_ASIO_DECL address_v6 make_address_v6(
- string_view str, boost::system::error_code& ec);
+BOOST_ASIO_DECL address_v6 make_address_v6(string_view str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT;
#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/ip/address_v6_iterator.hpp b/boost/asio/ip/address_v6_iterator.hpp
index 887b09f79a..4598a872b2 100644
--- a/boost/asio/ip/address_v6_iterator.hpp
+++ b/boost/asio/ip/address_v6_iterator.hpp
@@ -2,7 +2,7 @@
// ip/address_v6_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/address_v6_range.hpp b/boost/asio/ip/address_v6_range.hpp
index 0a095cd80b..9189fde3c9 100644
--- a/boost/asio/ip/address_v6_range.hpp
+++ b/boost/asio/ip/address_v6_range.hpp
@@ -2,7 +2,7 @@
// ip/address_v6_range.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/bad_address_cast.hpp b/boost/asio/ip/bad_address_cast.hpp
index fce9f053b1..da06983301 100644
--- a/boost/asio/ip/bad_address_cast.hpp
+++ b/boost/asio/ip/bad_address_cast.hpp
@@ -2,7 +2,7 @@
// ip/bad_address_cast.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/basic_endpoint.hpp b/boost/asio/ip/basic_endpoint.hpp
index bad4114f0b..0951fd70d3 100644
--- a/boost/asio/ip/basic_endpoint.hpp
+++ b/boost/asio/ip/basic_endpoint.hpp
@@ -2,7 +2,7 @@
// ip/basic_endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -57,7 +57,7 @@ public:
#endif
/// Default constructor.
- basic_endpoint()
+ basic_endpoint() BOOST_ASIO_NOEXCEPT
: impl_()
{
}
@@ -79,7 +79,7 @@ public:
* @endcode
*/
basic_endpoint(const InternetProtocol& internet_protocol,
- unsigned short port_num)
+ unsigned short port_num) BOOST_ASIO_NOEXCEPT
: impl_(internet_protocol.family(), port_num)
{
}
@@ -87,27 +87,28 @@ public:
/// 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)
+ basic_endpoint(const boost::asio::ip::address& addr,
+ unsigned short port_num) BOOST_ASIO_NOEXCEPT
: impl_(addr, port_num)
{
}
/// Copy constructor.
- basic_endpoint(const basic_endpoint& other)
+ basic_endpoint(const basic_endpoint& other) BOOST_ASIO_NOEXCEPT
: impl_(other.impl_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move constructor.
- basic_endpoint(basic_endpoint&& other)
+ basic_endpoint(basic_endpoint&& other) BOOST_ASIO_NOEXCEPT
: impl_(other.impl_)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Assign from another endpoint.
- basic_endpoint& operator=(const basic_endpoint& other)
+ basic_endpoint& operator=(const basic_endpoint& other) BOOST_ASIO_NOEXCEPT
{
impl_ = other.impl_;
return *this;
@@ -115,7 +116,7 @@ public:
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move-assign from another endpoint.
- basic_endpoint& operator=(basic_endpoint&& other)
+ basic_endpoint& operator=(basic_endpoint&& other) BOOST_ASIO_NOEXCEPT
{
impl_ = other.impl_;
return *this;
@@ -123,7 +124,7 @@ public:
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// The protocol associated with the endpoint.
- protocol_type protocol() const
+ protocol_type protocol() const BOOST_ASIO_NOEXCEPT
{
if (impl_.is_v4())
return InternetProtocol::v4();
@@ -131,19 +132,19 @@ public:
}
/// Get the underlying endpoint in the native type.
- data_type* data()
+ data_type* data() BOOST_ASIO_NOEXCEPT
{
return impl_.data();
}
/// Get the underlying endpoint in the native type.
- const data_type* data() const
+ const data_type* data() const BOOST_ASIO_NOEXCEPT
{
return impl_.data();
}
/// Get the underlying size of the endpoint in the native type.
- std::size_t size() const
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
{
return impl_.size();
}
@@ -155,75 +156,75 @@ public:
}
/// Get the capacity of the endpoint in the native type.
- std::size_t capacity() const
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{
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
+ unsigned short port() const BOOST_ASIO_NOEXCEPT
{
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)
+ void port(unsigned short port_num) BOOST_ASIO_NOEXCEPT
{
impl_.port(port_num);
}
/// Get the IP address associated with the endpoint.
- boost::asio::ip::address address() const
+ boost::asio::ip::address address() const BOOST_ASIO_NOEXCEPT
{
return impl_.address();
}
/// Set the IP address associated with the endpoint.
- void address(const boost::asio::ip::address& addr)
+ void address(const boost::asio::ip::address& addr) BOOST_ASIO_NOEXCEPT
{
impl_.address(addr);
}
/// Compare two endpoints for equality.
friend bool operator==(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return e1.impl_ == e2.impl_;
}
/// Compare two endpoints for inequality.
friend bool operator!=(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return !(e1 == e2);
}
/// Compare endpoints for ordering.
friend bool operator<(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return e1.impl_ < e2.impl_;
}
/// Compare endpoints for ordering.
friend bool operator>(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return e2.impl_ < e1.impl_;
}
/// Compare endpoints for ordering.
friend bool operator<=(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return !(e2 < e1);
}
/// Compare endpoints for ordering.
friend bool operator>=(const basic_endpoint<InternetProtocol>& e1,
- const basic_endpoint<InternetProtocol>& e2)
+ const basic_endpoint<InternetProtocol>& e2) BOOST_ASIO_NOEXCEPT
{
return !(e1 < e2);
}
diff --git a/boost/asio/ip/basic_resolver.hpp b/boost/asio/ip/basic_resolver.hpp
index 4979d104cf..b937ce5c10 100644
--- a/boost/asio/ip/basic_resolver.hpp
+++ b/boost/asio/ip/basic_resolver.hpp
@@ -2,7 +2,7 @@
// ip/basic_resolver.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -18,41 +18,43 @@
#include <boost/asio/detail/config.hpp>
#include <string>
#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/ip/basic_resolver_iterator.hpp>
#include <boost/asio/ip/basic_resolver_query.hpp>
#include <boost/asio/ip/basic_resolver_results.hpp>
#include <boost/asio/ip/resolver_base.hpp>
+#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+# include <boost/asio/detail/winrt_resolver_service.hpp>
+#else
+# include <boost/asio/detail/resolver_service.hpp>
+#endif
#if defined(BOOST_ASIO_HAS_MOVE)
# include <utility>
#endif // defined(BOOST_ASIO_HAS_MOVE)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/ip/resolver_service.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_resolver_service.hpp>
-# define BOOST_ASIO_SVC_T \
- boost::asio::detail::winrt_resolver_service<InternetProtocol>
-# else
-# include <boost/asio/detail/resolver_service.hpp>
-# define BOOST_ASIO_SVC_T \
- boost::asio::detail::resolver_service<InternetProtocol>
-# endif
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
namespace asio {
namespace ip {
+#if !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+#define BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename InternetProtocol, typename Executor = executor>
+class basic_resolver;
+
+#endif // !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+
/// Provides endpoint resolution functionality.
/**
* The basic_resolver class template provides the ability to resolve a query
@@ -62,15 +64,13 @@ namespace ip {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename InternetProtocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= resolver_service<InternetProtocol>)>
+template <typename InternetProtocol, typename Executor>
class basic_resolver
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- public resolver_base
+ : public resolver_base
{
public:
/// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
+ typedef Executor executor_type;
/// The protocol type.
typedef InternetProtocol protocol_type;
@@ -89,16 +89,33 @@ public:
/// The results type.
typedef basic_resolver_results<InternetProtocol> results_type;
- /// Constructor.
+ /// Construct with executor.
/**
* This constructor creates a basic_resolver.
*
- * @param io_context The io_context object that the resolver will use to
+ * @param ex The I/O executor that the resolver will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* resolver.
*/
- explicit basic_resolver(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
+ explicit basic_resolver(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Construct with execution context.
+ /**
+ * This constructor creates a basic_resolver.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the resolver will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the resolver.
+ */
+ template <typename ExecutionContext>
+ explicit basic_resolver(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
@@ -111,10 +128,10 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_resolver(io_context&) constructor.
+ * constructed using the @c basic_resolver(const executor_type&) constructor.
*/
basic_resolver(basic_resolver&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
+ : impl_(std::move(other.impl_))
{
}
@@ -128,11 +145,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_resolver(io_context&) constructor.
+ * constructed using the @c basic_resolver(const executor_type&) constructor.
*/
basic_resolver& operator=(basic_resolver&& other)
{
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -147,45 +164,11 @@ public:
{
}
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- // These functions are provided by basic_io_object<>.
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the executor associated with the object.
executor_type get_executor() BOOST_ASIO_NOEXCEPT
{
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
+ return impl_.get_executor();
}
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the resolver.
/**
@@ -195,7 +178,7 @@ public:
*/
void cancel()
{
- return this->get_service().cancel(this->get_implementation());
+ return impl_.get_service().cancel(impl_.get_implementation());
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -215,8 +198,8 @@ public:
results_type resolve(const query& q)
{
boost::system::error_code ec;
- results_type r = this->get_service().resolve(
- this->get_implementation(), q, ec);
+ results_type r = impl_.get_service().resolve(
+ impl_.get_implementation(), q, ec);
boost::asio::detail::throw_error(ec, "resolve");
return r;
}
@@ -236,7 +219,7 @@ public:
*/
results_type resolve(const query& q, boost::system::error_code& ec)
{
- return this->get_service().resolve(this->get_implementation(), q, ec);
+ return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -336,7 +319,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @returns A range object representing the list of endpoint entries. A
* successful call to this function is guaranteed to return a non-empty
@@ -361,8 +345,8 @@ public:
boost::system::error_code ec;
basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
- results_type r = this->get_service().resolve(
- this->get_implementation(), q, ec);
+ results_type r = impl_.get_service().resolve(
+ impl_.get_implementation(), q, ec);
boost::asio::detail::throw_error(ec, "resolve");
return r;
}
@@ -385,7 +369,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @param ec Set to indicate what error occurred, if any.
*
@@ -410,7 +395,7 @@ public:
{
basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
- return this->get_service().resolve(this->get_implementation(), q, ec);
+ return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
}
/// Perform forward resolution of a query to a list of entries.
@@ -519,7 +504,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @returns A range object representing the list of endpoint entries. A
* successful call to this function is guaranteed to return a non-empty
@@ -546,8 +532,8 @@ public:
basic_resolver_query<protocol_type> q(
protocol, static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
- results_type r = this->get_service().resolve(
- this->get_implementation(), q, ec);
+ results_type r = impl_.get_service().resolve(
+ impl_.get_implementation(), q, ec);
boost::asio::detail::throw_error(ec, "resolve");
return r;
}
@@ -573,7 +559,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @param ec Set to indicate what error occurred, if any.
*
@@ -599,7 +586,7 @@ public:
basic_resolver_query<protocol_type> q(
protocol, static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
- return this->get_service().resolve(this->get_implementation(), q, ec);
+ return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
}
#if !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -619,9 +606,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -632,23 +619,9 @@ public:
async_resolve(const query& q,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ResolveHandler.
- BOOST_ASIO_RESOLVE_HANDLER_CHECK(
- ResolveHandler, handler, results_type) type_check;
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_resolve(this->get_implementation(), q,
- BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
-
- this->get_service().async_resolve(
- this->get_implementation(), q, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return boost::asio::async_initiate<ResolveHandler,
+ void (boost::system::error_code, results_type)>(
+ initiate_async_resolve(), handler, this, q);
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
@@ -676,9 +649,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -723,7 +696,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @param handler The handler to be called when the resolve operation
* completes. Copies will be made of the handler as required. The function
@@ -733,9 +707,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -759,26 +733,12 @@ public:
resolver_base::flags resolve_flags,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ResolveHandler.
- BOOST_ASIO_RESOLVE_HANDLER_CHECK(
- ResolveHandler, handler, results_type) type_check;
-
basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_resolve(this->get_implementation(), q,
- BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
-
- this->get_service().async_resolve(
- this->get_implementation(), q, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return boost::asio::async_initiate<ResolveHandler,
+ void (boost::system::error_code, results_type)>(
+ initiate_async_resolve(), handler, this, q);
}
/// Asynchronously perform forward resolution of a query to a list of entries.
@@ -808,9 +768,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -858,7 +818,8 @@ public:
*
* @param resolve_flags A set of flags that determine how name resolution
* should be performed. The default flags are suitable for communication with
- * remote hosts.
+ * remote hosts. See the @ref resolver_base documentation for the set of
+ * available flags.
*
* @param handler The handler to be called when the resolve operation
* completes. Copies will be made of the handler as required. The function
@@ -868,9 +829,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -894,27 +855,13 @@ public:
resolver_base::flags resolve_flags,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ResolveHandler.
- BOOST_ASIO_RESOLVE_HANDLER_CHECK(
- ResolveHandler, handler, results_type) type_check;
-
basic_resolver_query<protocol_type> q(
protocol, static_cast<std::string>(host),
static_cast<std::string>(service), resolve_flags);
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_resolve(this->get_implementation(), q,
- BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
-
- this->get_service().async_resolve(
- this->get_implementation(), q, init.completion_handler);
-
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ return boost::asio::async_initiate<ResolveHandler,
+ void (boost::system::error_code, results_type)>(
+ initiate_async_resolve(), handler, this, q);
}
/// Perform reverse resolution of an endpoint to a list of entries.
@@ -934,8 +881,8 @@ public:
results_type resolve(const endpoint_type& e)
{
boost::system::error_code ec;
- results_type i = this->get_service().resolve(
- this->get_implementation(), e, ec);
+ results_type i = impl_.get_service().resolve(
+ impl_.get_implementation(), e, ec);
boost::asio::detail::throw_error(ec, "resolve");
return i;
}
@@ -956,7 +903,7 @@ public:
*/
results_type resolve(const endpoint_type& e, boost::system::error_code& ec)
{
- return this->get_service().resolve(this->get_implementation(), e, ec);
+ return impl_.get_service().resolve(impl_.get_implementation(), e, ec);
}
/// Asynchronously perform reverse resolution of an endpoint to a list of
@@ -976,9 +923,9 @@ public:
* resolver::results_type results // Resolved endpoints as a range.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* A successful resolve operation is guaranteed to pass a non-empty range to
* the handler.
@@ -989,24 +936,43 @@ public:
async_resolve(const endpoint_type& e,
BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ResolveHandler.
- BOOST_ASIO_RESOLVE_HANDLER_CHECK(
- ResolveHandler, handler, results_type) type_check;
+ return boost::asio::async_initiate<ResolveHandler,
+ void (boost::system::error_code, results_type)>(
+ initiate_async_resolve(), handler, this, e);
+ }
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- return this->get_service().async_resolve(this->get_implementation(), e,
- BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
+private:
+ // Disallow copying and assignment.
+ basic_resolver(const basic_resolver&) BOOST_ASIO_DELETED;
+ basic_resolver& operator=(const basic_resolver&) BOOST_ASIO_DELETED;
- this->get_service().async_resolve(
- this->get_implementation(), e, init.completion_handler);
+ struct initiate_async_resolve
+ {
+ template <typename ResolveHandler, typename Query>
+ void operator()(BOOST_ASIO_MOVE_ARG(ResolveHandler) handler,
+ basic_resolver* self, const Query& q) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ResolveHandler.
+ BOOST_ASIO_RESOLVE_HANDLER_CHECK(
+ ResolveHandler, handler, results_type) type_check;
+
+ boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
+ self->impl_.get_service().async_resolve(
+ self->impl_.get_implementation(), q, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
- return init.result.get();
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
- }
+# if defined(BOOST_ASIO_WINDOWS_RUNTIME)
+ boost::asio::detail::io_object_impl<
+ boost::asio::detail::winrt_resolver_service<InternetProtocol>,
+ Executor> impl_;
+# else
+ boost::asio::detail::io_object_impl<
+ boost::asio::detail::resolver_service<InternetProtocol>,
+ Executor> impl_;
+# endif
};
} // namespace ip
@@ -1015,8 +981,4 @@ public:
#include <boost/asio/detail/pop_options.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_IP_BASIC_RESOLVER_HPP
diff --git a/boost/asio/ip/basic_resolver_entry.hpp b/boost/asio/ip/basic_resolver_entry.hpp
index efaf976577..c00f17a2aa 100644
--- a/boost/asio/ip/basic_resolver_entry.hpp
+++ b/boost/asio/ip/basic_resolver_entry.hpp
@@ -2,7 +2,7 @@
// ip/basic_resolver_entry.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/basic_resolver_iterator.hpp b/boost/asio/ip/basic_resolver_iterator.hpp
index dd93b84149..5564a78d6f 100644
--- a/boost/asio/ip/basic_resolver_iterator.hpp
+++ b/boost/asio/ip/basic_resolver_iterator.hpp
@@ -2,7 +2,7 @@
// ip/basic_resolver_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/basic_resolver_query.hpp b/boost/asio/ip/basic_resolver_query.hpp
index cbbae25ae7..e01597ebee 100644
--- a/boost/asio/ip/basic_resolver_query.hpp
+++ b/boost/asio/ip/basic_resolver_query.hpp
@@ -2,7 +2,7 @@
// ip/basic_resolver_query.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/basic_resolver_results.hpp b/boost/asio/ip/basic_resolver_results.hpp
index f553930cfc..64d1937c17 100644
--- a/boost/asio/ip/basic_resolver_results.hpp
+++ b/boost/asio/ip/basic_resolver_results.hpp
@@ -2,7 +2,7 @@
// ip/basic_resolver_results.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/detail/endpoint.hpp b/boost/asio/ip/detail/endpoint.hpp
index a6f04abed9..690e6b1703 100644
--- a/boost/asio/ip/detail/endpoint.hpp
+++ b/boost/asio/ip/detail/endpoint.hpp
@@ -2,7 +2,7 @@
// ip/detail/endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -34,42 +34,43 @@ class endpoint
{
public:
// Default constructor.
- BOOST_ASIO_DECL endpoint();
+ BOOST_ASIO_DECL endpoint() BOOST_ASIO_NOEXCEPT;
// Construct an endpoint using a family and port number.
- BOOST_ASIO_DECL endpoint(int family, unsigned short port_num);
+ BOOST_ASIO_DECL endpoint(int family,
+ unsigned short port_num) BOOST_ASIO_NOEXCEPT;
// Construct an endpoint using an address and port number.
BOOST_ASIO_DECL endpoint(const boost::asio::ip::address& addr,
- unsigned short port_num);
+ unsigned short port_num) BOOST_ASIO_NOEXCEPT;
// Copy constructor.
- endpoint(const endpoint& other)
+ endpoint(const endpoint& other) BOOST_ASIO_NOEXCEPT
: data_(other.data_)
{
}
// Assign from another endpoint.
- endpoint& operator=(const endpoint& other)
+ endpoint& operator=(const endpoint& other) BOOST_ASIO_NOEXCEPT
{
data_ = other.data_;
return *this;
}
// Get the underlying endpoint in the native type.
- boost::asio::detail::socket_addr_type* data()
+ boost::asio::detail::socket_addr_type* data() BOOST_ASIO_NOEXCEPT
{
return &data_.base;
}
// Get the underlying endpoint in the native type.
- const boost::asio::detail::socket_addr_type* data() const
+ const boost::asio::detail::socket_addr_type* data() const BOOST_ASIO_NOEXCEPT
{
return &data_.base;
}
// Get the underlying size of the endpoint in the native type.
- std::size_t size() const
+ std::size_t size() const BOOST_ASIO_NOEXCEPT
{
if (is_v4())
return sizeof(boost::asio::detail::sockaddr_in4_type);
@@ -81,33 +82,34 @@ public:
BOOST_ASIO_DECL void resize(std::size_t new_size);
// Get the capacity of the endpoint in the native type.
- std::size_t capacity() const
+ std::size_t capacity() const BOOST_ASIO_NOEXCEPT
{
return sizeof(data_);
}
// Get the port associated with the endpoint.
- BOOST_ASIO_DECL unsigned short port() const;
+ BOOST_ASIO_DECL unsigned short port() const BOOST_ASIO_NOEXCEPT;
// Set the port associated with the endpoint.
- BOOST_ASIO_DECL void port(unsigned short port_num);
+ BOOST_ASIO_DECL void port(unsigned short port_num) BOOST_ASIO_NOEXCEPT;
// Get the IP address associated with the endpoint.
- BOOST_ASIO_DECL boost::asio::ip::address address() const;
+ BOOST_ASIO_DECL boost::asio::ip::address address() const BOOST_ASIO_NOEXCEPT;
// Set the IP address associated with the endpoint.
- BOOST_ASIO_DECL void address(const boost::asio::ip::address& addr);
+ BOOST_ASIO_DECL void address(
+ const boost::asio::ip::address& addr) BOOST_ASIO_NOEXCEPT;
// Compare two endpoints for equality.
- BOOST_ASIO_DECL friend bool operator==(
- const endpoint& e1, const endpoint& e2);
+ BOOST_ASIO_DECL friend bool operator==(const endpoint& e1,
+ const endpoint& e2) BOOST_ASIO_NOEXCEPT;
// Compare endpoints for ordering.
- BOOST_ASIO_DECL friend bool operator<(
- const endpoint& e1, const endpoint& e2);
+ BOOST_ASIO_DECL friend bool operator<(const endpoint& e1,
+ const endpoint& e2) BOOST_ASIO_NOEXCEPT;
// Determine whether the endpoint is IPv4.
- bool is_v4() const
+ bool is_v4() const BOOST_ASIO_NOEXCEPT
{
return data_.base.sa_family == BOOST_ASIO_OS_DEF(AF_INET);
}
diff --git a/boost/asio/ip/detail/impl/endpoint.ipp b/boost/asio/ip/detail/impl/endpoint.ipp
index 49f5af116f..9297429999 100644
--- a/boost/asio/ip/detail/impl/endpoint.ipp
+++ b/boost/asio/ip/detail/impl/endpoint.ipp
@@ -2,7 +2,7 @@
// ip/detail/impl/endpoint.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,7 +32,7 @@ namespace asio {
namespace ip {
namespace detail {
-endpoint::endpoint()
+endpoint::endpoint() BOOST_ASIO_NOEXCEPT
: data_()
{
data_.v4.sin_family = BOOST_ASIO_OS_DEF(AF_INET);
@@ -40,7 +40,7 @@ endpoint::endpoint()
data_.v4.sin_addr.s_addr = BOOST_ASIO_OS_DEF(INADDR_ANY);
}
-endpoint::endpoint(int family, unsigned short port_num)
+endpoint::endpoint(int family, unsigned short port_num) BOOST_ASIO_NOEXCEPT
: data_()
{
using namespace std; // For memcpy.
@@ -70,7 +70,7 @@ endpoint::endpoint(int family, unsigned short port_num)
}
endpoint::endpoint(const boost::asio::ip::address& addr,
- unsigned short port_num)
+ unsigned short port_num) BOOST_ASIO_NOEXCEPT
: data_()
{
using namespace std; // For memcpy.
@@ -107,7 +107,7 @@ void endpoint::resize(std::size_t new_size)
}
}
-unsigned short endpoint::port() const
+unsigned short endpoint::port() const BOOST_ASIO_NOEXCEPT
{
if (is_v4())
{
@@ -121,7 +121,7 @@ unsigned short endpoint::port() const
}
}
-void endpoint::port(unsigned short port_num)
+void endpoint::port(unsigned short port_num) BOOST_ASIO_NOEXCEPT
{
if (is_v4())
{
@@ -135,7 +135,7 @@ void endpoint::port(unsigned short port_num)
}
}
-boost::asio::ip::address endpoint::address() const
+boost::asio::ip::address endpoint::address() const BOOST_ASIO_NOEXCEPT
{
using namespace std; // For memcpy.
if (is_v4())
@@ -156,18 +156,18 @@ boost::asio::ip::address endpoint::address() const
}
}
-void endpoint::address(const boost::asio::ip::address& addr)
+void endpoint::address(const boost::asio::ip::address& addr) BOOST_ASIO_NOEXCEPT
{
endpoint tmp_endpoint(addr, port());
data_ = tmp_endpoint.data_;
}
-bool operator==(const endpoint& e1, const endpoint& e2)
+bool operator==(const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT
{
return e1.address() == e2.address() && e1.port() == e2.port();
}
-bool operator<(const endpoint& e1, const endpoint& e2)
+bool operator<(const endpoint& e1, const endpoint& e2) BOOST_ASIO_NOEXCEPT
{
if (e1.address() < e2.address())
return true;
diff --git a/boost/asio/ip/detail/socket_option.hpp b/boost/asio/ip/detail/socket_option.hpp
index ec3ca7e970..7f8b3f586f 100644
--- a/boost/asio/ip/detail/socket_option.hpp
+++ b/boost/asio/ip/detail/socket_option.hpp
@@ -2,7 +2,7 @@
// detail/socket_option.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/host_name.hpp b/boost/asio/ip/host_name.hpp
index c1e4e0cf8b..bb893ef24b 100644
--- a/boost/asio/ip/host_name.hpp
+++ b/boost/asio/ip/host_name.hpp
@@ -2,7 +2,7 @@
// ip/host_name.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/icmp.hpp b/boost/asio/ip/icmp.hpp
index 4b9d642048..229529f770 100644
--- a/boost/asio/ip/icmp.hpp
+++ b/boost/asio/ip/icmp.hpp
@@ -2,7 +2,7 @@
// ip/icmp.hpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/address.hpp b/boost/asio/ip/impl/address.hpp
index cf5afb4fcf..63f6b2e0ac 100644
--- a/boost/asio/ip/impl/address.hpp
+++ b/boost/asio/ip/impl/address.hpp
@@ -2,7 +2,7 @@
// ip/impl/address.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/address.ipp b/boost/asio/ip/impl/address.ipp
index 9afa566a35..2dc55290b0 100644
--- a/boost/asio/ip/impl/address.ipp
+++ b/boost/asio/ip/impl/address.ipp
@@ -2,7 +2,7 @@
// ip/impl/address.ipp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -30,28 +30,30 @@ namespace boost {
namespace asio {
namespace ip {
-address::address()
+address::address() BOOST_ASIO_NOEXCEPT
: type_(ipv4),
ipv4_address_(),
ipv6_address_()
{
}
-address::address(const boost::asio::ip::address_v4& ipv4_address)
+address::address(
+ const boost::asio::ip::address_v4& ipv4_address) BOOST_ASIO_NOEXCEPT
: type_(ipv4),
ipv4_address_(ipv4_address),
ipv6_address_()
{
}
-address::address(const boost::asio::ip::address_v6& ipv6_address)
+address::address(
+ const boost::asio::ip::address_v6& ipv6_address) BOOST_ASIO_NOEXCEPT
: type_(ipv6),
ipv4_address_(),
ipv6_address_(ipv6_address)
{
}
-address::address(const address& other)
+address::address(const address& other) BOOST_ASIO_NOEXCEPT
: type_(other.type_),
ipv4_address_(other.ipv4_address_),
ipv6_address_(other.ipv6_address_)
@@ -59,7 +61,7 @@ address::address(const address& other)
}
#if defined(BOOST_ASIO_HAS_MOVE)
-address::address(address&& other)
+address::address(address&& other) BOOST_ASIO_NOEXCEPT
: type_(other.type_),
ipv4_address_(other.ipv4_address_),
ipv6_address_(other.ipv6_address_)
@@ -67,7 +69,7 @@ address::address(address&& other)
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
-address& address::operator=(const address& other)
+address& address::operator=(const address& other) BOOST_ASIO_NOEXCEPT
{
type_ = other.type_;
ipv4_address_ = other.ipv4_address_;
@@ -76,7 +78,7 @@ address& address::operator=(const address& other)
}
#if defined(BOOST_ASIO_HAS_MOVE)
-address& address::operator=(address&& other)
+address& address::operator=(address&& other) BOOST_ASIO_NOEXCEPT
{
type_ = other.type_;
ipv4_address_ = other.ipv4_address_;
@@ -85,7 +87,8 @@ address& address::operator=(address&& other)
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
-address& address::operator=(const boost::asio::ip::address_v4& ipv4_address)
+address& address::operator=(
+ const boost::asio::ip::address_v4& ipv4_address) BOOST_ASIO_NOEXCEPT
{
type_ = ipv4;
ipv4_address_ = ipv4_address;
@@ -93,7 +96,8 @@ address& address::operator=(const boost::asio::ip::address_v4& ipv4_address)
return *this;
}
-address& address::operator=(const boost::asio::ip::address_v6& ipv6_address)
+address& address::operator=(
+ const boost::asio::ip::address_v6& ipv6_address) BOOST_ASIO_NOEXCEPT
{
type_ = ipv6;
ipv4_address_ = boost::asio::ip::address_v4();
@@ -109,7 +113,8 @@ address make_address(const char* str)
return addr;
}
-address make_address(const char* str, boost::system::error_code& ec)
+address make_address(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
boost::asio::ip::address_v6 ipv6_address =
boost::asio::ip::make_address_v6(str, ec);
@@ -130,7 +135,7 @@ address make_address(const std::string& str)
}
address make_address(const std::string& str,
- boost::system::error_code& ec)
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address(str.c_str(), ec);
}
@@ -143,7 +148,7 @@ address make_address(string_view str)
}
address make_address(string_view str,
- boost::system::error_code& ec)
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address(static_cast<std::string>(str), ec);
}
@@ -186,28 +191,28 @@ std::string address::to_string(boost::system::error_code& ec) const
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-bool address::is_loopback() const
+bool address::is_loopback() const BOOST_ASIO_NOEXCEPT
{
return (type_ == ipv4)
? ipv4_address_.is_loopback()
: ipv6_address_.is_loopback();
}
-bool address::is_unspecified() const
+bool address::is_unspecified() const BOOST_ASIO_NOEXCEPT
{
return (type_ == ipv4)
? ipv4_address_.is_unspecified()
: ipv6_address_.is_unspecified();
}
-bool address::is_multicast() const
+bool address::is_multicast() const BOOST_ASIO_NOEXCEPT
{
return (type_ == ipv4)
? ipv4_address_.is_multicast()
: ipv6_address_.is_multicast();
}
-bool operator==(const address& a1, const address& a2)
+bool operator==(const address& a1, const address& a2) BOOST_ASIO_NOEXCEPT
{
if (a1.type_ != a2.type_)
return false;
@@ -216,7 +221,7 @@ bool operator==(const address& a1, const address& a2)
return a1.ipv4_address_ == a2.ipv4_address_;
}
-bool operator<(const address& a1, const address& a2)
+bool operator<(const address& a1, const address& a2) BOOST_ASIO_NOEXCEPT
{
if (a1.type_ < a2.type_)
return true;
diff --git a/boost/asio/ip/impl/address_v4.hpp b/boost/asio/ip/impl/address_v4.hpp
index 838dc613e2..98bd89d89f 100644
--- a/boost/asio/ip/impl/address_v4.hpp
+++ b/boost/asio/ip/impl/address_v4.hpp
@@ -2,7 +2,7 @@
// ip/impl/address_v4.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/address_v4.ipp b/boost/asio/ip/impl/address_v4.ipp
index 7693deaf40..c572100a8b 100644
--- a/boost/asio/ip/impl/address_v4.ipp
+++ b/boost/asio/ip/impl/address_v4.ipp
@@ -2,7 +2,7 @@
// ip/impl/address_v4.ipp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -58,7 +58,7 @@ address_v4::address_v4(address_v4::uint_type addr)
static_cast<boost::asio::detail::u_long_type>(addr));
}
-address_v4::bytes_type address_v4::to_bytes() const
+address_v4::bytes_type address_v4::to_bytes() const BOOST_ASIO_NOEXCEPT
{
using namespace std; // For memcpy.
bytes_type bytes;
@@ -70,7 +70,7 @@ address_v4::bytes_type address_v4::to_bytes() const
return bytes;
}
-address_v4::uint_type address_v4::to_uint() const
+address_v4::uint_type address_v4::to_uint() const BOOST_ASIO_NOEXCEPT
{
return boost::asio::detail::socket_ops::network_to_host_long(addr_.s_addr);
}
@@ -109,12 +109,12 @@ std::string address_v4::to_string(boost::system::error_code& ec) const
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-bool address_v4::is_loopback() const
+bool address_v4::is_loopback() const BOOST_ASIO_NOEXCEPT
{
return (to_uint() & 0xFF000000) == 0x7F000000;
}
-bool address_v4::is_unspecified() const
+bool address_v4::is_unspecified() const BOOST_ASIO_NOEXCEPT
{
return to_uint() == 0;
}
@@ -136,7 +136,7 @@ bool address_v4::is_class_c() const
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-bool address_v4::is_multicast() const
+bool address_v4::is_multicast() const BOOST_ASIO_NOEXCEPT
{
return (to_uint() & 0xF0000000) == 0xE0000000;
}
@@ -167,8 +167,8 @@ address_v4 make_address_v4(const char* str)
return addr;
}
-address_v4 make_address_v4(
- const char* str, boost::system::error_code& ec)
+address_v4 make_address_v4(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
address_v4::bytes_type bytes;
if (boost::asio::detail::socket_ops::inet_pton(
@@ -182,8 +182,8 @@ address_v4 make_address_v4(const std::string& str)
return make_address_v4(str.c_str());
}
-address_v4 make_address_v4(
- const std::string& str, boost::system::error_code& ec)
+address_v4 make_address_v4(const std::string& str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address_v4(str.c_str(), ec);
}
@@ -196,7 +196,7 @@ address_v4 make_address_v4(string_view str)
}
address_v4 make_address_v4(string_view str,
- boost::system::error_code& ec)
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address_v4(static_cast<std::string>(str), ec);
}
diff --git a/boost/asio/ip/impl/address_v6.hpp b/boost/asio/ip/impl/address_v6.hpp
index f989b6a702..ebfd467e0f 100644
--- a/boost/asio/ip/impl/address_v6.hpp
+++ b/boost/asio/ip/impl/address_v6.hpp
@@ -2,7 +2,7 @@
// ip/impl/address_v6.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/address_v6.ipp b/boost/asio/ip/impl/address_v6.ipp
index 4eea4bc5a0..7ea2f24e1f 100644
--- a/boost/asio/ip/impl/address_v6.ipp
+++ b/boost/asio/ip/impl/address_v6.ipp
@@ -2,7 +2,7 @@
// ip/impl/address_v6.ipp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,7 +32,7 @@ namespace boost {
namespace asio {
namespace ip {
-address_v6::address_v6()
+address_v6::address_v6() BOOST_ASIO_NOEXCEPT
: addr_(),
scope_id_(0)
{
@@ -57,21 +57,21 @@ address_v6::address_v6(const address_v6::bytes_type& bytes,
memcpy(addr_.s6_addr, bytes.data(), 16);
}
-address_v6::address_v6(const address_v6& other)
+address_v6::address_v6(const address_v6& other) BOOST_ASIO_NOEXCEPT
: addr_(other.addr_),
scope_id_(other.scope_id_)
{
}
#if defined(BOOST_ASIO_HAS_MOVE)
-address_v6::address_v6(address_v6&& other)
+address_v6::address_v6(address_v6&& other) BOOST_ASIO_NOEXCEPT
: addr_(other.addr_),
scope_id_(other.scope_id_)
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
-address_v6& address_v6::operator=(const address_v6& other)
+address_v6& address_v6::operator=(const address_v6& other) BOOST_ASIO_NOEXCEPT
{
addr_ = other.addr_;
scope_id_ = other.scope_id_;
@@ -79,7 +79,7 @@ address_v6& address_v6::operator=(const address_v6& other)
}
#if defined(BOOST_ASIO_HAS_MOVE)
-address_v6& address_v6::operator=(address_v6&& other)
+address_v6& address_v6::operator=(address_v6&& other) BOOST_ASIO_NOEXCEPT
{
addr_ = other.addr_;
scope_id_ = other.scope_id_;
@@ -87,7 +87,7 @@ address_v6& address_v6::operator=(address_v6&& other)
}
#endif // defined(BOOST_ASIO_HAS_MOVE)
-address_v6::bytes_type address_v6::to_bytes() const
+address_v6::bytes_type address_v6::to_bytes() const BOOST_ASIO_NOEXCEPT
{
using namespace std; // For memcpy.
bytes_type bytes;
@@ -139,7 +139,7 @@ address_v4 address_v6::to_v4() const
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-bool address_v6::is_loopback() const
+bool address_v6::is_loopback() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
@@ -151,7 +151,7 @@ bool address_v6::is_loopback() const
&& (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 1));
}
-bool address_v6::is_unspecified() const
+bool address_v6::is_unspecified() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
@@ -163,17 +163,17 @@ bool address_v6::is_unspecified() const
&& (addr_.s6_addr[14] == 0) && (addr_.s6_addr[15] == 0));
}
-bool address_v6::is_link_local() const
+bool address_v6::is_link_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0x80));
}
-bool address_v6::is_site_local() const
+bool address_v6::is_site_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xfe) && ((addr_.s6_addr[1] & 0xc0) == 0xc0));
}
-bool address_v6::is_v4_mapped() const
+bool address_v6::is_v4_mapped() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0) && (addr_.s6_addr[1] == 0)
&& (addr_.s6_addr[2] == 0) && (addr_.s6_addr[3] == 0)
@@ -199,37 +199,37 @@ bool address_v6::is_v4_compatible() const
}
#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-bool address_v6::is_multicast() const
+bool address_v6::is_multicast() const BOOST_ASIO_NOEXCEPT
{
return (addr_.s6_addr[0] == 0xff);
}
-bool address_v6::is_multicast_global() const
+bool address_v6::is_multicast_global() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x0e));
}
-bool address_v6::is_multicast_link_local() const
+bool address_v6::is_multicast_link_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x02));
}
-bool address_v6::is_multicast_node_local() const
+bool address_v6::is_multicast_node_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x01));
}
-bool address_v6::is_multicast_org_local() const
+bool address_v6::is_multicast_org_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x08));
}
-bool address_v6::is_multicast_site_local() const
+bool address_v6::is_multicast_site_local() const BOOST_ASIO_NOEXCEPT
{
return ((addr_.s6_addr[0] == 0xff) && ((addr_.s6_addr[1] & 0x0f) == 0x05));
}
-bool operator==(const address_v6& a1, const address_v6& a2)
+bool operator==(const address_v6& a1, const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
using namespace std; // For memcmp.
return memcmp(&a1.addr_, &a2.addr_,
@@ -237,7 +237,7 @@ bool operator==(const address_v6& a1, const address_v6& a2)
&& a1.scope_id_ == a2.scope_id_;
}
-bool operator<(const address_v6& a1, const address_v6& a2)
+bool operator<(const address_v6& a1, const address_v6& a2) BOOST_ASIO_NOEXCEPT
{
using namespace std; // For memcmp.
int memcmp_result = memcmp(&a1.addr_, &a2.addr_,
@@ -249,7 +249,7 @@ bool operator<(const address_v6& a1, const address_v6& a2)
return a1.scope_id_ < a2.scope_id_;
}
-address_v6 address_v6::loopback()
+address_v6 address_v6::loopback() BOOST_ASIO_NOEXCEPT
{
address_v6 tmp;
tmp.addr_.s6_addr[15] = 1;
@@ -282,8 +282,8 @@ address_v6 make_address_v6(const char* str)
return addr;
}
-address_v6 make_address_v6(
- const char* str, boost::system::error_code& ec)
+address_v6 make_address_v6(const char* str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
address_v6::bytes_type bytes;
unsigned long scope_id = 0;
@@ -298,8 +298,8 @@ address_v6 make_address_v6(const std::string& str)
return make_address_v6(str.c_str());
}
-address_v6 make_address_v6(
- const std::string& str, boost::system::error_code& ec)
+address_v6 make_address_v6(const std::string& str,
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address_v6(str.c_str(), ec);
}
@@ -312,7 +312,7 @@ address_v6 make_address_v6(string_view str)
}
address_v6 make_address_v6(string_view str,
- boost::system::error_code& ec)
+ boost::system::error_code& ec) BOOST_ASIO_NOEXCEPT
{
return make_address_v6(static_cast<std::string>(str), ec);
}
diff --git a/boost/asio/ip/impl/basic_endpoint.hpp b/boost/asio/ip/impl/basic_endpoint.hpp
index 23655bf940..5eba925242 100644
--- a/boost/asio/ip/impl/basic_endpoint.hpp
+++ b/boost/asio/ip/impl/basic_endpoint.hpp
@@ -2,7 +2,7 @@
// ip/impl/basic_endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/host_name.ipp b/boost/asio/ip/impl/host_name.ipp
index 17b8395a76..565e5459a3 100644
--- a/boost/asio/ip/impl/host_name.ipp
+++ b/boost/asio/ip/impl/host_name.ipp
@@ -2,7 +2,7 @@
// ip/impl/host_name.ipp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/network_v4.hpp b/boost/asio/ip/impl/network_v4.hpp
index 3ca4e746bd..e20a6fefc9 100644
--- a/boost/asio/ip/impl/network_v4.hpp
+++ b/boost/asio/ip/impl/network_v4.hpp
@@ -2,7 +2,7 @@
// ip/impl/network_v4.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/impl/network_v4.ipp b/boost/asio/ip/impl/network_v4.ipp
index 62f742c669..d443475183 100644
--- a/boost/asio/ip/impl/network_v4.ipp
+++ b/boost/asio/ip/impl/network_v4.ipp
@@ -2,7 +2,7 @@
// ip/impl/network_v4.ipp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/impl/network_v6.hpp b/boost/asio/ip/impl/network_v6.hpp
index 1b13879ea3..6be5ab533f 100644
--- a/boost/asio/ip/impl/network_v6.hpp
+++ b/boost/asio/ip/impl/network_v6.hpp
@@ -2,7 +2,7 @@
// ip/impl/network_v6.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/impl/network_v6.ipp b/boost/asio/ip/impl/network_v6.ipp
index 426bc33b39..cbdb974489 100644
--- a/boost/asio/ip/impl/network_v6.ipp
+++ b/boost/asio/ip/impl/network_v6.ipp
@@ -2,7 +2,7 @@
// ip/impl/network_v6.ipp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/multicast.hpp b/boost/asio/ip/multicast.hpp
index d46692c268..d863284192 100644
--- a/boost/asio/ip/multicast.hpp
+++ b/boost/asio/ip/multicast.hpp
@@ -2,7 +2,7 @@
// ip/multicast.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -33,7 +33,7 @@ namespace multicast {
* @par Examples
* Setting the option to join a multicast group:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::address multicast_address =
* boost::asio::ip::address::from_string("225.0.0.1");
@@ -61,7 +61,7 @@ typedef boost::asio::ip::detail::socket_option::multicast_request<
* @par Examples
* Setting the option to leave a multicast group:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::address multicast_address =
* boost::asio::ip::address::from_string("225.0.0.1");
@@ -89,7 +89,7 @@ typedef boost::asio::ip::detail::socket_option::multicast_request<
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::address_v4 local_interface =
* boost::asio::ip::address_v4::from_string("1.2.3.4");
@@ -117,7 +117,7 @@ typedef boost::asio::ip::detail::socket_option::network_interface<
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::multicast::hops option(4);
* socket.set_option(option);
@@ -126,7 +126,7 @@ typedef boost::asio::ip::detail::socket_option::network_interface<
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::multicast::hops option;
* socket.get_option(option);
@@ -154,7 +154,7 @@ typedef boost::asio::ip::detail::socket_option::multicast_hops<
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::multicast::enable_loopback option(true);
* socket.set_option(option);
@@ -163,7 +163,7 @@ typedef boost::asio::ip::detail::socket_option::multicast_hops<
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::multicast::enable_loopback option;
* socket.get_option(option);
diff --git a/boost/asio/ip/network_v4.hpp b/boost/asio/ip/network_v4.hpp
index 24e67b8371..25cbbce69f 100644
--- a/boost/asio/ip/network_v4.hpp
+++ b/boost/asio/ip/network_v4.hpp
@@ -2,7 +2,7 @@
// ip/network_v4.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/network_v6.hpp b/boost/asio/ip/network_v6.hpp
index 5fe96743df..dce950870b 100644
--- a/boost/asio/ip/network_v6.hpp
+++ b/boost/asio/ip/network_v6.hpp
@@ -2,7 +2,7 @@
// ip/network_v6.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2014 Oliver Kowalke (oliver dot kowalke at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/ip/resolver_base.hpp b/boost/asio/ip/resolver_base.hpp
index 06cbcd0220..a61565fdc1 100644
--- a/boost/asio/ip/resolver_base.hpp
+++ b/boost/asio/ip/resolver_base.hpp
@@ -2,7 +2,7 @@
// ip/resolver_base.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/resolver_query_base.hpp b/boost/asio/ip/resolver_query_base.hpp
index 1e287c6225..9e0a0321a5 100644
--- a/boost/asio/ip/resolver_query_base.hpp
+++ b/boost/asio/ip/resolver_query_base.hpp
@@ -2,7 +2,7 @@
// ip/resolver_query_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/resolver_service.hpp b/boost/asio/ip/resolver_service.hpp
deleted file mode 100644
index 3e1fd38a70..0000000000
--- a/boost/asio/ip/resolver_service.hpp
+++ /dev/null
@@ -1,202 +0,0 @@
-//
-// ip/resolver_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_RESOLVER_SERVICE_HPP
-#define BOOST_ASIO_IP_RESOLVER_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_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/async_result.hpp>
-#include <boost/system/error_code.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/ip/basic_resolver_iterator.hpp>
-#include <boost/asio/ip/basic_resolver_query.hpp>
-#include <boost/asio/ip/basic_resolver_results.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_resolver_service.hpp>
-#else
-# include <boost/asio/detail/resolver_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace ip {
-
-/// Default service implementation for a resolver.
-template <typename InternetProtocol>
-class resolver_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<
- resolver_service<InternetProtocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef InternetProtocol protocol_type;
-
- /// The endpoint type.
- typedef typename InternetProtocol::endpoint endpoint_type;
-
- /// The query type.
- typedef basic_resolver_query<InternetProtocol> query_type;
-
- /// The iterator type.
- typedef basic_resolver_iterator<InternetProtocol> iterator_type;
-
- /// The results type.
- typedef basic_resolver_results<InternetProtocol> results_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef boost::asio::detail::winrt_resolver_service<InternetProtocol>
- service_impl_type;
-#else
- typedef boost::asio::detail::resolver_service<InternetProtocol>
- service_impl_type;
-#endif
-
-public:
- /// The type of a resolver implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// Construct a new resolver service for the specified io_context.
- explicit resolver_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- resolver_service<InternetProtocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new resolver implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new resolver implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another resolver implementation.
- void move_assign(implementation_type& impl,
- resolver_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a resolver implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Cancel pending asynchronous operations.
- void cancel(implementation_type& impl)
- {
- service_impl_.cancel(impl);
- }
-
- /// Resolve a query to a list of entries.
- results_type resolve(implementation_type& impl, const query_type& query,
- boost::system::error_code& ec)
- {
- return service_impl_.resolve(impl, query, ec);
- }
-
- /// Asynchronously resolve a query to a list of entries.
- template <typename ResolveHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
- void (boost::system::error_code, results_type))
- async_resolve(implementation_type& impl, const query_type& query,
- BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
- {
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
-
- service_impl_.async_resolve(impl, query, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Resolve an endpoint to a list of entries.
- results_type resolve(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- return service_impl_.resolve(impl, endpoint, ec);
- }
-
- /// Asynchronously resolve an endpoint to a list of entries.
- template <typename ResolveHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ResolveHandler,
- void (boost::system::error_code, results_type))
- async_resolve(implementation_type& impl, const endpoint_type& endpoint,
- BOOST_ASIO_MOVE_ARG(ResolveHandler) handler)
- {
- boost::asio::async_completion<ResolveHandler,
- void (boost::system::error_code, results_type)> init(handler);
-
- service_impl_.async_resolve(impl, endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // Perform any fork-related housekeeping.
- void notify_fork(boost::asio::io_context::fork_event event)
- {
- service_impl_.notify_fork(event);
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace ip
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_IP_RESOLVER_SERVICE_HPP
diff --git a/boost/asio/ip/tcp.hpp b/boost/asio/ip/tcp.hpp
index dce1c8ee6a..d37b012b3c 100644
--- a/boost/asio/ip/tcp.hpp
+++ b/boost/asio/ip/tcp.hpp
@@ -2,7 +2,7 @@
// ip/tcp.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -100,7 +100,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::no_delay option(true);
* socket.set_option(option);
@@ -109,7 +109,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::tcp::no_delay option;
* socket.get_option(option);
diff --git a/boost/asio/ip/udp.hpp b/boost/asio/ip/udp.hpp
index 9f07a55e7e..8ba20b4e62 100644
--- a/boost/asio/ip/udp.hpp
+++ b/boost/asio/ip/udp.hpp
@@ -2,7 +2,7 @@
// ip/udp.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ip/unicast.hpp b/boost/asio/ip/unicast.hpp
index 793c5f7eb4..2cfcc59601 100644
--- a/boost/asio/ip/unicast.hpp
+++ b/boost/asio/ip/unicast.hpp
@@ -2,7 +2,7 @@
// ip/unicast.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -33,7 +33,7 @@ namespace unicast {
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::unicast::hops option(4);
* socket.set_option(option);
@@ -42,7 +42,7 @@ namespace unicast {
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::ip::unicast::hops option;
* socket.get_option(option);
diff --git a/boost/asio/ip/v6_only.hpp b/boost/asio/ip/v6_only.hpp
index c2f34acc11..54f4706430 100644
--- a/boost/asio/ip/v6_only.hpp
+++ b/boost/asio/ip/v6_only.hpp
@@ -2,7 +2,7 @@
// ip/v6_only.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,7 +32,7 @@ namespace ip {
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::v6_only option(true);
* socket.set_option(option);
@@ -41,7 +41,7 @@ namespace ip {
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::ip::v6_only option;
* socket.get_option(option);
diff --git a/boost/asio/is_executor.hpp b/boost/asio/is_executor.hpp
index 8570475241..6cb8bb8380 100644
--- a/boost/asio/is_executor.hpp
+++ b/boost/asio/is_executor.hpp
@@ -2,7 +2,7 @@
// is_executor.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/is_read_buffered.hpp b/boost/asio/is_read_buffered.hpp
index 4839bc53a7..bc97ba77f5 100644
--- a/boost/asio/is_read_buffered.hpp
+++ b/boost/asio/is_read_buffered.hpp
@@ -2,7 +2,7 @@
// is_read_buffered.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/is_write_buffered.hpp b/boost/asio/is_write_buffered.hpp
index f18e981ba8..5ed8318e53 100644
--- a/boost/asio/is_write_buffered.hpp
+++ b/boost/asio/is_write_buffered.hpp
@@ -2,7 +2,7 @@
// is_write_buffered.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/local/basic_endpoint.hpp b/boost/asio/local/basic_endpoint.hpp
index 248c4a809e..835eb20922 100644
--- a/boost/asio/local/basic_endpoint.hpp
+++ b/boost/asio/local/basic_endpoint.hpp
@@ -2,7 +2,7 @@
// local/basic_endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
@@ -77,6 +77,14 @@ public:
{
}
+ #if defined(BOOST_ASIO_HAS_STRING_VIEW)
+ /// Construct an endpoint using the specified path name.
+ basic_endpoint(string_view path_name)
+ : impl_(path_name)
+ {
+ }
+ #endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
+
/// Copy constructor.
basic_endpoint(const basic_endpoint& other)
: impl_(other.impl_)
diff --git a/boost/asio/local/connect_pair.hpp b/boost/asio/local/connect_pair.hpp
index 10a3f6d2b1..6ee9a23ae3 100644
--- a/boost/asio/local/connect_pair.hpp
+++ b/boost/asio/local/connect_pair.hpp
@@ -2,7 +2,7 @@
// local/connect_pair.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -33,33 +33,28 @@ namespace asio {
namespace local {
/// Create a pair of connected sockets.
-template <typename Protocol BOOST_ASIO_SVC_TPARAM BOOST_ASIO_SVC_TPARAM1>
-void connect_pair(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket1,
- basic_socket<Protocol BOOST_ASIO_SVC_TARG1>& socket2);
+template <typename Protocol, typename Executor1, typename Executor2>
+void connect_pair(basic_socket<Protocol, Executor1>& socket1,
+ basic_socket<Protocol, Executor2>& socket2);
/// Create a pair of connected sockets.
-template <typename Protocol BOOST_ASIO_SVC_TPARAM BOOST_ASIO_SVC_TPARAM1>
-BOOST_ASIO_SYNC_OP_VOID connect_pair(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket1,
- basic_socket<Protocol BOOST_ASIO_SVC_TARG1>& socket2,
- boost::system::error_code& ec);
-
-template <typename Protocol BOOST_ASIO_SVC_TPARAM BOOST_ASIO_SVC_TPARAM1>
-inline void connect_pair(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket1,
- basic_socket<Protocol BOOST_ASIO_SVC_TARG1>& socket2)
+template <typename Protocol, typename Executor1, typename Executor2>
+BOOST_ASIO_SYNC_OP_VOID connect_pair(basic_socket<Protocol, Executor1>& socket1,
+ basic_socket<Protocol, Executor2>& socket2, boost::system::error_code& ec);
+
+template <typename Protocol, typename Executor1, typename Executor2>
+inline void connect_pair(basic_socket<Protocol, Executor1>& socket1,
+ basic_socket<Protocol, Executor2>& socket2)
{
boost::system::error_code ec;
connect_pair(socket1, socket2, ec);
boost::asio::detail::throw_error(ec, "connect_pair");
}
-template <typename Protocol BOOST_ASIO_SVC_TPARAM BOOST_ASIO_SVC_TPARAM1>
+template <typename Protocol, typename Executor1, typename Executor2>
inline BOOST_ASIO_SYNC_OP_VOID connect_pair(
- basic_socket<Protocol BOOST_ASIO_SVC_TARG>& socket1,
- basic_socket<Protocol BOOST_ASIO_SVC_TARG1>& socket2,
- boost::system::error_code& ec)
+ basic_socket<Protocol, Executor1>& socket1,
+ basic_socket<Protocol, Executor2>& socket2, boost::system::error_code& ec)
{
// Check that this function is only being used with a UNIX domain socket.
boost::asio::local::basic_endpoint<Protocol>* tmp
diff --git a/boost/asio/local/datagram_protocol.hpp b/boost/asio/local/datagram_protocol.hpp
index c664323013..b29add6fc5 100644
--- a/boost/asio/local/datagram_protocol.hpp
+++ b/boost/asio/local/datagram_protocol.hpp
@@ -2,7 +2,7 @@
// local/datagram_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/local/detail/endpoint.hpp b/boost/asio/local/detail/endpoint.hpp
index 52d6246ae9..294fb95ef9 100644
--- a/boost/asio/local/detail/endpoint.hpp
+++ b/boost/asio/local/detail/endpoint.hpp
@@ -2,7 +2,7 @@
// local/detail/endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
@@ -23,6 +23,7 @@
#include <cstddef>
#include <string>
#include <boost/asio/detail/socket_types.hpp>
+#include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/push_options.hpp>
@@ -44,6 +45,11 @@ public:
// Construct an endpoint using the specified path name.
BOOST_ASIO_DECL endpoint(const std::string& path_name);
+ #if defined(BOOST_ASIO_HAS_STRING_VIEW)
+ // Construct an endpoint using the specified path name.
+ BOOST_ASIO_DECL endpoint(string_view path_name);
+ #endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
+
// Copy constructor.
endpoint(const endpoint& other)
: data_(other.data_),
diff --git a/boost/asio/local/detail/impl/endpoint.ipp b/boost/asio/local/detail/impl/endpoint.ipp
index 3d6a800414..51ce2cf36d 100644
--- a/boost/asio/local/detail/impl/endpoint.ipp
+++ b/boost/asio/local/detail/impl/endpoint.ipp
@@ -2,7 +2,7 @@
// local/detail/impl/endpoint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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
@@ -49,6 +49,13 @@ endpoint::endpoint(const std::string& path_name)
init(path_name.data(), path_name.length());
}
+#if defined(BOOST_ASIO_HAS_STRING_VIEW)
+endpoint::endpoint(string_view path_name)
+{
+ init(path_name.data(), path_name.length());
+}
+#endif // defined(BOOST_ASIO_HAS_STRING_VIEW)
+
void endpoint::resize(std::size_t new_size)
{
if (new_size > sizeof(boost::asio::detail::sockaddr_un_type))
diff --git a/boost/asio/local/stream_protocol.hpp b/boost/asio/local/stream_protocol.hpp
index 65fdbf1a90..4fe0de5352 100644
--- a/boost/asio/local/stream_protocol.hpp
+++ b/boost/asio/local/stream_protocol.hpp
@@ -2,7 +2,7 @@
// local/stream_protocol.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/packaged_task.hpp b/boost/asio/packaged_task.hpp
index 4928a1cc7a..0985e6d49b 100644
--- a/boost/asio/packaged_task.hpp
+++ b/boost/asio/packaged_task.hpp
@@ -2,7 +2,7 @@
// packaged_task.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/placeholders.hpp b/boost/asio/placeholders.hpp
index 50e399ed28..3640bd62b5 100644
--- a/boost/asio/placeholders.hpp
+++ b/boost/asio/placeholders.hpp
@@ -2,7 +2,7 @@
// placeholders.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/posix/basic_descriptor.hpp b/boost/asio/posix/basic_descriptor.hpp
index faf5b6def2..301c618e4d 100644
--- a/boost/asio/posix/basic_descriptor.hpp
+++ b/boost/asio/posix/basic_descriptor.hpp
@@ -2,7 +2,7 @@
// posix/basic_descriptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,16 +17,24 @@
#include <boost/asio/detail/config.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
|| defined(GENERATING_DOCUMENTATION)
-#include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
+#include <boost/asio/detail/reactive_descriptor_service.hpp>
#include <boost/asio/detail/throw_error.hpp>
#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
#include <boost/asio/posix/descriptor_base.hpp>
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -42,37 +50,61 @@ namespace posix {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename DescriptorService>
+template <typename Executor = executor>
class basic_descriptor
- : public basic_io_object<DescriptorService>,
- public descriptor_base
+ : public descriptor_base
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a descriptor.
- typedef typename DescriptorService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef detail::reactive_descriptor_service::native_handle_type
+ native_handle_type;
+#endif
- /// A basic_descriptor is always the lowest layer.
- typedef basic_descriptor<DescriptorService> lowest_layer_type;
+ /// A descriptor is always the lowest layer.
+ typedef basic_descriptor lowest_layer_type;
- /// Construct a basic_descriptor without opening it.
+ /// Construct a descriptor without opening it.
/**
* This constructor creates a descriptor without opening it.
*
- * @param io_context The io_context object that the descriptor will use to
+ * @param ex The I/O executor that the descriptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* descriptor.
*/
- explicit basic_descriptor(boost::asio::io_context& io_context)
- : basic_io_object<DescriptorService>(io_context)
+ explicit basic_descriptor(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Construct a descriptor without opening it.
+ /**
+ * This constructor creates a descriptor without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the descriptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the descriptor.
+ */
+ template <typename ExecutionContext>
+ explicit basic_descriptor(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
}
- /// Construct a basic_descriptor on an existing native descriptor.
+ /// Construct a descriptor on an existing native descriptor.
/**
* This constructor creates a descriptor object to hold an existing native
* descriptor.
*
- * @param io_context The io_context object that the descriptor will use to
+ * @param ex The I/O executor that the descriptor will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* descriptor.
*
@@ -80,55 +112,88 @@ public:
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_descriptor(boost::asio::io_context& io_context,
+ basic_descriptor(const executor_type& ex,
const native_handle_type& native_descriptor)
- : basic_io_object<DescriptorService>(io_context)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(),
+ native_descriptor, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct a descriptor on an existing native descriptor.
+ /**
+ * This constructor creates a descriptor object to hold an existing native
+ * descriptor.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the descriptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the descriptor.
+ *
+ * @param native_descriptor A native descriptor.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_descriptor(ExecutionContext& context,
+ const native_handle_type& native_descriptor,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
native_descriptor, ec);
boost::asio::detail::throw_error(ec, "assign");
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_descriptor from another.
+ /// Move-construct a descriptor from another.
/**
* This constructor moves a descriptor from one object to another.
*
- * @param other The other basic_descriptor object from which the move will
+ * @param other The other descriptor object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_descriptor(io_context&) constructor.
+ * constructed using the @c basic_descriptor(const executor_type&)
+ * constructor.
*/
basic_descriptor(basic_descriptor&& other)
- : basic_io_object<DescriptorService>(
- BOOST_ASIO_MOVE_CAST(basic_descriptor)(other))
+ : impl_(std::move(other.impl_))
{
}
- /// Move-assign a basic_descriptor from another.
+ /// Move-assign a descriptor from another.
/**
* This assignment operator moves a descriptor from one object to another.
*
- * @param other The other basic_descriptor object from which the move will
+ * @param other The other descriptor object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_descriptor(io_context&) constructor.
+ * constructed using the @c basic_descriptor(const executor_type&)
+ * constructor.
*/
basic_descriptor& operator=(basic_descriptor&& other)
{
- basic_io_object<DescriptorService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_descriptor)(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
/// Get a reference to the lowest layer.
/**
* This function returns a reference to the lowest layer in a stack of
- * layers. Since a basic_descriptor cannot contain any further layers, it
+ * layers. Since a descriptor cannot contain any further layers, it
* simply returns a reference to itself.
*
* @return A reference to the lowest layer in the stack of layers. Ownership
@@ -142,7 +207,7 @@ public:
/// Get a const reference to the lowest layer.
/**
* This function returns a const reference to the lowest layer in a stack of
- * layers. Since a basic_descriptor cannot contain any further layers, it
+ * layers. Since a descriptor cannot contain any further layers, it
* simply returns a reference to itself.
*
* @return A const reference to the lowest layer in the stack of layers.
@@ -164,7 +229,7 @@ public:
void assign(const native_handle_type& native_descriptor)
{
boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
+ impl_.get_service().assign(impl_.get_implementation(),
native_descriptor, ec);
boost::asio::detail::throw_error(ec, "assign");
}
@@ -180,15 +245,15 @@ public:
BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor,
boost::system::error_code& ec)
{
- this->get_service().assign(
- this->get_implementation(), native_descriptor, ec);
+ impl_.get_service().assign(
+ impl_.get_implementation(), native_descriptor, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the descriptor is open.
bool is_open() const
{
- return this->get_service().is_open(this->get_implementation());
+ return impl_.get_service().is_open(impl_.get_implementation());
}
/// Close the descriptor.
@@ -203,7 +268,7 @@ public:
void close()
{
boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "close");
}
@@ -218,7 +283,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
{
- this->get_service().close(this->get_implementation(), ec);
+ impl_.get_service().close(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -230,7 +295,7 @@ public:
*/
native_handle_type native_handle()
{
- return this->get_service().native_handle(this->get_implementation());
+ return impl_.get_service().native_handle(impl_.get_implementation());
}
/// Release ownership of the native descriptor implementation.
@@ -245,7 +310,7 @@ public:
*/
native_handle_type release()
{
- return this->get_service().release(this->get_implementation());
+ return impl_.get_service().release(impl_.get_implementation());
}
/// Cancel all asynchronous operations associated with the descriptor.
@@ -259,7 +324,7 @@ public:
void cancel()
{
boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "cancel");
}
@@ -273,7 +338,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
{
- this->get_service().cancel(this->get_implementation(), ec);
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -292,7 +357,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* boost::asio::posix::stream_descriptor::bytes_readable command;
* descriptor.io_control(command);
@@ -303,7 +368,7 @@ public:
void io_control(IoControlCommand& command)
{
boost::system::error_code ec;
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
boost::asio::detail::throw_error(ec, "io_control");
}
@@ -322,7 +387,7 @@ public:
* @par Example
* Getting the number of bytes ready to read:
* @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* boost::asio::posix::stream_descriptor::bytes_readable command;
* boost::system::error_code ec;
@@ -338,7 +403,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
boost::system::error_code& ec)
{
- this->get_service().io_control(this->get_implementation(), command, ec);
+ impl_.get_service().io_control(impl_.get_implementation(), command, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -355,7 +420,7 @@ public:
*/
bool non_blocking() const
{
- return this->get_service().non_blocking(this->get_implementation());
+ return impl_.get_service().non_blocking(impl_.get_implementation());
}
/// Sets the non-blocking mode of the descriptor.
@@ -374,7 +439,7 @@ public:
void non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "non_blocking");
}
@@ -394,7 +459,7 @@ public:
BOOST_ASIO_SYNC_OP_VOID non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
+ impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -414,8 +479,8 @@ public:
*/
bool native_non_blocking() const
{
- return this->get_service().native_non_blocking(
- this->get_implementation());
+ return impl_.get_service().native_non_blocking(
+ impl_.get_implementation());
}
/// Sets the non-blocking mode of the native descriptor implementation.
@@ -436,8 +501,8 @@ public:
void native_non_blocking(bool mode)
{
boost::system::error_code ec;
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
boost::asio::detail::throw_error(ec, "native_non_blocking");
}
@@ -459,8 +524,8 @@ public:
BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
bool mode, boost::system::error_code& ec)
{
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
+ impl_.get_service().native_non_blocking(
+ impl_.get_implementation(), mode, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -475,7 +540,7 @@ public:
* @par Example
* Waiting for a descriptor to become readable.
* @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* descriptor.wait(boost::asio::posix::stream_descriptor::wait_read);
* @endcode
@@ -483,7 +548,7 @@ public:
void wait(wait_type w)
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -500,7 +565,7 @@ public:
* @par Example
* Waiting for a descriptor to become readable.
* @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* boost::system::error_code ec;
* descriptor.wait(boost::asio::posix::stream_descriptor::wait_read, ec);
@@ -508,7 +573,7 @@ public:
*/
BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), w, ec);
+ impl_.get_service().wait(impl_.get_implementation(), w, ec);
BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -527,9 +592,9 @@ public:
* const boost::system::error_code& error // Result of operation
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* @code
@@ -543,7 +608,7 @@ public:
*
* ...
*
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* descriptor.async_wait(
* boost::asio::posix::stream_descriptor::wait_read,
@@ -555,19 +620,44 @@ public:
void (boost::system::error_code))
async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
- return this->get_service().async_wait(this->get_implementation(),
- w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+ return async_initiate<WaitHandler, void (boost::system::error_code)>(
+ initiate_async_wait(), handler, this, w);
}
protected:
/// Protected destructor to prevent deletion through this type.
+ /**
+ * This function destroys the descriptor, cancelling any outstanding
+ * asynchronous wait operations associated with the descriptor as if by
+ * calling @c cancel.
+ */
~basic_descriptor()
{
}
+
+ detail::io_object_impl<detail::reactive_descriptor_service, Executor> impl_;
+
+private:
+ // Disallow copying and assignment.
+ basic_descriptor(const basic_descriptor&) BOOST_ASIO_DELETED;
+ basic_descriptor& operator=(const basic_descriptor&) BOOST_ASIO_DELETED;
+
+ struct initiate_async_wait
+ {
+ template <typename WaitHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler,
+ basic_descriptor* self, wait_type w) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WaitHandler.
+ BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
+
+ detail::non_const_lvalue<WaitHandler> handler2(handler);
+ self->impl_.get_service().async_wait(
+ self->impl_.get_implementation(), w, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace posix
@@ -579,6 +669,4 @@ protected:
#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_POSIX_BASIC_DESCRIPTOR_HPP
diff --git a/boost/asio/posix/basic_stream_descriptor.hpp b/boost/asio/posix/basic_stream_descriptor.hpp
index d840703a95..0098802211 100644
--- a/boost/asio/posix/basic_stream_descriptor.hpp
+++ b/boost/asio/posix/basic_stream_descriptor.hpp
@@ -2,7 +2,7 @@
// posix/basic_stream_descriptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,21 +16,11 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#include <boost/asio/posix/descriptor.hpp>
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
|| defined(GENERATING_DOCUMENTATION)
-#include <cstddef>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#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/push_options.hpp>
-
namespace boost {
namespace asio {
namespace posix {
@@ -47,81 +37,126 @@ namespace posix {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
-template <typename StreamDescriptorService = stream_descriptor_service>
+template <typename Executor = executor>
class basic_stream_descriptor
- : public basic_descriptor<StreamDescriptorService>
+ : public basic_descriptor<Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a descriptor.
- typedef typename StreamDescriptorService::native_handle_type
+ typedef typename basic_descriptor<Executor>::native_handle_type
native_handle_type;
- /// Construct a basic_stream_descriptor without opening it.
+ /// Construct a stream descriptor without opening it.
/**
* This constructor creates a stream descriptor without opening it. The
* descriptor needs to be opened and then connected or accepted before data
* can be sent or received on it.
*
- * @param io_context The io_context object that the stream descriptor will
- * use to dispatch handlers for any asynchronous operations performed on the
+ * @param ex The I/O executor that the descriptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
* descriptor.
*/
- explicit basic_stream_descriptor(boost::asio::io_context& io_context)
- : basic_descriptor<StreamDescriptorService>(io_context)
+ explicit basic_stream_descriptor(const executor_type& ex)
+ : basic_descriptor<Executor>(ex)
+ {
+ }
+
+ /// Construct a stream descriptor without opening it.
+ /**
+ * This constructor creates a stream descriptor without opening it. The
+ * descriptor needs to be opened and then connected or accepted before data
+ * can be sent or received on it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the descriptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the descriptor.
+ */
+ template <typename ExecutionContext>
+ explicit basic_stream_descriptor(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_descriptor<Executor>(context)
{
}
- /// Construct a basic_stream_descriptor on an existing native descriptor.
+ /// Construct a stream descriptor on an existing native descriptor.
/**
* This constructor creates a stream descriptor object to hold an existing
* native descriptor.
*
- * @param io_context The io_context object that the stream descriptor will
- * use to dispatch handlers for any asynchronous operations performed on the
+ * @param ex The I/O executor that the descriptor will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
* descriptor.
*
* @param native_descriptor The new underlying descriptor implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_descriptor(boost::asio::io_context& io_context,
+ basic_stream_descriptor(const executor_type& ex,
const native_handle_type& native_descriptor)
- : basic_descriptor<StreamDescriptorService>(io_context, native_descriptor)
+ : basic_descriptor<Executor>(ex, native_descriptor)
+ {
+ }
+
+ /// Construct a stream descriptor on an existing native descriptor.
+ /**
+ * This constructor creates a stream descriptor object to hold an existing
+ * native descriptor.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the descriptor will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the descriptor.
+ *
+ * @param native_descriptor The new underlying descriptor implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_descriptor(ExecutionContext& context,
+ const native_handle_type& native_descriptor,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_descriptor<Executor>(context, native_descriptor)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_stream_descriptor from another.
+ /// Move-construct a stream descriptor from another.
/**
* This constructor moves a stream descriptor from one object to another.
*
- * @param other The other basic_stream_descriptor object from which the move
+ * @param other The other stream descriptor object from which the move
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_descriptor(io_context&) constructor.
+ * constructed using the @c basic_stream_descriptor(const executor_type&)
+ * constructor.
*/
basic_stream_descriptor(basic_stream_descriptor&& other)
- : basic_descriptor<StreamDescriptorService>(
- BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other))
+ : descriptor(std::move(other))
{
}
- /// Move-assign a basic_stream_descriptor from another.
+ /// Move-assign a stream descriptor from another.
/**
* This assignment operator moves a stream descriptor from one object to
* another.
*
- * @param other The other basic_stream_descriptor object from which the move
+ * @param other The other stream descriptor object from which the move
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_descriptor(io_context&) constructor.
+ * constructed using the @c basic_stream_descriptor(const executor_type&)
+ * constructor.
*/
basic_stream_descriptor& operator=(basic_stream_descriptor&& other)
{
- basic_descriptor<StreamDescriptorService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_stream_descriptor)(other));
+ descriptor::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -157,8 +192,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = this->impl_.get_service().write_some(
+ this->impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@@ -183,8 +218,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ return this->impl_.get_service().write_some(
+ this->impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous write.
@@ -205,9 +240,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -228,12 +263,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- return this->get_service().async_write_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the descriptor.
@@ -268,8 +300,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = this->impl_.get_service().read_some(
+ this->impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@@ -295,8 +327,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ return this->impl_.get_service().read_some(
+ this->impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous read.
@@ -317,9 +349,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -341,24 +373,54 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- return this->get_service().async_read_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_read_some(), handler, this, buffers);
}
+
+private:
+ struct initiate_async_write_some
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ basic_stream_descriptor* self,
+ const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ detail::non_const_lvalue<WriteHandler> handler2(handler);
+ self->impl_.get_service().async_write_some(
+ self->impl_.get_implementation(), buffers, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
+
+ struct initiate_async_read_some
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ basic_stream_descriptor* self,
+ const MutableBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ detail::non_const_lvalue<ReadHandler> handler2(handler);
+ self->impl_.get_service().async_read_some(
+ self->impl_.get_implementation(), buffers, handler2.value,
+ self->impl_.get_implementation_executor());
+ }
+ };
};
} // namespace posix
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_POSIX_BASIC_STREAM_DESCRIPTOR_HPP
diff --git a/boost/asio/posix/descriptor.hpp b/boost/asio/posix/descriptor.hpp
index be672ff11c..d7aa928725 100644
--- a/boost/asio/posix/descriptor.hpp
+++ b/boost/asio/posix/descriptor.hpp
@@ -2,7 +2,7 @@
// posix/descriptor.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,630 +17,23 @@
#include <boost/asio/detail/config.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
|| defined(GENERATING_DOCUMENTATION)
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/reactive_descriptor_service.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/posix/descriptor_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#define BOOST_ASIO_SVC_T boost::asio::detail::reactive_descriptor_service
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/posix/basic_descriptor.hpp>
namespace boost {
namespace asio {
namespace posix {
-/// Provides POSIX descriptor functionality.
-/**
- * The posix::descriptor class template provides the ability to wrap a
- * POSIX descriptor.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-class descriptor
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- public descriptor_base
-{
-public:
- /// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
-
- /// The native representation of a descriptor.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
-#endif
-
- /// A descriptor is always the lowest layer.
- typedef descriptor lowest_layer_type;
-
- /// Construct a descriptor without opening it.
- /**
- * This constructor creates a descriptor without opening it.
- *
- * @param io_context The io_context object that the descriptor will use to
- * dispatch handlers for any asynchronous operations performed on the
- * descriptor.
- */
- explicit descriptor(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- }
-
- /// Construct a descriptor on an existing native descriptor.
- /**
- * This constructor creates a descriptor object to hold an existing native
- * descriptor.
- *
- * @param io_context The io_context object that the descriptor will use to
- * dispatch handlers for any asynchronous operations performed on the
- * descriptor.
- *
- * @param native_descriptor A native descriptor.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- descriptor(boost::asio::io_context& io_context,
- const native_handle_type& native_descriptor)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
- native_descriptor, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a descriptor from another.
- /**
- * This constructor moves a descriptor from one object to another.
- *
- * @param other The other descriptor object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c descriptor(io_context&) constructor.
- */
- descriptor(descriptor&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
- {
- }
-
- /// Move-assign a descriptor from another.
- /**
- * This assignment operator moves a descriptor from one object to another.
- *
- * @param other The other descriptor object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c descriptor(io_context&) constructor.
- */
- descriptor& operator=(descriptor&& other)
- {
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the executor associated with the object.
- executor_type get_executor() BOOST_ASIO_NOEXCEPT
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
- }
-
- /// Get a reference to the lowest layer.
- /**
- * This function returns a reference to the lowest layer in a stack of
- * layers. Since a descriptor cannot contain any further layers, it
- * simply returns a reference to itself.
- *
- * @return A reference to the lowest layer in the stack of layers. Ownership
- * is not transferred to the caller.
- */
- lowest_layer_type& lowest_layer()
- {
- return *this;
- }
-
- /// Get a const reference to the lowest layer.
- /**
- * This function returns a const reference to the lowest layer in a stack of
- * layers. Since a descriptor cannot contain any further layers, it
- * simply returns a reference to itself.
- *
- * @return A const reference to the lowest layer in the stack of layers.
- * Ownership is not transferred to the caller.
- */
- const lowest_layer_type& lowest_layer() const
- {
- return *this;
- }
-
- /// Assign an existing native descriptor to the descriptor.
- /*
- * This function opens the descriptor to hold an existing native descriptor.
- *
- * @param native_descriptor A native descriptor.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void assign(const native_handle_type& native_descriptor)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
- native_descriptor, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
- /// Assign an existing native descriptor to the descriptor.
- /*
- * This function opens the descriptor to hold an existing native descriptor.
- *
- * @param native_descriptor A native descriptor.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_descriptor,
- boost::system::error_code& ec)
- {
- this->get_service().assign(
- this->get_implementation(), native_descriptor, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the descriptor is open.
- bool is_open() const
- {
- return this->get_service().is_open(this->get_implementation());
- }
-
- /// Close the descriptor.
- /**
- * This function is used to close the descriptor. Any asynchronous read or
- * write operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure. Note that, even if
- * the function indicates an error, the underlying descriptor is closed.
- */
- void close()
- {
- boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "close");
- }
-
- /// Close the descriptor.
- /**
- * This function is used to close the descriptor. Any asynchronous read or
- * write operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any. Note that, even if
- * the function indicates an error, the underlying descriptor is closed.
- */
- BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
- {
- this->get_service().close(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native descriptor representation.
- /**
- * This function may be used to obtain the underlying representation of the
- * descriptor. This is intended to allow access to native descriptor
- * functionality that is not otherwise provided.
- */
- native_handle_type native_handle()
- {
- return this->get_service().native_handle(this->get_implementation());
- }
-
- /// Release ownership of the native descriptor implementation.
- /**
- * This function may be used to obtain the underlying representation of the
- * descriptor. After calling this function, @c is_open() returns false. The
- * caller is responsible for closing the descriptor.
- *
- * All outstanding asynchronous read or write operations will finish
- * immediately, and the handlers for cancelled operations will be passed the
- * boost::asio::error::operation_aborted error.
- */
- native_handle_type release()
- {
- return this->get_service().release(this->get_implementation());
- }
-
- /// Cancel all asynchronous operations associated with the descriptor.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all asynchronous operations associated with the descriptor.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the descriptor.
- /**
- * This function is used to execute an IO control command on the descriptor.
- *
- * @param command The IO control command to be performed on the descriptor.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @sa IoControlCommand @n
- * boost::asio::posix::descriptor_base::bytes_readable @n
- * boost::asio::posix::descriptor_base::non_blocking_io
- *
- * @par Example
- * Getting the number of bytes ready to read:
- * @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
- * ...
- * boost::asio::posix::stream_descriptor::bytes_readable command;
- * descriptor.io_control(command);
- * std::size_t bytes_readable = command.get();
- * @endcode
- */
- template <typename IoControlCommand>
- void io_control(IoControlCommand& command)
- {
- boost::system::error_code ec;
- this->get_service().io_control(this->get_implementation(), command, ec);
- boost::asio::detail::throw_error(ec, "io_control");
- }
-
- /// Perform an IO control command on the descriptor.
- /**
- * This function is used to execute an IO control command on the descriptor.
- *
- * @param command The IO control command to be performed on the descriptor.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @sa IoControlCommand @n
- * boost::asio::posix::descriptor_base::bytes_readable @n
- * boost::asio::posix::descriptor_base::non_blocking_io
- *
- * @par Example
- * Getting the number of bytes ready to read:
- * @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
- * ...
- * boost::asio::posix::stream_descriptor::bytes_readable command;
- * boost::system::error_code ec;
- * descriptor.io_control(command, ec);
- * if (ec)
- * {
- * // An error occurred.
- * }
- * std::size_t bytes_readable = command.get();
- * @endcode
- */
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command,
- boost::system::error_code& ec)
- {
- this->get_service().io_control(this->get_implementation(), command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the descriptor.
- /**
- * @returns @c true if the descriptor's synchronous operations will fail with
- * boost::asio::error::would_block if they are unable to perform the requested
- * operation immediately. If @c false, synchronous operations will block
- * until complete.
- *
- * @note The non-blocking mode has no effect on the behaviour of asynchronous
- * operations. Asynchronous operations will never fail with the error
- * boost::asio::error::would_block.
- */
- bool non_blocking() const
- {
- return this->get_service().non_blocking(this->get_implementation());
- }
-
- /// Sets the non-blocking mode of the descriptor.
- /**
- * @param mode If @c true, the descriptor's synchronous operations will fail
- * with boost::asio::error::would_block if they are unable to perform the
- * requested operation immediately. If @c false, synchronous operations will
- * block until complete.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @note The non-blocking mode has no effect on the behaviour of asynchronous
- * operations. Asynchronous operations will never fail with the error
- * boost::asio::error::would_block.
- */
- void non_blocking(bool mode)
- {
- boost::system::error_code ec;
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
- boost::asio::detail::throw_error(ec, "non_blocking");
- }
-
- /// Sets the non-blocking mode of the descriptor.
- /**
- * @param mode If @c true, the descriptor's synchronous operations will fail
- * with boost::asio::error::would_block if they are unable to perform the
- * requested operation immediately. If @c false, synchronous operations will
- * block until complete.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @note The non-blocking mode has no effect on the behaviour of asynchronous
- * operations. Asynchronous operations will never fail with the error
- * boost::asio::error::would_block.
- */
- BOOST_ASIO_SYNC_OP_VOID non_blocking(
- bool mode, boost::system::error_code& ec)
- {
- this->get_service().non_blocking(this->get_implementation(), mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native descriptor implementation.
- /**
- * This function is used to retrieve the non-blocking mode of the underlying
- * native descriptor. This mode has no effect on the behaviour of the
- * descriptor object's synchronous operations.
- *
- * @returns @c true if the underlying descriptor is in non-blocking mode and
- * direct system calls may fail with boost::asio::error::would_block (or the
- * equivalent system error).
- *
- * @note The current non-blocking mode is cached by the descriptor object.
- * Consequently, the return value may be incorrect if the non-blocking mode
- * was set directly on the native descriptor.
- */
- bool native_non_blocking() const
- {
- return this->get_service().native_non_blocking(
- this->get_implementation());
- }
-
- /// Sets the non-blocking mode of the native descriptor implementation.
- /**
- * This function is used to modify the non-blocking mode of the underlying
- * native descriptor. It has no effect on the behaviour of the descriptor
- * object's synchronous operations.
- *
- * @param mode If @c true, the underlying descriptor is put into non-blocking
- * mode and direct system calls may fail with boost::asio::error::would_block
- * (or the equivalent system error).
- *
- * @throws boost::system::system_error Thrown on failure. If the @c mode is
- * @c false, but the current value of @c non_blocking() is @c true, this
- * function fails with boost::asio::error::invalid_argument, as the
- * combination does not make sense.
- */
- void native_non_blocking(bool mode)
- {
- boost::system::error_code ec;
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
- boost::asio::detail::throw_error(ec, "native_non_blocking");
- }
-
- /// Sets the non-blocking mode of the native descriptor implementation.
- /**
- * This function is used to modify the non-blocking mode of the underlying
- * native descriptor. It has no effect on the behaviour of the descriptor
- * object's synchronous operations.
- *
- * @param mode If @c true, the underlying descriptor is put into non-blocking
- * mode and direct system calls may fail with boost::asio::error::would_block
- * (or the equivalent system error).
- *
- * @param ec Set to indicate what error occurred, if any. If the @c mode is
- * @c false, but the current value of @c non_blocking() is @c true, this
- * function fails with boost::asio::error::invalid_argument, as the
- * combination does not make sense.
- */
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(
- bool mode, boost::system::error_code& ec)
- {
- this->get_service().native_non_blocking(
- this->get_implementation(), mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the descriptor to become ready to read, ready to write, or to
- /// have pending error conditions.
- /**
- * This function is used to perform a blocking wait for a descriptor to enter
- * a ready to read, write or error condition state.
- *
- * @param w Specifies the desired descriptor state.
- *
- * @par Example
- * Waiting for a descriptor to become readable.
- * @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
- * ...
- * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read);
- * @endcode
- */
- void wait(wait_type w)
- {
- boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), w, ec);
- boost::asio::detail::throw_error(ec, "wait");
- }
-
- /// Wait for the descriptor to become ready to read, ready to write, or to
- /// have pending error conditions.
- /**
- * This function is used to perform a blocking wait for a descriptor to enter
- * a ready to read, write or error condition state.
- *
- * @param w Specifies the desired descriptor state.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @par Example
- * Waiting for a descriptor to become readable.
- * @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
- * ...
- * boost::system::error_code ec;
- * descriptor.wait(boost::asio::posix::stream_descriptor::wait_read, ec);
- * @endcode
- */
- BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec)
- {
- this->get_service().wait(this->get_implementation(), w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the descriptor to become ready to read, ready to
- /// write, or to have pending error conditions.
- /**
- * This function is used to perform an asynchronous wait for a descriptor to
- * enter a ready to read, write or error condition state.
- *
- * @param w Specifies the desired descriptor state.
- *
- * @param handler The handler to be called when the wait operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error // Result of operation
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @par Example
- * @code
- * void wait_handler(const boost::system::error_code& error)
- * {
- * if (!error)
- * {
- * // Wait succeeded.
- * }
- * }
- *
- * ...
- *
- * boost::asio::posix::stream_descriptor descriptor(io_context);
- * ...
- * descriptor.async_wait(
- * boost::asio::posix::stream_descriptor::wait_read,
- * wait_handler);
- * @endcode
- */
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WaitHandler.
- BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
-
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(
- this->get_implementation(), w, init.completion_handler);
-
- return init.result.get();
- }
-
-protected:
- /// Protected destructor to prevent deletion through this type.
- /**
- * This function destroys the descriptor, cancelling any outstanding
- * asynchronous wait operations associated with the descriptor as if by
- * calling @c cancel.
- */
- ~descriptor()
- {
- }
-};
+/// Typedef for the typical usage of basic_descriptor.
+typedef basic_descriptor<> descriptor;
} // namespace posix
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
-#undef BOOST_ASIO_SVC_T
-
#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+ // || defined(GENERATING_DOCUMENTATION)
#endif // BOOST_ASIO_POSIX_DESCRIPTOR_HPP
diff --git a/boost/asio/posix/descriptor_base.hpp b/boost/asio/posix/descriptor_base.hpp
index 6722f04ef7..ff7d4c9845 100644
--- a/boost/asio/posix/descriptor_base.hpp
+++ b/boost/asio/posix/descriptor_base.hpp
@@ -2,7 +2,7 @@
// posix/descriptor_base.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -57,7 +57,7 @@ public:
*
* @par Example
* @code
- * boost::asio::posix::stream_descriptor descriptor(io_context);
+ * boost::asio::posix::stream_descriptor descriptor(my_context);
* ...
* boost::asio::descriptor_base::bytes_readable command(true);
* descriptor.io_control(command);
diff --git a/boost/asio/posix/stream_descriptor.hpp b/boost/asio/posix/stream_descriptor.hpp
index af8cbe92c0..035cf3c5b1 100644
--- a/boost/asio/posix/stream_descriptor.hpp
+++ b/boost/asio/posix/stream_descriptor.hpp
@@ -2,7 +2,7 @@
// posix/stream_descriptor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,341 +16,18 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-#include <boost/asio/posix/descriptor.hpp>
#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
|| defined(GENERATING_DOCUMENTATION)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/posix/basic_stream_descriptor.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#include <boost/asio/posix/basic_stream_descriptor.hpp>
namespace boost {
namespace asio {
namespace posix {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of a stream-oriented descriptor.
+/// Typedef for the typical usage of a stream-oriented descriptor.
typedef basic_stream_descriptor<> stream_descriptor;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides stream-oriented descriptor functionality.
-/**
- * The posix::stream_descriptor class template provides asynchronous and
- * blocking stream-oriented descriptor functionality.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- *
- * @par Concepts:
- * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
- */
-class stream_descriptor
- : public descriptor
-{
-public:
- /// Construct a stream_descriptor without opening it.
- /**
- * This constructor creates a stream descriptor without opening it. The
- * descriptor needs to be opened and then connected or accepted before data
- * can be sent or received on it.
- *
- * @param io_context The io_context object that the stream descriptor will
- * use to dispatch handlers for any asynchronous operations performed on the
- * descriptor.
- */
- explicit stream_descriptor(boost::asio::io_context& io_context)
- : descriptor(io_context)
- {
- }
-
- /// Construct a stream_descriptor on an existing native descriptor.
- /**
- * This constructor creates a stream descriptor object to hold an existing
- * native descriptor.
- *
- * @param io_context The io_context object that the stream descriptor will
- * use to dispatch handlers for any asynchronous operations performed on the
- * descriptor.
- *
- * @param native_descriptor The new underlying descriptor implementation.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- stream_descriptor(boost::asio::io_context& io_context,
- const native_handle_type& native_descriptor)
- : descriptor(io_context, native_descriptor)
- {
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a stream_descriptor from another.
- /**
- * This constructor moves a stream descriptor from one object to another.
- *
- * @param other The other stream_descriptor object from which the move
- * will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c stream_descriptor(io_context&) constructor.
- */
- stream_descriptor(stream_descriptor&& other)
- : descriptor(std::move(other))
- {
- }
-
- /// Move-assign a stream_descriptor from another.
- /**
- * This assignment operator moves a stream descriptor from one object to
- * another.
- *
- * @param other The other stream_descriptor object from which the move
- * will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c stream_descriptor(io_context&) constructor.
- */
- stream_descriptor& operator=(stream_descriptor&& other)
- {
- descriptor::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Write some data to the descriptor.
- /**
- * This function is used to write data to the stream descriptor. The function
- * call will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the descriptor.
- *
- * @returns The number of bytes written.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * descriptor.write_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "write_some");
- return s;
- }
-
- /// Write some data to the descriptor.
- /**
- * This function is used to write data to the stream descriptor. The function
- * call will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the descriptor.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes written. Returns 0 if an error occurred.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous write.
- /**
- * This function is used to asynchronously write data to the stream
- * descriptor. The function call always returns immediately.
- *
- * @param buffers One or more data buffers to be written to the descriptor.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the write operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes written.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The write operation may not transmit all of the data to the peer.
- * Consider using the @ref async_write function if you need to ensure that all
- * data is written before the asynchronous operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * descriptor.async_write_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_write_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the descriptor.
- /**
- * This function is used to read data from the stream descriptor. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @returns The number of bytes read.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * descriptor.read_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "read_some");
- return s;
- }
-
- /// Read some data from the descriptor.
- /**
- * This function is used to read data from the stream descriptor. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes read. Returns 0 if an error occurred.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous read.
- /**
- * This function is used to asynchronously read data from the stream
- * descriptor. The function call always returns immediately.
- *
- * @param buffers One or more buffers into which the data will be read.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the read operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes read.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The read operation may not read all of the requested number of bytes.
- * Consider using the @ref async_read function if you need to ensure that the
- * requested amount of data is read before the asynchronous operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * descriptor.async_read_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_read_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace posix
} // namespace asio
diff --git a/boost/asio/posix/stream_descriptor_service.hpp b/boost/asio/posix/stream_descriptor_service.hpp
deleted file mode 100644
index b91000ba29..0000000000
--- a/boost/asio/posix/stream_descriptor_service.hpp
+++ /dev/null
@@ -1,281 +0,0 @@
-//
-// posix/stream_descriptor_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP
-#define BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/detail/reactive_descriptor_service.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace posix {
-
-/// Default service implementation for a stream descriptor.
-class stream_descriptor_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<stream_descriptor_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::reactive_descriptor_service service_impl_type;
-
-public:
- /// The type of a stream descriptor implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native descriptor type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new stream descriptor service for the specified io_context.
- explicit stream_descriptor_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<stream_descriptor_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new stream descriptor implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new stream descriptor implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another stream descriptor implementation.
- void move_assign(implementation_type& impl,
- stream_descriptor_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a stream descriptor implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Assign an existing native descriptor to a stream descriptor.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const native_handle_type& native_descriptor,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, native_descriptor, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the descriptor is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a stream descriptor implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native descriptor implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Release ownership of the native descriptor implementation.
- native_handle_type release(implementation_type& impl)
- {
- return service_impl_.release(impl);
- }
-
- /// Cancel all asynchronous operations associated with the descriptor.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the descriptor.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the descriptor.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the descriptor.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native descriptor implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native descriptor implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the descriptor to become ready to read, ready to write, or to
- /// have pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- descriptor_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the descriptor to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, descriptor_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Write the given data to the stream.
- template <typename ConstBufferSequence>
- std::size_t write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.write_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous write.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_write_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the stream.
- template <typename MutableBufferSequence>
- std::size_t read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.read_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous read.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_read_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace posix
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_POSIX_STREAM_DESCRIPTOR_SERVICE_HPP
diff --git a/boost/asio/post.hpp b/boost/asio/post.hpp
index 667613ec54..0fbdbf0b98 100644
--- a/boost/asio/post.hpp
+++ b/boost/asio/post.hpp
@@ -2,7 +2,7 @@
// post.hpp
// ~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,6 +32,9 @@ namespace asio {
* executor. The function object is queued for execution, and is never called
* from the current thread prior to returning from <tt>post()</tt>.
*
+ * The use of @c post(), rather than @ref defer(), indicates the caller's
+ * preference that the function object be eagerly queued for execution.
+ *
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized
@@ -60,6 +63,9 @@ BOOST_ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) post(
* The function object is queued for execution, and is never called from the
* current thread prior to returning from <tt>post()</tt>.
*
+ * The use of @c post(), rather than @ref defer(), indicates the caller's
+ * preference that the function object be eagerly queued for execution.
+ *
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized
diff --git a/boost/asio/raw_socket_service.hpp b/boost/asio/raw_socket_service.hpp
deleted file mode 100644
index 63ebf5cb30..0000000000
--- a/boost/asio/raw_socket_service.hpp
+++ /dev/null
@@ -1,468 +0,0 @@
-//
-// raw_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_RAW_SOCKET_SERVICE_HPP
-#define BOOST_ASIO_RAW_SOCKET_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_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a raw socket.
-template <typename Protocol>
-class raw_socket_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<raw_socket_service<Protocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef Protocol protocol_type;
-
- /// The endpoint type.
- typedef typename Protocol::endpoint endpoint_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef detail::null_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service<Protocol> service_impl_type;
-#endif
-
-public:
- /// The type of a raw socket.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native socket type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new raw socket service for the specified io_context.
- explicit raw_socket_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- raw_socket_service<Protocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new raw socket implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new raw socket implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another raw socket implementation.
- void move_assign(implementation_type& impl,
- raw_socket_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-
- // All socket services have access to each other's implementations.
- template <typename Protocol1> friend class raw_socket_service;
-
- /// Move-construct a new raw socket implementation from another protocol
- /// type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- raw_socket_service<Protocol1>& other_service,
- typename raw_socket_service<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a raw socket implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- // Open a new raw socket implementation.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const protocol_type& protocol, boost::system::error_code& ec)
- {
- if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_RAW))
- service_impl_.open(impl, protocol, ec);
- else
- ec = boost::asio::error::invalid_argument;
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native socket to a raw socket.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const protocol_type& protocol, const native_handle_type& native_socket,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, protocol, native_socket, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a raw socket implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Release ownership of the underlying socket.
- native_handle_type release(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.release(impl, ec);
- }
-
- /// Get the native socket implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the socket.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_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
- {
- return service_impl_.at_mark(impl, ec);
- }
-
- /// Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.available(impl, ec);
- }
-
- // Bind the raw socket to the specified local endpoint.
- BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- service_impl_.bind(impl, endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Connect the raw socket to the specified endpoint.
- BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, boost::system::error_code& ec)
- {
- service_impl_.connect(impl, peer_endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Start an asynchronous connect.
- template <typename ConnectHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
- void (boost::system::error_code))
- async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint,
- BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
- {
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSocketOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a socket option.
- template <typename GettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSocketOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the socket.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the socket.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the socket.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native socket implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native socket implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the local endpoint.
- endpoint_type local_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.local_endpoint(impl, ec);
- }
-
- /// Get the remote endpoint.
- endpoint_type remote_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.remote_endpoint(impl, ec);
- }
-
- /// Disable sends or receives on the socket.
- BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- service_impl_.shutdown(impl, what, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the socket to become ready to read, ready to write, or to have
- /// pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- socket_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the socket to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, socket_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send the given data to the peer.
- template <typename ConstBufferSequence>
- std::size_t send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send(implementation_type& impl, const ConstBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send raw data to the specified endpoint.
- template <typename ConstBufferSequence>
- std::size_t send_to(implementation_type& impl,
- const ConstBufferSequence& buffers, const endpoint_type& destination,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send_to(impl, buffers, destination, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send_to(implementation_type& impl,
- const ConstBufferSequence& buffers, const endpoint_type& destination,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send_to(impl, buffers,
- destination, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive some data from the peer.
- template <typename MutableBufferSequence>
- std::size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.receive(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous receive.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive raw data with the endpoint of the sender.
- template <typename MutableBufferSequence>
- std::size_t receive_from(implementation_type& impl,
- const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
- ec);
- }
-
- /// Start an asynchronous receive that will get the endpoint of the sender.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive_from(implementation_type& impl,
- const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive_from(impl, buffers,
- sender_endpoint, flags, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_RAW_SOCKET_SERVICE_HPP
diff --git a/boost/asio/read.hpp b/boost/asio/read.hpp
index efa373c3cf..3c4868605b 100644
--- a/boost/asio/read.hpp
+++ b/boost/asio/read.hpp
@@ -2,7 +2,7 @@
// read.hpp
// ~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -224,6 +224,8 @@ std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type* = 0);
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Attempt to read a certain amount of data from a stream before returning.
/**
* This function is used to read a certain number of bytes of data from a
@@ -251,11 +253,12 @@ std::size_t read(SyncReadStream& s, const MutableBufferSequence& buffers,
* s, buffers,
* boost::asio::transfer_all()); @endcode
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Attempt to read a certain amount of data from a stream before returning.
@@ -284,12 +287,13 @@ std::size_t read(SyncReadStream& s,
* s, buffers,
* boost::asio::transfer_all(), ec); @endcode
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Attempt to read a certain amount of data from a stream before returning.
@@ -328,13 +332,14 @@ std::size_t read(SyncReadStream& s,
*
* @throws boost::system::system_error Thrown on failure.
*/
-template <typename SyncReadStream, typename DynamicBuffer,
+template <typename SyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Attempt to read a certain amount of data from a stream before returning.
@@ -374,13 +379,14 @@ std::size_t read(SyncReadStream& s,
* @returns The number of bytes read. If an error occurs, returns the total
* number of bytes successfully transferred prior to the error.
*/
-template <typename SyncReadStream, typename DynamicBuffer,
+template <typename SyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t read(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition, boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -528,6 +534,162 @@ std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Attempt to read a certain amount of data from a stream before returning.
+/**
+ * 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:
+ *
+ * @li The specified dynamic buffer sequence is full (that is, it has reached
+ * maximum size).
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::read(
+ * s, buffers,
+ * boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Attempt to read a certain amount of data from a stream before returning.
+/**
+ * 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:
+ *
+ * @li The supplied buffer is full (that is, it has reached maximum size).
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::read(
+ * s, buffers,
+ * boost::asio::transfer_all(), ec); @endcode
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Attempt to read a certain amount of data from a stream before returning.
+/**
+ * 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:
+ *
+ * @li The specified dynamic buffer sequence is full (that is, it has reached
+ * maximum size).
+ *
+ * @li 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.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest read_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the read operation is complete. A non-zero
+ * return value indicates the maximum number of bytes to be read on the next
+ * call to the stream's read_some function.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Attempt to read a certain amount of data from a stream before returning.
+/**
+ * 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:
+ *
+ * @li The specified dynamic buffer sequence is full (that is, it has reached
+ * maximum size).
+ *
+ * @li 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.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest read_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the read operation is complete. A non-zero
+ * return value indicates the maximum number of bytes to be read on the next
+ * call to the stream's read_some function.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes read. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t read(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
/*@}*/
/**
@@ -579,9 +741,9 @@ std::size_t read(SyncReadStream& s, basic_streambuf<Allocator>& b,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
@@ -657,9 +819,9 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
@@ -682,6 +844,8 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
is_mutable_buffer_sequence<MutableBufferSequence>::value
>::type* = 0);
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Start an asynchronous operation to read a certain amount of data from a
/// stream.
/**
@@ -722,9 +886,9 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note This overload is equivalent to calling:
* @code boost::asio::async_read(
@@ -733,14 +897,15 @@ async_read(AsyncReadStream& s, const MutableBufferSequence& buffers,
* handler); @endcode
*/
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Start an asynchronous operation to read a certain amount of data from a
@@ -797,20 +962,21 @@ async_read(AsyncReadStream& s,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -854,9 +1020,9 @@ async_read(AsyncReadStream& s,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note This overload is equivalent to calling:
* @code boost::asio::async_read(
@@ -922,9 +1088,9 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
* // prior to the error.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncReadStream, typename Allocator,
typename CompletionCondition, typename ReadHandler>
@@ -936,6 +1102,136 @@ async_read(AsyncReadStream& s, basic_streambuf<Allocator>& b,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Start an asynchronous operation to read a certain amount of data from a
+/// stream.
+/**
+ * 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:
+ *
+ * @li The specified dynamic buffer sequence is full (that is, it has reached
+ * maximum size).
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_read_some function, and is known as a <em>composed operation</em>. 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.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ *
+ * std::size_t bytes_transferred // Number of bytes copied into the
+ * // buffers. If an error occurred,
+ * // this will be the number of
+ * // bytes successfully transferred
+ * // prior to the error.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::async_read(
+ * s, buffers,
+ * boost::asio::transfer_all(),
+ * handler); @endcode
+ */
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Start an asynchronous operation to read a certain amount of data from a
+/// stream.
+/**
+ * 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:
+ *
+ * @li The specified dynamic buffer sequence is full (that is, it has reached
+ * maximum size).
+ *
+ * @li 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 <em>composed operation</em>. 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.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the read operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest async_read_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the read operation is complete. A non-zero
+ * return value indicates the maximum number of bytes to be read on the next
+ * call to the stream's async_read_some function.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ *
+ * std::size_t bytes_transferred // Number of bytes copied into the
+ * // buffers. If an error occurred,
+ * // this will be the number of
+ * // bytes successfully transferred
+ * // prior to the error.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
/*@}*/
diff --git a/boost/asio/read_at.hpp b/boost/asio/read_at.hpp
index ec6780382b..8319feb196 100644
--- a/boost/asio/read_at.hpp
+++ b/boost/asio/read_at.hpp
@@ -2,7 +2,7 @@
// read_at.hpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -440,9 +440,9 @@ std::size_t read_at(SyncRandomAccessReadDevice& d,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
@@ -518,9 +518,9 @@ async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To read into a single data buffer use the @ref buffer function as follows:
@@ -579,9 +579,9 @@ async_read_at(AsyncRandomAccessReadDevice& d,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note This overload is equivalent to calling:
* @code boost::asio::async_read_at(
@@ -645,9 +645,9 @@ async_read_at(AsyncRandomAccessReadDevice& d, uint64_t offset,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncRandomAccessReadDevice, typename Allocator,
typename CompletionCondition, typename ReadHandler>
diff --git a/boost/asio/read_until.hpp b/boost/asio/read_until.hpp
index f9c1f51323..96ed6a77de 100644
--- a/boost/asio/read_until.hpp
+++ b/boost/asio/read_until.hpp
@@ -2,7 +2,7 @@
// read_until.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -19,6 +19,7 @@
#include <cstddef>
#include <string>
#include <boost/asio/async_result.hpp>
+#include <boost/asio/buffer.hpp>
#include <boost/asio/detail/regex_fwd.hpp>
#include <boost/asio/detail/string_view.hpp>
#include <boost/asio/detail/type_traits.hpp>
@@ -75,6 +76,8 @@ struct is_match_condition
*/
/*@{*/
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Read data into a dynamic buffer sequence until it contains a specified
/// delimiter.
/**
@@ -128,9 +131,13 @@ struct is_match_condition
* This data may be the start of a new line, to be extracted by a subsequent
* @c read_until operation.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers, char delim);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers, char delim,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Read data into a dynamic buffer sequence until it contains a specified
/// delimiter.
@@ -166,10 +173,14 @@ std::size_t read_until(SyncReadStream& s,
* typically leave that data in the dynamic buffer sequence for a subsequent
* read_until operation to examine.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- char delim, boost::system::error_code& ec);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ char delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Read data into a dynamic buffer sequence until it contains a specified
/// delimiter.
@@ -222,10 +233,14 @@ std::size_t read_until(SyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent
* @c read_until operation.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- BOOST_ASIO_STRING_VIEW_PARAM delim);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Read data into a dynamic buffer sequence until it contains a specified
/// delimiter.
@@ -261,11 +276,15 @@ std::size_t read_until(SyncReadStream& s,
* typically leave that data in the dynamic buffer sequence for a subsequent
* read_until operation to examine.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_STRING_VIEW_PARAM delim,
- boost::system::error_code& ec);
+ boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
@@ -325,10 +344,14 @@ std::size_t read_until(SyncReadStream& s,
* This data may be the start of a new line, to be extracted by a subsequent
* @c read_until operation.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- const boost::regex& expr);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const boost::regex& expr,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Read data into a dynamic buffer sequence until some part of the data it
/// contains matches a regular expression.
@@ -366,10 +389,14 @@ std::size_t read_until(SyncReadStream& s,
* expression. An application will typically leave that data in the dynamic
* buffer sequence for a subsequent read_until operation to examine.
*/
-template <typename SyncReadStream, typename DynamicBuffer>
+template <typename SyncReadStream, typename DynamicBuffer_v1>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- const boost::regex& expr, boost::system::error_code& ec);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ const boost::regex& expr, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
// || defined(GENERATING_DOCUMENTATION)
@@ -402,7 +429,7 @@ std::size_t read_until(SyncReadStream& s,
* @code pair<iterator, bool> match_condition(iterator begin, iterator end);
* @endcode
* where @c iterator represents the type:
- * @code buffers_iterator<typename DynamicBuffer::const_buffers_type>
+ * @code buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
* @endcode
* The iterator parameters @c begin and @c end define the range of bytes to be
* scanned to determine whether there is a match. The @c first member of the
@@ -477,11 +504,15 @@ std::size_t read_until(SyncReadStream& s,
* @endcode
*/
template <typename SyncReadStream,
- typename DynamicBuffer, typename MatchCondition>
+ typename DynamicBuffer_v1, typename MatchCondition>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition,
- typename enable_if<is_match_condition<MatchCondition>::value>::type* = 0);
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Read data into a dynamic buffer sequence until a function object indicates a
/// match.
@@ -510,7 +541,7 @@ std::size_t read_until(SyncReadStream& s,
* @code pair<iterator, bool> match_condition(iterator begin, iterator end);
* @endcode
* where @c iterator represents the type:
- * @code buffers_iterator<DynamicBuffer::const_buffers_type>
+ * @code buffers_iterator<DynamicBuffer_v1::const_buffers_type>
* @endcode
* The iterator parameters @c begin and @c end define the range of bytes to be
* scanned to determine whether there is a match. The @c first member of the
@@ -537,11 +568,15 @@ std::size_t read_until(SyncReadStream& s,
* function objects.
*/
template <typename SyncReadStream,
- typename DynamicBuffer, typename MatchCondition>
+ typename DynamicBuffer_v1, typename MatchCondition>
std::size_t read_until(SyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition, boost::system::error_code& ec,
- typename enable_if<is_match_condition<MatchCondition>::value>::type* = 0);
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#if !defined(BOOST_ASIO_NO_IOSTREAM)
@@ -982,6 +1017,492 @@ std::size_t read_until(SyncReadStream& s,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Read data into a dynamic buffer sequence until it contains a specified
+/// delimiter.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains the specified
+ * delimiter. The call will block until one of the following conditions is
+ * true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains the delimiter, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param delim The delimiter character.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the delimiter.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond the delimiter. An application will
+ * typically leave that data in the dynamic buffer sequence for a subsequent
+ * read_until operation to examine.
+ *
+ * @par Example
+ * To read data into a @c std::string until a newline is encountered:
+ * @code std::string data;
+ * std::string n = boost::asio::read_until(s,
+ * boost::asio::dynamic_buffer(data), '\n');
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n); @endcode
+ * After the @c read_until operation completes successfully, the string @c data
+ * contains the delimiter:
+ * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the
+ * delimiter, so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the buffer @c b as
+ * follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c read_until operation.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers, char delim,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Read data into a dynamic buffer sequence until it contains a specified
+/// delimiter.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains the specified
+ * delimiter. The call will block until one of the following conditions is
+ * true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains the delimiter, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param delim The delimiter character.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the delimiter. Returns 0 if an error occurred.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond the delimiter. An application will
+ * typically leave that data in the dynamic buffer sequence for a subsequent
+ * read_until operation to examine.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ char delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Read data into a dynamic buffer sequence until it contains a specified
+/// delimiter.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains the specified
+ * delimiter. The call will block until one of the following conditions is
+ * true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains the delimiter, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param delim The delimiter string.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the delimiter.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond the delimiter. An application will
+ * typically leave that data in the dynamic buffer sequence for a subsequent
+ * read_until operation to examine.
+ *
+ * @par Example
+ * To read data into a @c std::string until a CR-LF sequence is encountered:
+ * @code std::string data;
+ * std::string n = boost::asio::read_until(s,
+ * boost::asio::dynamic_buffer(data), "\r\n");
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n); @endcode
+ * After the @c read_until operation completes successfully, the string @c data
+ * contains the delimiter:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the
+ * delimiter, so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the buffer @c b as
+ * follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c read_until operation.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Read data into a dynamic buffer sequence until it contains a specified
+/// delimiter.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains the specified
+ * delimiter. The call will block until one of the following conditions is
+ * true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains the delimiter, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ *
+ * @param delim The delimiter string.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the delimiter. Returns 0 if an error occurred.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond the delimiter. An application will
+ * typically leave that data in the dynamic buffer sequence for a subsequent
+ * read_until operation to examine.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+#if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
+ || defined(GENERATING_DOCUMENTATION)
+
+/// Read data into a dynamic buffer sequence until some part of the data it
+/// contains matches a regular expression.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains some data
+ * that matches a regular expression. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li A substring of the dynamic buffer sequence's get area matches the
+ * regular expression.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains data that matches the regular expression, the function returns
+ * immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers A dynamic buffer sequence into which the data will be read.
+ *
+ * @param expr The regular expression.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the substring that matches the regular expression.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond that which matched the regular
+ * expression. An application will typically leave that data in the dynamic
+ * buffer sequence for a subsequent read_until operation to examine.
+ *
+ * @par Example
+ * To read data into a @c std::string until a CR-LF sequence is encountered:
+ * @code std::string data;
+ * std::string n = boost::asio::read_until(s,
+ * boost::asio::dynamic_buffer(data), boost::regex("\r\n"));
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n); @endcode
+ * After the @c read_until operation completes successfully, the string @c data
+ * contains the delimiter:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the
+ * delimiter, so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the buffer @c b as
+ * follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c read_until operation.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ const boost::regex& expr,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Read data into a dynamic buffer sequence until some part of the data it
+/// contains matches a regular expression.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until the dynamic buffer sequence's get area contains some data
+ * that matches a regular expression. The call will block until one of the
+ * following conditions is true:
+ *
+ * @li A substring of the dynamic buffer sequence's get area matches the
+ * regular expression.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the dynamic buffer sequence's get area already
+ * contains data that matches the regular expression, the function returns
+ * immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers A dynamic buffer sequence into which the data will be read.
+ *
+ * @param expr The regular expression.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area up to
+ * and including the substring that matches the regular expression. Returns 0
+ * if an error occurred.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond that which matched the regular
+ * expression. An application will typically leave that data in the dynamic
+ * buffer sequence for a subsequent read_until operation to examine.
+ */
+template <typename SyncReadStream, typename DynamicBuffer_v2>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ const boost::regex& expr, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
+ // || defined(GENERATING_DOCUMENTATION)
+
+/// Read data into a dynamic buffer sequence until a function object indicates a
+/// match.
+
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until a user-defined match condition function object, when applied
+ * to the data contained in the dynamic buffer sequence, indicates a successful
+ * match. The call will block until one of the following conditions is true:
+ *
+ * @li The match condition function object returns a std::pair where the second
+ * element evaluates to true.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the match condition function object already indicates
+ * a match, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers A dynamic buffer sequence into which the data will be read.
+ *
+ * @param match_condition The function object to be called to determine whether
+ * a match exists. The signature of the function object must be:
+ * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
+ * @endcode
+ * where @c iterator represents the type:
+ * @code buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>
+ * @endcode
+ * The iterator parameters @c begin and @c end define the range of bytes to be
+ * scanned to determine whether there is a match. The @c first member of the
+ * return value is an iterator marking one-past-the-end of the bytes that have
+ * been consumed by the match function. This iterator is used to calculate the
+ * @c begin parameter for any subsequent invocation of the match condition. The
+ * @c second member of the return value is true if a match has been found, false
+ * otherwise.
+ *
+ * @returns The number of bytes in the dynamic_buffer's get area that
+ * have been fully consumed by the match function.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond that which matched the function object.
+ * An application will typically leave that data in the dynamic buffer sequence
+ * for a subsequent read_until operation to examine.
+
+ * @note The default implementation of the @c is_match_condition type trait
+ * evaluates to true for function pointers and function objects with a
+ * @c result_type typedef. It must be specialised for other user-defined
+ * function objects.
+ *
+ * @par Examples
+ * To read data into a dynamic buffer sequence until whitespace is encountered:
+ * @code typedef boost::asio::buffers_iterator<
+ * boost::asio::const_buffers_1> iterator;
+ *
+ * std::pair<iterator, bool>
+ * match_whitespace(iterator begin, iterator end)
+ * {
+ * iterator i = begin;
+ * while (i != end)
+ * if (std::isspace(*i++))
+ * return std::make_pair(i, true);
+ * return std::make_pair(i, false);
+ * }
+ * ...
+ * std::string data;
+ * boost::asio::read_until(s, data, match_whitespace);
+ * @endcode
+ *
+ * To read data into a @c std::string until a matching character is found:
+ * @code class match_char
+ * {
+ * public:
+ * explicit match_char(char c) : c_(c) {}
+ *
+ * template <typename Iterator>
+ * std::pair<Iterator, bool> operator()(
+ * Iterator begin, Iterator end) const
+ * {
+ * Iterator i = begin;
+ * while (i != end)
+ * if (c_ == *i++)
+ * return std::make_pair(i, true);
+ * return std::make_pair(i, false);
+ * }
+ *
+ * private:
+ * char c_;
+ * };
+ *
+ * namespace asio {
+ * template <> struct is_match_condition<match_char>
+ * : public boost::true_type {};
+ * } // namespace asio
+ * ...
+ * std::string data;
+ * boost::asio::read_until(s, data, match_char('a'));
+ * @endcode
+ */
+template <typename SyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ MatchCondition match_condition,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Read data into a dynamic buffer sequence until a function object indicates a
+/// match.
+/**
+ * This function is used to read data into the specified dynamic buffer
+ * sequence until a user-defined match condition function object, when applied
+ * to the data contained in the dynamic buffer sequence, indicates a successful
+ * match. The call will block until one of the following conditions is true:
+ *
+ * @li The match condition function object returns a std::pair where the second
+ * element evaluates to true.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * read_some function. If the match condition function object already indicates
+ * a match, the function returns immediately.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the SyncReadStream concept.
+ *
+ * @param buffers A dynamic buffer sequence into which the data will be read.
+ *
+ * @param match_condition The function object to be called to determine whether
+ * a match exists. The signature of the function object must be:
+ * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
+ * @endcode
+ * where @c iterator represents the type:
+ * @code buffers_iterator<DynamicBuffer_v2::const_buffers_type>
+ * @endcode
+ * The iterator parameters @c begin and @c end define the range of bytes to be
+ * scanned to determine whether there is a match. The @c first member of the
+ * return value is an iterator marking one-past-the-end of the bytes that have
+ * been consumed by the match function. This iterator is used to calculate the
+ * @c begin parameter for any subsequent invocation of the match condition. The
+ * @c second member of the return value is true if a match has been found, false
+ * otherwise.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes in the dynamic buffer sequence's get area that
+ * have been fully consumed by the match function. Returns 0 if an error
+ * occurred.
+ *
+ * @note After a successful read_until operation, the dynamic buffer sequence
+ * may contain additional data beyond that which matched the function object.
+ * An application will typically leave that data in the dynamic buffer sequence
+ * for a subsequent read_until operation to examine.
+ *
+ * @note The default implementation of the @c is_match_condition type trait
+ * evaluates to true for function pointers and function objects with a
+ * @c result_type typedef. It must be specialised for other user-defined
+ * function objects.
+ */
+template <typename SyncReadStream,
+ typename DynamicBuffer_v2, typename MatchCondition>
+std::size_t read_until(SyncReadStream& s, DynamicBuffer_v2 buffers,
+ MatchCondition match_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
/*@}*/
/**
@@ -994,6 +1515,8 @@ std::size_t read_until(SyncReadStream& s,
*/
/*@{*/
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Start an asynchronous operation to read data into a dynamic buffer sequence
/// until it contains a specified delimiter.
/**
@@ -1039,9 +1562,9 @@ std::size_t read_until(SyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the dynamic buffer
* sequence may contain additional data beyond the delimiter. An application
@@ -1077,12 +1600,16 @@ std::size_t read_until(SyncReadStream& s,
* @c async_read_until operation.
*/
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
- char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler);
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
+ char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
/// Start an asynchronous operation to read data into a dynamic buffer sequence
/// until it contains a specified delimiter.
@@ -1129,9 +1656,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the dynamic buffer
* sequence may contain additional data beyond the delimiter. An application
@@ -1167,13 +1694,17 @@ async_read_until(AsyncReadStream& s,
* @c async_read_until operation.
*/
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_STRING_VIEW_PARAM delim,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler);
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
#if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
@@ -1226,9 +1757,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the dynamic buffer
* sequence may contain additional data beyond that which matched the regular
@@ -1265,13 +1796,17 @@ async_read_until(AsyncReadStream& s,
* @c async_read_until operation.
*/
template <typename AsyncReadStream,
- typename DynamicBuffer, typename ReadHandler>
+ typename DynamicBuffer_v1, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
const boost::regex& expr,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler);
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
// || defined(GENERATING_DOCUMENTATION)
@@ -1312,7 +1847,7 @@ async_read_until(AsyncReadStream& s,
* @code pair<iterator, bool> match_condition(iterator begin, iterator end);
* @endcode
* where @c iterator represents the type:
- * @code buffers_iterator<typename DynamicBuffer::const_buffers_type>
+ * @code buffers_iterator<typename DynamicBuffer_v1::const_buffers_type>
* @endcode
* The iterator parameters @c begin and @c end define the range of bytes to be
* scanned to determine whether there is a match. The @c first member of the
@@ -1335,9 +1870,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the dynamic buffer
* sequence may contain additional data beyond that which matched the function
@@ -1404,14 +1939,18 @@ async_read_until(AsyncReadStream& s,
* boost::asio::async_read_until(s, data, match_char('a'), handler);
* @endcode
*/
-template <typename AsyncReadStream, typename DynamicBuffer,
+template <typename AsyncReadStream, typename DynamicBuffer_v1,
typename MatchCondition, typename ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (boost::system::error_code, std::size_t))
async_read_until(AsyncReadStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
- typename enable_if<is_match_condition<MatchCondition>::value>::type* = 0);
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
+ >::type* = 0);
#if !defined(BOOST_ASIO_NO_IOSTREAM)
@@ -1457,9 +1996,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the streambuf may
* contain additional data beyond the delimiter. An application will typically
@@ -1542,9 +2081,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the streambuf may
* contain additional data beyond the delimiter. An application will typically
@@ -1634,9 +2173,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the streambuf may
* contain additional data beyond that which matched the regular expression. An
@@ -1736,9 +2275,9 @@ async_read_until(AsyncReadStream& s,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note After a successful async_read_until operation, the streambuf may
* contain additional data beyond that which matched the function object. An
@@ -1815,6 +2354,436 @@ async_read_until(AsyncReadStream& s,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Start an asynchronous operation to read data into a dynamic buffer sequence
+/// until it contains a specified delimiter.
+/**
+ * This function is used to asynchronously read data into the specified dynamic
+ * buffer sequence until the dynamic buffer sequence's get area contains the
+ * specified delimiter. The function call always returns immediately. The
+ * asynchronous operation will continue until one of the following conditions
+ * is true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_read_some function, and is known as a <em>composed operation</em>. If
+ * the dynamic buffer sequence's get area already contains the delimiter, this
+ * asynchronous operation completes immediately. The program must ensure that
+ * the stream performs no other read operations (such as async_read,
+ * async_read_until, the stream's async_read_some function, or any other
+ * composed operations that perform reads) until this operation completes.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param delim The delimiter character.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * // Result of operation.
+ * const boost::system::error_code& error,
+ *
+ * // The number of bytes in the dynamic buffer sequence's
+ * // get area up to and including the delimiter.
+ * // 0 if an error occurred.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note After a successful async_read_until operation, the dynamic buffer
+ * sequence may contain additional data beyond the delimiter. An application
+ * will typically leave that data in the dynamic buffer sequence for a
+ * subsequent async_read_until operation to examine.
+ *
+ * @par Example
+ * To asynchronously read data into a @c std::string until a newline is
+ * encountered:
+ * @code std::string data;
+ * ...
+ * void handler(const boost::system::error_code& e, std::size_t size)
+ * {
+ * if (!e)
+ * {
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n);
+ * ...
+ * }
+ * }
+ * ...
+ * boost::asio::async_read_until(s, data, '\n', handler); @endcode
+ * After the @c async_read_until operation completes successfully, the buffer
+ * @c data contains the delimiter:
+ * @code { 'a', 'b', ..., 'c', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the
+ * delimiter, so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the buffer @c data
+ * as follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c async_read_until operation.
+ */
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ char delim, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Start an asynchronous operation to read data into a dynamic buffer sequence
+/// until it contains a specified delimiter.
+/**
+ * This function is used to asynchronously read data into the specified dynamic
+ * buffer sequence until the dynamic buffer sequence's get area contains the
+ * specified delimiter. The function call always returns immediately. The
+ * asynchronous operation will continue until one of the following conditions
+ * is true:
+ *
+ * @li The get area of the dynamic buffer sequence contains the specified
+ * delimiter.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_read_some function, and is known as a <em>composed operation</em>. If
+ * the dynamic buffer sequence's get area already contains the delimiter, this
+ * asynchronous operation completes immediately. The program must ensure that
+ * the stream performs no other read operations (such as async_read,
+ * async_read_until, the stream's async_read_some function, or any other
+ * composed operations that perform reads) until this operation completes.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param delim The delimiter string.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * // Result of operation.
+ * const boost::system::error_code& error,
+ *
+ * // The number of bytes in the dynamic buffer sequence's
+ * // get area up to and including the delimiter.
+ * // 0 if an error occurred.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note After a successful async_read_until operation, the dynamic buffer
+ * sequence may contain additional data beyond the delimiter. An application
+ * will typically leave that data in the dynamic buffer sequence for a
+ * subsequent async_read_until operation to examine.
+ *
+ * @par Example
+ * To asynchronously read data into a @c std::string until a CR-LF sequence is
+ * encountered:
+ * @code std::string data;
+ * ...
+ * void handler(const boost::system::error_code& e, std::size_t size)
+ * {
+ * if (!e)
+ * {
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n);
+ * ...
+ * }
+ * }
+ * ...
+ * boost::asio::async_read_until(s, data, "\r\n", handler); @endcode
+ * After the @c async_read_until operation completes successfully, the string
+ * @c data contains the delimiter:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the
+ * delimiter, so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the string @c data
+ * as follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c async_read_until operation.
+ */
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_STRING_VIEW_PARAM delim,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#if !defined(BOOST_ASIO_NO_EXTENSIONS)
+#if defined(BOOST_ASIO_HAS_BOOST_REGEX) \
+ || defined(GENERATING_DOCUMENTATION)
+
+/// Start an asynchronous operation to read data into a dynamic buffer sequence
+/// until some part of its data matches a regular expression.
+/**
+ * This function is used to asynchronously read data into the specified dynamic
+ * buffer sequence until the dynamic buffer sequence's get area contains some
+ * data that matches a regular expression. The function call always returns
+ * immediately. The asynchronous operation will continue until one of the
+ * following conditions is true:
+ *
+ * @li A substring of the dynamic buffer sequence's get area matches the regular
+ * expression.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_read_some function, and is known as a <em>composed operation</em>. If
+ * the dynamic buffer sequence's get area already contains data that matches
+ * the regular expression, this asynchronous operation completes immediately.
+ * The program must ensure that the stream performs no other read operations
+ * (such as async_read, async_read_until, the stream's async_read_some
+ * function, or any other composed operations that perform reads) until this
+ * operation completes.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param expr The regular expression.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * // Result of operation.
+ * const boost::system::error_code& error,
+ *
+ * // The number of bytes in the dynamic buffer
+ * // sequence's get area up to and including the
+ * // substring that matches the regular expression.
+ * // 0 if an error occurred.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note After a successful async_read_until operation, the dynamic buffer
+ * sequence may contain additional data beyond that which matched the regular
+ * expression. An application will typically leave that data in the dynamic
+ * buffer sequence for a subsequent async_read_until operation to examine.
+ *
+ * @par Example
+ * To asynchronously read data into a @c std::string until a CR-LF sequence is
+ * encountered:
+ * @code std::string data;
+ * ...
+ * void handler(const boost::system::error_code& e, std::size_t size)
+ * {
+ * if (!e)
+ * {
+ * std::string line = data.substr(0, n);
+ * data.erase(0, n);
+ * ...
+ * }
+ * }
+ * ...
+ * boost::asio::async_read_until(s, data,
+ * boost::regex("\r\n"), handler); @endcode
+ * After the @c async_read_until operation completes successfully, the string
+ * @c data contains the data which matched the regular expression:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n', 'd', 'e', ... } @endcode
+ * The call to @c substr then extracts the data up to and including the match,
+ * so that the string @c line contains:
+ * @code { 'a', 'b', ..., 'c', '\r', '\n' } @endcode
+ * After the call to @c erase, the remaining data is left in the string @c data
+ * as follows:
+ * @code { 'd', 'e', ... } @endcode
+ * This data may be the start of a new line, to be extracted by a subsequent
+ * @c async_read_until operation.
+ */
+template <typename AsyncReadStream,
+ typename DynamicBuffer_v2, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ const boost::regex& expr,
+ BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#endif // defined(BOOST_ASIO_HAS_BOOST_REGEX)
+ // || defined(GENERATING_DOCUMENTATION)
+
+/// Start an asynchronous operation to read data into a dynamic buffer sequence
+/// until a function object indicates a match.
+/**
+ * This function is used to asynchronously read data into the specified dynamic
+ * buffer sequence until a user-defined match condition function object, when
+ * applied to the data contained in the dynamic buffer sequence, indicates a
+ * successful match. The function call always returns immediately. The
+ * asynchronous operation will continue until one of the following conditions
+ * is true:
+ *
+ * @li The match condition function object returns a std::pair where the second
+ * element evaluates to true.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_read_some function, and is known as a <em>composed operation</em>. If
+ * the match condition function object already indicates a match, this
+ * asynchronous operation completes immediately. The program must ensure that
+ * the stream performs no other read operations (such as async_read,
+ * async_read_until, the stream's async_read_some function, or any other
+ * composed operations that perform reads) until this operation completes.
+ *
+ * @param s The stream from which the data is to be read. The type must support
+ * the AsyncReadStream concept.
+ *
+ * @param buffers The dynamic buffer sequence into which the data will be read.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called.
+ *
+ * @param match_condition The function object to be called to determine whether
+ * a match exists. The signature of the function object must be:
+ * @code pair<iterator, bool> match_condition(iterator begin, iterator end);
+ * @endcode
+ * where @c iterator represents the type:
+ * @code buffers_iterator<typename DynamicBuffer_v2::const_buffers_type>
+ * @endcode
+ * The iterator parameters @c begin and @c end define the range of bytes to be
+ * scanned to determine whether there is a match. The @c first member of the
+ * return value is an iterator marking one-past-the-end of the bytes that have
+ * been consumed by the match function. This iterator is used to calculate the
+ * @c begin parameter for any subsequent invocation of the match condition. The
+ * @c second member of the return value is true if a match has been found, false
+ * otherwise.
+ *
+ * @param handler The handler to be called when the read operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * // Result of operation.
+ * const boost::system::error_code& error,
+ *
+ * // The number of bytes in the dynamic buffer sequence's
+ * // get area that have been fully consumed by the match
+ * // function. O if an error occurred.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ *
+ * @note After a successful async_read_until operation, the dynamic buffer
+ * sequence may contain additional data beyond that which matched the function
+ * object. An application will typically leave that data in the dynamic buffer
+ * sequence for a subsequent async_read_until operation to examine.
+ *
+ * @note The default implementation of the @c is_match_condition type trait
+ * evaluates to true for function pointers and function objects with a
+ * @c result_type typedef. It must be specialised for other user-defined
+ * function objects.
+ *
+ * @par Examples
+ * To asynchronously read data into a @c std::string until whitespace is
+ * encountered:
+ * @code typedef boost::asio::buffers_iterator<
+ * boost::asio::const_buffers_1> iterator;
+ *
+ * std::pair<iterator, bool>
+ * match_whitespace(iterator begin, iterator end)
+ * {
+ * iterator i = begin;
+ * while (i != end)
+ * if (std::isspace(*i++))
+ * return std::make_pair(i, true);
+ * return std::make_pair(i, false);
+ * }
+ * ...
+ * void handler(const boost::system::error_code& e, std::size_t size);
+ * ...
+ * std::string data;
+ * boost::asio::async_read_until(s, data, match_whitespace, handler);
+ * @endcode
+ *
+ * To asynchronously read data into a @c std::string until a matching character
+ * is found:
+ * @code class match_char
+ * {
+ * public:
+ * explicit match_char(char c) : c_(c) {}
+ *
+ * template <typename Iterator>
+ * std::pair<Iterator, bool> operator()(
+ * Iterator begin, Iterator end) const
+ * {
+ * Iterator i = begin;
+ * while (i != end)
+ * if (c_ == *i++)
+ * return std::make_pair(i, true);
+ * return std::make_pair(i, false);
+ * }
+ *
+ * private:
+ * char c_;
+ * };
+ *
+ * namespace asio {
+ * template <> struct is_match_condition<match_char>
+ * : public boost::true_type {};
+ * } // namespace asio
+ * ...
+ * void handler(const boost::system::error_code& e, std::size_t size);
+ * ...
+ * std::string data;
+ * boost::asio::async_read_until(s, data, match_char('a'), handler);
+ * @endcode
+ */
+template <typename AsyncReadStream, typename DynamicBuffer_v2,
+ typename MatchCondition, typename ReadHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
+ void (boost::system::error_code, std::size_t))
+async_read_until(AsyncReadStream& s, DynamicBuffer_v2 buffers,
+ MatchCondition match_condition, BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ typename enable_if<
+ is_match_condition<MatchCondition>::value
+ && is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
/*@}*/
diff --git a/boost/asio/experimental/redirect_error.hpp b/boost/asio/redirect_error.hpp
index a138854521..f4563a5931 100644
--- a/boost/asio/experimental/redirect_error.hpp
+++ b/boost/asio/redirect_error.hpp
@@ -1,15 +1,15 @@
//
-// experimental/redirect_error.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// redirect_error.hpp
+// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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_EXPERIMENTAL_REDIRECT_ERROR_HPP
-#define BOOST_ASIO_EXPERIMENTAL_REDIRECT_ERROR_HPP
+#ifndef BOOST_ASIO_REDIRECT_ERROR_HPP
+#define BOOST_ASIO_REDIRECT_ERROR_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
@@ -23,7 +23,6 @@
namespace boost {
namespace asio {
-namespace experimental {
/// Completion token type used to specify that an error produced by an
/// asynchronous operation is captured to an error_code variable.
@@ -52,18 +51,18 @@ public:
/// Create a completion token to capture error_code values to a variable.
template <typename CompletionToken>
inline redirect_error_t<typename decay<CompletionToken>::type> redirect_error(
- CompletionToken&& completion_token, boost::system::error_code& ec)
+ BOOST_ASIO_MOVE_ARG(CompletionToken) completion_token,
+ boost::system::error_code& ec)
{
return redirect_error_t<typename decay<CompletionToken>::type>(
BOOST_ASIO_MOVE_CAST(CompletionToken)(completion_token), ec);
}
-} // namespace experimental
} // namespace asio
} // namespace boost
#include <boost/asio/detail/pop_options.hpp>
-#include <boost/asio/experimental/impl/redirect_error.hpp>
+#include <boost/asio/impl/redirect_error.hpp>
-#endif // BOOST_ASIO_EXPERIMENTAL_REDIRECT_ERROR_HPP
+#endif // BOOST_ASIO_REDIRECT_ERROR_HPP
diff --git a/boost/asio/seq_packet_socket_service.hpp b/boost/asio/seq_packet_socket_service.hpp
deleted file mode 100644
index d6445782b3..0000000000
--- a/boost/asio/seq_packet_socket_service.hpp
+++ /dev/null
@@ -1,418 +0,0 @@
-//
-// seq_packet_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_SEQ_PACKET_SOCKET_SERVICE_HPP
-#define BOOST_ASIO_SEQ_PACKET_SOCKET_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_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a sequenced packet socket.
-template <typename Protocol>
-class seq_packet_socket_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<
- seq_packet_socket_service<Protocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef Protocol protocol_type;
-
- /// The endpoint type.
- typedef typename Protocol::endpoint endpoint_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef detail::null_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service<Protocol> service_impl_type;
-#endif
-
-public:
- /// The type of a sequenced packet socket implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native socket type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new sequenced packet socket service for the specified
- /// io_context.
- explicit seq_packet_socket_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- seq_packet_socket_service<Protocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new sequenced packet socket implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new sequenced packet socket implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another sequenced packet socket implementation.
- void move_assign(implementation_type& impl,
- seq_packet_socket_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-
- // All socket services have access to each other's implementations.
- template <typename Protocol1> friend class seq_packet_socket_service;
-
- /// Move-construct a new sequenced packet socket implementation from another
- /// protocol type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- seq_packet_socket_service<Protocol1>& other_service,
- typename seq_packet_socket_service<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a sequenced packet socket implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Open a sequenced packet socket.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const protocol_type& protocol, boost::system::error_code& ec)
- {
- if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_SEQPACKET))
- service_impl_.open(impl, protocol, ec);
- else
- ec = boost::asio::error::invalid_argument;
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native socket to a sequenced packet socket.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const protocol_type& protocol, const native_handle_type& native_socket,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, protocol, native_socket, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a sequenced packet socket implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Release ownership of the underlying socket.
- native_handle_type release(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.release(impl, ec);
- }
-
- /// Get the native socket implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the socket.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_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
- {
- return service_impl_.at_mark(impl, ec);
- }
-
- /// Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.available(impl, ec);
- }
-
- /// Bind the sequenced packet socket to the specified local endpoint.
- BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- service_impl_.bind(impl, endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Connect the sequenced packet socket to the specified endpoint.
- BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, boost::system::error_code& ec)
- {
- service_impl_.connect(impl, peer_endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Start an asynchronous connect.
- template <typename ConnectHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
- void (boost::system::error_code))
- async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint,
- BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
- {
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSocketOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a socket option.
- template <typename GettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSocketOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the socket.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the socket.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the socket.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native socket implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native socket implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the local endpoint.
- endpoint_type local_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.local_endpoint(impl, ec);
- }
-
- /// Get the remote endpoint.
- endpoint_type remote_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.remote_endpoint(impl, ec);
- }
-
- /// Disable sends or receives on the socket.
- BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- service_impl_.shutdown(impl, what, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the socket to become ready to read, ready to write, or to have
- /// pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- socket_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the socket to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, socket_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send the given data to the peer.
- template <typename ConstBufferSequence>
- std::size_t send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive some data from the peer.
- template <typename MutableBufferSequence>
- std::size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags, boost::system::error_code& ec)
- {
- return service_impl_.receive_with_flags(impl,
- buffers, in_flags, out_flags, ec);
- }
-
- /// Start an asynchronous receive.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive(implementation_type& impl,
- const MutableBufferSequence& buffers, socket_base::message_flags in_flags,
- socket_base::message_flags& out_flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive_with_flags(impl,
- buffers, in_flags, out_flags, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_SEQ_PACKET_SOCKET_SERVICE_HPP
diff --git a/boost/asio/serial_port.hpp b/boost/asio/serial_port.hpp
index f2185b8037..b0960d8934 100644
--- a/boost/asio/serial_port.hpp
+++ b/boost/asio/serial_port.hpp
@@ -2,7 +2,7 @@
// serial_port.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -21,750 +21,17 @@
#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION)
-#include <string>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/serial_port_base.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/basic_serial_port.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# if defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_serial_port_service.hpp>
-# define BOOST_ASIO_SVC_T detail::win_iocp_serial_port_service
-# else
-# include <boost/asio/detail/reactive_serial_port_service.hpp>
-# define BOOST_ASIO_SVC_T detail::reactive_serial_port_service
-# endif
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/basic_serial_port.hpp>
namespace boost {
namespace asio {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of a serial port.
+/// Typedef for the typical usage of a serial port.
typedef basic_serial_port<> serial_port;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides serial port functionality.
-/**
- * The serial_port class provides a wrapper over serial port functionality.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-class serial_port
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>,
- public serial_port_base
-{
-public:
- /// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
-
- /// The native representation of a serial port.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
-#endif
-
- /// A basic_serial_port is always the lowest layer.
- typedef serial_port lowest_layer_type;
-
- /// Construct a serial_port without opening it.
- /**
- * This constructor creates a serial port without opening it.
- *
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
- */
- explicit serial_port(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- }
-
- /// Construct and open a serial_port.
- /**
- * This constructor creates and opens a serial port for the specified device
- * name.
- *
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
- *
- * @param device The platform-specific device name for this serial
- * port.
- */
- explicit serial_port(boost::asio::io_context& io_context,
- const char* device)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
- boost::asio::detail::throw_error(ec, "open");
- }
-
- /// Construct and open a serial_port.
- /**
- * This constructor creates and opens a serial port for the specified device
- * name.
- *
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
- *
- * @param device The platform-specific device name for this serial
- * port.
- */
- explicit serial_port(boost::asio::io_context& io_context,
- const std::string& device)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
- boost::asio::detail::throw_error(ec, "open");
- }
-
- /// Construct a serial_port on an existing native serial port.
- /**
- * This constructor creates a serial port object to hold an existing native
- * serial port.
- *
- * @param io_context The io_context object that the serial port will use to
- * dispatch handlers for any asynchronous operations performed on the port.
- *
- * @param native_serial_port A native serial port.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- serial_port(boost::asio::io_context& io_context,
- const native_handle_type& native_serial_port)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
- native_serial_port, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a serial_port from another.
- /**
- * This constructor moves a serial port from one object to another.
- *
- * @param other The other serial_port object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c serial_port(io_context&) constructor.
- */
- serial_port(serial_port&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
- {
- }
-
- /// Move-assign a serial_port from another.
- /**
- * This assignment operator moves a serial port from one object to another.
- *
- * @param other The other serial_port object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c serial_port(io_context&) constructor.
- */
- serial_port& operator=(serial_port&& other)
- {
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroys the serial port.
- /**
- * This function destroys the serial port, cancelling any outstanding
- * asynchronous wait operations associated with the serial port as if by
- * calling @c cancel.
- */
- ~serial_port()
- {
- }
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the executor associated with the object.
- executor_type get_executor() BOOST_ASIO_NOEXCEPT
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
- }
-
- /// Get a reference to the lowest layer.
- /**
- * This function returns a reference to the lowest layer in a stack of
- * layers. Since a serial_port cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A reference to the lowest layer in the stack of layers. Ownership
- * is not transferred to the caller.
- */
- lowest_layer_type& lowest_layer()
- {
- return *this;
- }
-
- /// Get a const reference to the lowest layer.
- /**
- * This function returns a const reference to the lowest layer in a stack of
- * layers. Since a serial_port cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A const reference to the lowest layer in the stack of layers.
- * Ownership is not transferred to the caller.
- */
- const lowest_layer_type& lowest_layer() const
- {
- return *this;
- }
-
- /// Open the serial port using the specified device name.
- /**
- * This function opens the serial port for the specified device name.
- *
- * @param device The platform-specific device name.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void open(const std::string& device)
- {
- boost::system::error_code ec;
- this->get_service().open(this->get_implementation(), device, ec);
- boost::asio::detail::throw_error(ec, "open");
- }
-
- /// Open the serial port using the specified device name.
- /**
- * This function opens the serial port using the given platform-specific
- * device name.
- *
- * @param device The platform-specific device name.
- *
- * @param ec Set the indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID open(const std::string& device,
- boost::system::error_code& ec)
- {
- this->get_service().open(this->get_implementation(), device, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native serial port to the serial port.
- /*
- * This function opens the serial port to hold an existing native serial port.
- *
- * @param native_serial_port A native serial port.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void assign(const native_handle_type& native_serial_port)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(),
- native_serial_port, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
- /// Assign an existing native serial port to the serial port.
- /*
- * This function opens the serial port to hold an existing native serial port.
- *
- * @param native_serial_port A native serial port.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port,
- boost::system::error_code& ec)
- {
- this->get_service().assign(this->get_implementation(),
- native_serial_port, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the serial port is open.
- bool is_open() const
- {
- return this->get_service().is_open(this->get_implementation());
- }
-
- /// Close the serial port.
- /**
- * This function is used to close the serial port. Any asynchronous read or
- * write operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void close()
- {
- boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "close");
- }
-
- /// Close the serial port.
- /**
- * This function is used to close the serial port. Any asynchronous read or
- * write operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
- {
- this->get_service().close(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native serial port representation.
- /**
- * This function may be used to obtain the underlying representation of the
- * serial port. This is intended to allow access to native serial port
- * functionality that is not otherwise provided.
- */
- native_handle_type native_handle()
- {
- return this->get_service().native_handle(this->get_implementation());
- }
-
- /// Cancel all asynchronous operations associated with the serial port.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all asynchronous operations associated with the serial port.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Send a break sequence to the serial port.
- /**
- * This function causes a break sequence of platform-specific duration to be
- * sent out the serial port.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void send_break()
- {
- boost::system::error_code ec;
- this->get_service().send_break(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "send_break");
- }
-
- /// Send a break sequence to the serial port.
- /**
- * This function causes a break sequence of platform-specific duration to be
- * sent out the serial port.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID send_break(boost::system::error_code& ec)
- {
- this->get_service().send_break(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Set an option on the serial port.
- /**
- * This function is used to set an option on the serial port.
- *
- * @param option The option value to be set on the serial port.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @sa SettableSerialPortOption @n
- * boost::asio::serial_port_base::baud_rate @n
- * boost::asio::serial_port_base::flow_control @n
- * boost::asio::serial_port_base::parity @n
- * boost::asio::serial_port_base::stop_bits @n
- * boost::asio::serial_port_base::character_size
- */
- template <typename SettableSerialPortOption>
- void set_option(const SettableSerialPortOption& option)
- {
- boost::system::error_code ec;
- this->get_service().set_option(this->get_implementation(), option, ec);
- boost::asio::detail::throw_error(ec, "set_option");
- }
-
- /// Set an option on the serial port.
- /**
- * This function is used to set an option on the serial port.
- *
- * @param option The option value to be set on the serial port.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @sa SettableSerialPortOption @n
- * boost::asio::serial_port_base::baud_rate @n
- * boost::asio::serial_port_base::flow_control @n
- * boost::asio::serial_port_base::parity @n
- * boost::asio::serial_port_base::stop_bits @n
- * boost::asio::serial_port_base::character_size
- */
- template <typename SettableSerialPortOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option,
- boost::system::error_code& ec)
- {
- this->get_service().set_option(this->get_implementation(), option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get an option from the serial port.
- /**
- * This function is used to get the current value of an option on the serial
- * port.
- *
- * @param option The option value to be obtained from the serial port.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @sa GettableSerialPortOption @n
- * boost::asio::serial_port_base::baud_rate @n
- * boost::asio::serial_port_base::flow_control @n
- * boost::asio::serial_port_base::parity @n
- * boost::asio::serial_port_base::stop_bits @n
- * boost::asio::serial_port_base::character_size
- */
- template <typename GettableSerialPortOption>
- void get_option(GettableSerialPortOption& option)
- {
- boost::system::error_code ec;
- this->get_service().get_option(this->get_implementation(), option, ec);
- boost::asio::detail::throw_error(ec, "get_option");
- }
-
- /// Get an option from the serial port.
- /**
- * This function is used to get the current value of an option on the serial
- * port.
- *
- * @param option The option value to be obtained from the serial port.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @sa GettableSerialPortOption @n
- * boost::asio::serial_port_base::baud_rate @n
- * boost::asio::serial_port_base::flow_control @n
- * boost::asio::serial_port_base::parity @n
- * boost::asio::serial_port_base::stop_bits @n
- * boost::asio::serial_port_base::character_size
- */
- template <typename GettableSerialPortOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
- boost::system::error_code& ec)
- {
- this->get_service().get_option(this->get_implementation(), option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Write some data to the serial port.
- /**
- * This function is used to write data to the serial port. The function call
- * will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the serial port.
- *
- * @returns The number of bytes written.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * serial_port.write_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "write_some");
- return s;
- }
-
- /// Write some data to the serial port.
- /**
- * This function is used to write data to the serial port. The function call
- * will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the serial port.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes written. Returns 0 if an error occurred.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous write.
- /**
- * This function is used to asynchronously write data to the serial port.
- * The function call always returns immediately.
- *
- * @param buffers One or more data buffers to be written to the serial port.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the write operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes written.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The write operation may not transmit all of the data to the peer.
- * Consider using the @ref async_write function if you need to ensure that all
- * data is written before the asynchronous operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * serial_port.async_write_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_write_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the serial port.
- /**
- * This function is used to read data from the serial port. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @returns The number of bytes read.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * serial_port.read_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "read_some");
- return s;
- }
-
- /// Read some data from the serial port.
- /**
- * This function is used to read data from the serial port. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes read. Returns 0 if an error occurred.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous read.
- /**
- * This function is used to asynchronously read data from the serial port.
- * The function call always returns immediately.
- *
- * @param buffers One or more buffers into which the data will be read.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the read operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes read.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The read operation may not read all of the requested number of bytes.
- * Consider using the @ref async_read function if you need to ensure that the
- * requested amount of data is read before the asynchronous operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * serial_port.async_read_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_read_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# undef BOOST_ASIO_SVC_T
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/serial_port_base.hpp b/boost/asio/serial_port_base.hpp
index 3b8c4951f3..f902af1ebe 100644
--- a/boost/asio/serial_port_base.hpp
+++ b/boost/asio/serial_port_base.hpp
@@ -2,7 +2,7 @@
// serial_port_base.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
diff --git a/boost/asio/serial_port_service.hpp b/boost/asio/serial_port_service.hpp
deleted file mode 100644
index 935f92fffa..0000000000
--- a/boost/asio/serial_port_service.hpp
+++ /dev/null
@@ -1,251 +0,0 @@
-//
-// serial_port_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_SERIAL_PORT_SERVICE_HPP
-#define BOOST_ASIO_SERIAL_PORT_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_SERIAL_PORT) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <cstddef>
-#include <string>
-#include <boost/asio/async_result.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_context.hpp>
-#include <boost/asio/serial_port_base.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a serial port.
-class serial_port_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<serial_port_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_serial_port_service service_impl_type;
-#else
- typedef detail::reactive_serial_port_service service_impl_type;
-#endif
-
-public:
- /// The type of a serial port implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native handle type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new serial port service for the specified io_context.
- explicit serial_port_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<serial_port_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new serial port implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new serial port implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another serial port implementation.
- void move_assign(implementation_type& impl,
- serial_port_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a serial port implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Open a serial port.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const std::string& device, boost::system::error_code& ec)
- {
- service_impl_.open(impl, device, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native handle to a serial port.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const native_handle_type& handle, boost::system::error_code& ec)
- {
- service_impl_.assign(impl, handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a serial port implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Set a serial port option.
- template <typename SettableSerialPortOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSerialPortOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a serial port option.
- template <typename GettableSerialPortOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSerialPortOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Send a break sequence to the serial port.
- BOOST_ASIO_SYNC_OP_VOID send_break(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.send_break(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Write the given data to the stream.
- template <typename ConstBufferSequence>
- std::size_t write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.write_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous write.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_write_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the stream.
- template <typename MutableBufferSequence>
- std::size_t read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.read_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous read.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_read_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_SERIAL_PORT)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_SERIAL_PORT_SERVICE_HPP
diff --git a/boost/asio/signal_set.hpp b/boost/asio/signal_set.hpp
index 0ddb996a58..29cfd1b3e5 100644
--- a/boost/asio/signal_set.hpp
+++ b/boost/asio/signal_set.hpp
@@ -2,7 +2,7 @@
// signal_set.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,432 +16,13 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/basic_signal_set.hpp>
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/detail/signal_set_service.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#include <boost/asio/basic_signal_set.hpp>
namespace boost {
namespace asio {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of a signal set.
+/// Typedef for the typical usage of a signal set.
typedef basic_signal_set<> signal_set;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides signal functionality.
-/**
- * The signal_set class provides the ability to perform an asynchronous wait
- * for one or more signals to occur.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- *
- * @par Example
- * Performing an asynchronous wait:
- * @code
- * void handler(
- * const boost::system::error_code& error,
- * int signal_number)
- * {
- * if (!error)
- * {
- * // A signal occurred.
- * }
- * }
- *
- * ...
- *
- * // Construct a signal set registered for process termination.
- * boost::asio::signal_set signals(io_context, SIGINT, SIGTERM);
- *
- * // Start an asynchronous wait for one of the signals to occur.
- * signals.async_wait(handler);
- * @endcode
- *
- * @par Queueing of signal notifications
- *
- * If a signal is registered with a signal_set, and the signal occurs when
- * there are no waiting handlers, then the signal notification is queued. The
- * next async_wait operation on that signal_set will dequeue the notification.
- * If multiple notifications are queued, subsequent async_wait operations
- * dequeue them one at a time. Signal notifications are dequeued in order of
- * ascending signal number.
- *
- * If a signal number is removed from a signal_set (using the @c remove or @c
- * erase member functions) then any queued notifications for that signal are
- * discarded.
- *
- * @par Multiple registration of signals
- *
- * The same signal number may be registered with different signal_set objects.
- * When the signal occurs, one handler is called for each signal_set object.
- *
- * Note that multiple registration only works for signals that are registered
- * using Asio. The application must not also register a signal handler using
- * functions such as @c signal() or @c sigaction().
- *
- * @par Signal masking on POSIX platforms
- *
- * POSIX allows signals to be blocked using functions such as @c sigprocmask()
- * and @c pthread_sigmask(). For signals to be delivered, programs must ensure
- * that any signals registered using signal_set objects are unblocked in at
- * least one thread.
- */
-class signal_set
- : BOOST_ASIO_SVC_ACCESS basic_io_object<detail::signal_set_service>
-{
-public:
- /// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
-
- /// Construct a signal set without adding any signals.
- /**
- * This constructor creates a signal set without registering for any signals.
- *
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
- */
- explicit signal_set(boost::asio::io_context& io_context)
- : basic_io_object<detail::signal_set_service>(io_context)
- {
- }
-
- /// Construct a signal set and add one signal.
- /**
- * This constructor creates a signal set and registers for one signal.
- *
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
- *
- * @param signal_number_1 The signal number to be added.
- *
- * @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
- * signals.add(signal_number_1); @endcode
- */
- signal_set(boost::asio::io_context& io_context, int signal_number_1)
- : basic_io_object<detail::signal_set_service>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
- boost::asio::detail::throw_error(ec, "add");
- }
-
- /// Construct a signal set and add two signals.
- /**
- * This constructor creates a signal set and registers for two signals.
- *
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
- *
- * @param signal_number_1 The first signal number to be added.
- *
- * @param signal_number_2 The second signal number to be added.
- *
- * @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
- * signals.add(signal_number_1);
- * signals.add(signal_number_2); @endcode
- */
- signal_set(boost::asio::io_context& io_context, int signal_number_1,
- int signal_number_2)
- : basic_io_object<detail::signal_set_service>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
- boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_2, ec);
- boost::asio::detail::throw_error(ec, "add");
- }
-
- /// Construct a signal set and add three signals.
- /**
- * This constructor creates a signal set and registers for three signals.
- *
- * @param io_context The io_context object that the signal set will use to
- * dispatch handlers for any asynchronous operations performed on the set.
- *
- * @param signal_number_1 The first signal number to be added.
- *
- * @param signal_number_2 The second signal number to be added.
- *
- * @param signal_number_3 The third signal number to be added.
- *
- * @note This constructor is equivalent to performing:
- * @code boost::asio::signal_set signals(io_context);
- * signals.add(signal_number_1);
- * signals.add(signal_number_2);
- * signals.add(signal_number_3); @endcode
- */
- signal_set(boost::asio::io_context& io_context, int signal_number_1,
- int signal_number_2, int signal_number_3)
- : basic_io_object<detail::signal_set_service>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number_1, ec);
- boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_2, ec);
- boost::asio::detail::throw_error(ec, "add");
- this->get_service().add(this->get_implementation(), signal_number_3, ec);
- boost::asio::detail::throw_error(ec, "add");
- }
-
- /// Destroys the signal set.
- /**
- * This function destroys the signal set, cancelling any outstanding
- * asynchronous wait operations associated with the signal set as if by
- * calling @c cancel.
- */
- ~signal_set()
- {
- }
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<detail::signal_set_service>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<detail::signal_set_service>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the executor associated with the object.
- executor_type get_executor() BOOST_ASIO_NOEXCEPT
- {
- return basic_io_object<detail::signal_set_service>::get_executor();
- }
-
- /// Add a signal to a signal_set.
- /**
- * This function adds the specified signal to the set. It has no effect if the
- * signal is already in the set.
- *
- * @param signal_number The signal to be added to the set.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void add(int signal_number)
- {
- boost::system::error_code ec;
- this->get_service().add(this->get_implementation(), signal_number, ec);
- boost::asio::detail::throw_error(ec, "add");
- }
-
- /// Add a signal to a signal_set.
- /**
- * This function adds the specified signal to the set. It has no effect if the
- * signal is already in the set.
- *
- * @param signal_number The signal to be added to the set.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID add(int signal_number,
- boost::system::error_code& ec)
- {
- this->get_service().add(this->get_implementation(), signal_number, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Remove a signal from a signal_set.
- /**
- * This function removes the specified signal from the set. It has no effect
- * if the signal is not in the set.
- *
- * @param signal_number The signal to be removed from the set.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @note Removes any notifications that have been queued for the specified
- * signal number.
- */
- void remove(int signal_number)
- {
- boost::system::error_code ec;
- this->get_service().remove(this->get_implementation(), signal_number, ec);
- boost::asio::detail::throw_error(ec, "remove");
- }
-
- /// Remove a signal from a signal_set.
- /**
- * This function removes the specified signal from the set. It has no effect
- * if the signal is not in the set.
- *
- * @param signal_number The signal to be removed from the set.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @note Removes any notifications that have been queued for the specified
- * signal number.
- */
- BOOST_ASIO_SYNC_OP_VOID remove(int signal_number,
- boost::system::error_code& ec)
- {
- this->get_service().remove(this->get_implementation(), signal_number, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Remove all signals from a signal_set.
- /**
- * This function removes all signals from the set. It has no effect if the set
- * is already empty.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @note Removes all queued notifications.
- */
- void clear()
- {
- boost::system::error_code ec;
- this->get_service().clear(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "clear");
- }
-
- /// Remove all signals from a signal_set.
- /**
- * This function removes all signals from the set. It has no effect if the set
- * is already empty.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @note Removes all queued notifications.
- */
- BOOST_ASIO_SYNC_OP_VOID clear(boost::system::error_code& ec)
- {
- this->get_service().clear(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Cancel all operations associated with the signal set.
- /**
- * This function forces the completion of any pending asynchronous wait
- * operations against the signal set. The handler for each cancelled
- * operation will be invoked with the boost::asio::error::operation_aborted
- * error code.
- *
- * Cancellation does not alter the set of registered signals.
- *
- * @throws boost::system::system_error Thrown on failure.
- *
- * @note If a registered signal occurred before cancel() is called, then the
- * handlers for asynchronous wait operations will:
- *
- * @li have already been invoked; or
- *
- * @li have been queued for invocation in the near future.
- *
- * These handlers can no longer be cancelled, and therefore are passed an
- * error code that indicates the successful completion of the wait operation.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all operations associated with the signal set.
- /**
- * This function forces the completion of any pending asynchronous wait
- * operations against the signal set. The handler for each cancelled
- * operation will be invoked with the boost::asio::error::operation_aborted
- * error code.
- *
- * Cancellation does not alter the set of registered signals.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @note If a registered signal occurred before cancel() is called, then the
- * handlers for asynchronous wait operations will:
- *
- * @li have already been invoked; or
- *
- * @li have been queued for invocation in the near future.
- *
- * These handlers can no longer be cancelled, and therefore are passed an
- * error code that indicates the successful completion of the wait operation.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Start an asynchronous operation to wait for a signal to be delivered.
- /**
- * This function may be used to initiate an asynchronous wait against the
- * signal set. It always returns immediately.
- *
- * For each call to async_wait(), the supplied handler will be called exactly
- * once. The handler will be called when:
- *
- * @li One of the registered signals in the signal set occurs; or
- *
- * @li The signal set was cancelled, in which case the handler is passed the
- * error code boost::asio::error::operation_aborted.
- *
- * @param handler The handler to be called when the signal occurs. Copies
- * will be made of the handler as required. The function signature of the
- * handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * int signal_number // Indicates which signal occurred.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- */
- template <typename SignalHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
- void (boost::system::error_code, int))
- async_wait(BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a SignalHandler.
- BOOST_ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check;
-
- async_completion<SignalHandler,
- void (boost::system::error_code, int)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace asio
} // namespace boost
diff --git a/boost/asio/signal_set_service.hpp b/boost/asio/signal_set_service.hpp
deleted file mode 100644
index 743611620d..0000000000
--- a/boost/asio/signal_set_service.hpp
+++ /dev/null
@@ -1,144 +0,0 @@
-//
-// signal_set_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_SIGNAL_SET_SERVICE_HPP
-#define BOOST_ASIO_SIGNAL_SET_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_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/signal_set_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a signal set.
-class signal_set_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<signal_set_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-public:
- /// The type of a signal set implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef detail::signal_set_service::implementation_type implementation_type;
-#endif
-
- /// Construct a new signal set service for the specified io_context.
- explicit signal_set_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<signal_set_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new signal set implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
- /// Destroy a signal set implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Add a signal to a signal_set.
- BOOST_ASIO_SYNC_OP_VOID add(implementation_type& impl,
- int signal_number, boost::system::error_code& ec)
- {
- service_impl_.add(impl, signal_number, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Remove a signal to a signal_set.
- BOOST_ASIO_SYNC_OP_VOID remove(implementation_type& impl,
- int signal_number, boost::system::error_code& ec)
- {
- service_impl_.remove(impl, signal_number, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Remove all signals from a signal_set.
- BOOST_ASIO_SYNC_OP_VOID clear(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.clear(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Cancel all operations associated with the signal set.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- // Start an asynchronous operation to wait for a signal to be delivered.
- template <typename SignalHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(SignalHandler,
- void (boost::system::error_code, int))
- async_wait(implementation_type& impl,
- BOOST_ASIO_MOVE_ARG(SignalHandler) handler)
- {
- async_completion<SignalHandler,
- void (boost::system::error_code, int)> init(handler);
-
- service_impl_.async_wait(impl, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // Perform any fork-related housekeeping.
- void notify_fork(boost::asio::io_context::fork_event event)
- {
- service_impl_.notify_fork(event);
- }
-
- // The platform-specific implementation.
- detail::signal_set_service service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_SIGNAL_SET_SERVICE_HPP
diff --git a/boost/asio/socket_acceptor_service.hpp b/boost/asio/socket_acceptor_service.hpp
deleted file mode 100644
index ed5c084401..0000000000
--- a/boost/asio/socket_acceptor_service.hpp
+++ /dev/null
@@ -1,374 +0,0 @@
-//
-// socket_acceptor_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_SOCKET_ACCEPTOR_SERVICE_HPP
-#define BOOST_ASIO_SOCKET_ACCEPTOR_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_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/basic_socket.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/null_socket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a socket acceptor.
-template <typename Protocol>
-class socket_acceptor_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<socket_acceptor_service<Protocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef Protocol protocol_type;
-
- /// The endpoint type.
- typedef typename protocol_type::endpoint endpoint_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef detail::null_socket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service<Protocol> service_impl_type;
-#endif
-
-public:
- /// The native type of the socket acceptor.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native acceptor type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new socket acceptor service for the specified io_context.
- explicit socket_acceptor_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- socket_acceptor_service<Protocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new socket acceptor implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new socket acceptor implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another socket acceptor implementation.
- void move_assign(implementation_type& impl,
- socket_acceptor_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-
- // All acceptor services have access to each other's implementations.
- template <typename Protocol1> friend class socket_acceptor_service;
-
- /// Move-construct a new socket acceptor implementation from another protocol
- /// type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- socket_acceptor_service<Protocol1>& other_service,
- typename socket_acceptor_service<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a socket acceptor implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Open a new socket acceptor implementation.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const protocol_type& protocol, boost::system::error_code& ec)
- {
- service_impl_.open(impl, protocol, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native acceptor to a socket acceptor.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const protocol_type& protocol, const native_handle_type& native_acceptor,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, protocol, native_acceptor, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the acceptor is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Cancel all asynchronous operations associated with the acceptor.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Bind the socket acceptor to the specified local endpoint.
- BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- service_impl_.bind(impl, endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Place the socket acceptor into the state where it will listen for new
- /// connections.
- BOOST_ASIO_SYNC_OP_VOID listen(implementation_type& impl, int backlog,
- boost::system::error_code& ec)
- {
- service_impl_.listen(impl, backlog, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Close a socket acceptor implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Release ownership of the underlying acceptor.
- native_handle_type release(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.release(impl, ec);
- }
-
- /// Get the native acceptor implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSocketOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a socket option.
- template <typename GettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSocketOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the socket.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the acceptor.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the acceptor.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native acceptor implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native acceptor implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the local endpoint.
- endpoint_type local_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.local_endpoint(impl, ec);
- }
-
- /// Wait for the acceptor to become ready to read, ready to write, or to have
- /// pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- socket_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the acceptor to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, socket_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Accept a new connection.
- template <typename Protocol1, typename SocketService>
- BOOST_ASIO_SYNC_OP_VOID accept(implementation_type& impl,
- basic_socket<Protocol1, SocketService>& peer,
- endpoint_type* peer_endpoint, boost::system::error_code& ec,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
- {
- service_impl_.accept(impl, peer, peer_endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE)
- /// Accept a new connection.
- typename Protocol::socket accept(implementation_type& impl,
- io_context* peer_io_context, endpoint_type* peer_endpoint,
- boost::system::error_code& ec)
- {
- return service_impl_.accept(impl, peer_io_context, peer_endpoint, ec);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
- /// Start an asynchronous accept.
- template <typename Protocol1, typename SocketService, typename AcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler,
- void (boost::system::error_code))
- async_accept(implementation_type& impl,
- basic_socket<Protocol1, SocketService>& peer,
- endpoint_type* peer_endpoint,
- BOOST_ASIO_MOVE_ARG(AcceptHandler) handler,
- typename enable_if<is_convertible<Protocol, Protocol1>::value>::type* = 0)
- {
- async_completion<AcceptHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_accept(impl,
- peer, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE)
- /// Start an asynchronous accept.
- template <typename MoveAcceptHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler,
- void (boost::system::error_code, typename Protocol::socket))
- async_accept(implementation_type& impl,
- boost::asio::io_context* peer_io_context, endpoint_type* peer_endpoint,
- BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler)
- {
- async_completion<MoveAcceptHandler,
- void (boost::system::error_code,
- typename Protocol::socket)> init(handler);
-
- service_impl_.async_accept(impl,
- peer_io_context, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_HPP
diff --git a/boost/asio/socket_base.hpp b/boost/asio/socket_base.hpp
index ee8aa6b262..c19f8d2742 100644
--- a/boost/asio/socket_base.hpp
+++ b/boost/asio/socket_base.hpp
@@ -2,7 +2,7 @@
// socket_base.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -99,7 +99,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::socket_base::broadcast option(true);
* socket.set_option(option);
@@ -108,7 +108,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::socket_base::broadcast option;
* socket.get_option(option);
@@ -133,7 +133,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::debug option(true);
* socket.set_option(option);
@@ -142,7 +142,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::debug option;
* socket.get_option(option);
@@ -166,7 +166,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::socket_base::do_not_route option(true);
* socket.set_option(option);
@@ -175,7 +175,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::udp::socket socket(io_context);
+ * boost::asio::ip::udp::socket socket(my_context);
* ...
* boost::asio::socket_base::do_not_route option;
* socket.get_option(option);
@@ -200,7 +200,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::keep_alive option(true);
* socket.set_option(option);
@@ -209,7 +209,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::keep_alive option;
* socket.get_option(option);
@@ -233,7 +233,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::send_buffer_size option(8192);
* socket.set_option(option);
@@ -242,7 +242,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::send_buffer_size option;
* socket.get_option(option);
@@ -267,7 +267,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::send_low_watermark option(1024);
* socket.set_option(option);
@@ -276,7 +276,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::send_low_watermark option;
* socket.get_option(option);
@@ -301,7 +301,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::receive_buffer_size option(8192);
* socket.set_option(option);
@@ -310,7 +310,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::receive_buffer_size option;
* socket.get_option(option);
@@ -335,7 +335,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::receive_low_watermark option(1024);
* socket.set_option(option);
@@ -344,7 +344,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::receive_low_watermark option;
* socket.get_option(option);
@@ -370,7 +370,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::socket_base::reuse_address option(true);
* acceptor.set_option(option);
@@ -379,7 +379,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::socket_base::reuse_address option;
* acceptor.get_option(option);
@@ -405,7 +405,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::linger option(true, 30);
* socket.set_option(option);
@@ -414,7 +414,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::linger option;
* socket.get_option(option);
@@ -440,7 +440,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::out_of_band_inline option(true);
* socket.set_option(option);
@@ -449,7 +449,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::out_of_band_inline option;
* socket.get_option(option);
@@ -476,7 +476,7 @@ public:
* @par Examples
* Setting the option:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::socket_base::enable_connection_aborted option(true);
* acceptor.set_option(option);
@@ -485,7 +485,7 @@ public:
* @par
* Getting the current option value:
* @code
- * boost::asio::ip::tcp::acceptor acceptor(io_context);
+ * boost::asio::ip::tcp::acceptor acceptor(my_context);
* ...
* boost::asio::socket_base::enable_connection_aborted option;
* acceptor.get_option(option);
@@ -511,7 +511,7 @@ public:
*
* @par Example
* @code
- * boost::asio::ip::tcp::socket socket(io_context);
+ * boost::asio::ip::tcp::socket socket(my_context);
* ...
* boost::asio::socket_base::bytes_readable command(true);
* socket.io_control(command);
diff --git a/boost/asio/spawn.hpp b/boost/asio/spawn.hpp
index b39cb90143..26fda32ff4 100644
--- a/boost/asio/spawn.hpp
+++ b/boost/asio/spawn.hpp
@@ -2,7 +2,7 @@
// spawn.hpp
// ~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl.hpp b/boost/asio/ssl.hpp
index 35138880ae..924f179503 100644
--- a/boost/asio/ssl.hpp
+++ b/boost/asio/ssl.hpp
@@ -2,7 +2,7 @@
// ssl.hpp
// ~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/context.hpp b/boost/asio/ssl/context.hpp
index 3d0cbfbfbc..60b92a8438 100644
--- a/boost/asio/ssl/context.hpp
+++ b/boost/asio/ssl/context.hpp
@@ -2,7 +2,7 @@
// ssl/context.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/context_base.hpp b/boost/asio/ssl/context_base.hpp
index 625ccc7b5b..98fdedc2e5 100644
--- a/boost/asio/ssl/context_base.hpp
+++ b/boost/asio/ssl/context_base.hpp
@@ -2,7 +2,7 @@
// ssl/context_base.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/buffered_handshake_op.hpp b/boost/asio/ssl/detail/buffered_handshake_op.hpp
index a8963ec590..812e4d7016 100644
--- a/boost/asio/ssl/detail/buffered_handshake_op.hpp
+++ b/boost/asio/ssl/detail/buffered_handshake_op.hpp
@@ -2,7 +2,7 @@
// ssl/detail/buffered_handshake_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/engine.hpp b/boost/asio/ssl/detail/engine.hpp
index 01717e789e..37e4d33016 100644
--- a/boost/asio/ssl/detail/engine.hpp
+++ b/boost/asio/ssl/detail/engine.hpp
@@ -2,7 +2,7 @@
// ssl/detail/engine.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/handshake_op.hpp b/boost/asio/ssl/detail/handshake_op.hpp
index edb112eee2..846e33f253 100644
--- a/boost/asio/ssl/detail/handshake_op.hpp
+++ b/boost/asio/ssl/detail/handshake_op.hpp
@@ -2,7 +2,7 @@
// ssl/detail/handshake_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/impl/engine.ipp b/boost/asio/ssl/detail/impl/engine.ipp
index 9142a5df3a..cac7dfda56 100644
--- a/boost/asio/ssl/detail/impl/engine.ipp
+++ b/boost/asio/ssl/detail/impl/engine.ipp
@@ -2,7 +2,7 @@
// ssl/detail/impl/engine.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -241,14 +241,23 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
{
ec = boost::system::error_code(sys_error,
boost::asio::error::get_ssl_category());
- return want_nothing;
+ return pending_output_after > pending_output_before
+ ? want_output : want_nothing;
}
if (ssl_error == SSL_ERROR_SYSCALL)
{
- ec = boost::system::error_code(sys_error,
- boost::asio::error::get_system_category());
- return want_nothing;
+ if (sys_error == 0)
+ {
+ ec = boost::asio::ssl::error::unspecified_system_error;
+ }
+ else
+ {
+ ec = boost::system::error_code(sys_error,
+ boost::asio::error::get_ssl_category());
+ }
+ return pending_output_after > pending_output_before
+ ? want_output : want_nothing;
}
if (result > 0 && bytes_transferred)
@@ -269,16 +278,21 @@ engine::want engine::perform(int (engine::* op)(void*, std::size_t),
ec = boost::system::error_code();
return want_input_and_retry;
}
- else if (::SSL_get_shutdown(ssl_) & SSL_RECEIVED_SHUTDOWN)
+ else if (ssl_error == SSL_ERROR_ZERO_RETURN)
{
ec = boost::asio::error::eof;
return want_nothing;
}
- else
+ else if (ssl_error == SSL_ERROR_NONE)
{
ec = boost::system::error_code();
return want_nothing;
}
+ else
+ {
+ ec = boost::asio::ssl::error::unexpected_result;
+ return want_nothing;
+ }
}
int engine::do_accept(void*, std::size_t)
diff --git a/boost/asio/ssl/detail/impl/openssl_init.ipp b/boost/asio/ssl/detail/impl/openssl_init.ipp
index 1608138e9d..5e80dd2556 100644
--- a/boost/asio/ssl/detail/impl/openssl_init.ipp
+++ b/boost/asio/ssl/detail/impl/openssl_init.ipp
@@ -3,7 +3,7 @@
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
-// Copyright (c) 2005-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005-2019 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)
diff --git a/boost/asio/ssl/detail/io.hpp b/boost/asio/ssl/detail/io.hpp
index 604148c795..f1c2e5317a 100644
--- a/boost/asio/ssl/detail/io.hpp
+++ b/boost/asio/ssl/detail/io.hpp
@@ -2,7 +2,7 @@
// ssl/detail/io.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -32,6 +32,7 @@ template <typename Stream, typename Operation>
std::size_t io(Stream& next_layer, stream_core& core,
const Operation& op, boost::system::error_code& ec)
{
+ boost::system::error_code io_ec;
std::size_t bytes_transferred = 0;
do switch (op(core.engine_, ec, bytes_transferred))
{
@@ -40,8 +41,12 @@ std::size_t io(Stream& next_layer, stream_core& core,
// If the input buffer is empty then we need to read some more data from
// the underlying transport.
if (core.input_.size() == 0)
+ {
core.input_ = boost::asio::buffer(core.input_buffer_,
- next_layer.read_some(core.input_buffer_, ec));
+ next_layer.read_some(core.input_buffer_, io_ec));
+ if (!ec)
+ ec = io_ec;
+ }
// Pass the new input data to the engine.
core.input_ = core.engine_.put_input(core.input_);
@@ -54,7 +59,9 @@ std::size_t io(Stream& next_layer, stream_core& core,
// Get output data from the engine and write it to the underlying
// transport.
boost::asio::write(next_layer,
- core.engine_.get_output(core.output_buffer_), ec);
+ core.engine_.get_output(core.output_buffer_), io_ec);
+ if (!ec)
+ ec = io_ec;
// Try the operation again.
continue;
@@ -64,7 +71,9 @@ std::size_t io(Stream& next_layer, stream_core& core,
// Get output data from the engine and write it to the underlying
// transport.
boost::asio::write(next_layer,
- core.engine_.get_output(core.output_buffer_), ec);
+ core.engine_.get_output(core.output_buffer_), io_ec);
+ if (!ec)
+ ec = io_ec;
// Operation is complete. Return result to caller.
core.engine_.map_error_code(ec);
diff --git a/boost/asio/ssl/detail/openssl_init.hpp b/boost/asio/ssl/detail/openssl_init.hpp
index 05b1ea4a33..74556a233b 100644
--- a/boost/asio/ssl/detail/openssl_init.hpp
+++ b/boost/asio/ssl/detail/openssl_init.hpp
@@ -2,7 +2,7 @@
// ssl/detail/openssl_init.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/openssl_types.hpp b/boost/asio/ssl/detail/openssl_types.hpp
index c955ac6013..494287a36e 100644
--- a/boost/asio/ssl/detail/openssl_types.hpp
+++ b/boost/asio/ssl/detail/openssl_types.hpp
@@ -2,7 +2,7 @@
// ssl/detail/openssl_types.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/password_callback.hpp b/boost/asio/ssl/detail/password_callback.hpp
index 2a442f34d2..9e57e90e39 100644
--- a/boost/asio/ssl/detail/password_callback.hpp
+++ b/boost/asio/ssl/detail/password_callback.hpp
@@ -2,7 +2,7 @@
// ssl/detail/password_callback.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/read_op.hpp b/boost/asio/ssl/detail/read_op.hpp
index 31929c9474..e0322aaa62 100644
--- a/boost/asio/ssl/detail/read_op.hpp
+++ b/boost/asio/ssl/detail/read_op.hpp
@@ -2,7 +2,7 @@
// ssl/detail/read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/shutdown_op.hpp b/boost/asio/ssl/detail/shutdown_op.hpp
index e98430621e..d55058af37 100644
--- a/boost/asio/ssl/detail/shutdown_op.hpp
+++ b/boost/asio/ssl/detail/shutdown_op.hpp
@@ -2,7 +2,7 @@
// ssl/detail/shutdown_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -42,7 +42,17 @@ public:
const boost::system::error_code& ec,
const std::size_t&) const
{
- handler(ec);
+ if (ec == boost::asio::error::eof)
+ {
+ // The engine only generates an eof when the shutdown notification has
+ // been received from the peer. This indicates that the shutdown has
+ // completed successfully, and thus need not be passed on to the handler.
+ handler(boost::system::error_code());
+ }
+ else
+ {
+ handler(ec);
+ }
}
};
diff --git a/boost/asio/ssl/detail/stream_core.hpp b/boost/asio/ssl/detail/stream_core.hpp
index fc0a6ffffc..eba283618f 100644
--- a/boost/asio/ssl/detail/stream_core.hpp
+++ b/boost/asio/ssl/detail/stream_core.hpp
@@ -2,7 +2,7 @@
// ssl/detail/stream_core.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -38,10 +38,11 @@ struct stream_core
// sufficient to hold the largest possible TLS record.
enum { max_tls_record_size = 17 * 1024 };
- stream_core(SSL_CTX* context, boost::asio::io_context& io_context)
+ template <typename Executor>
+ stream_core(SSL_CTX* context, const Executor& ex)
: engine_(context),
- pending_read_(io_context),
- pending_write_(io_context),
+ pending_read_(ex),
+ pending_write_(ex),
output_buffer_space_(max_tls_record_size),
output_buffer_(boost::asio::buffer(output_buffer_space_)),
input_buffer_space_(max_tls_record_size),
diff --git a/boost/asio/ssl/detail/verify_callback.hpp b/boost/asio/ssl/detail/verify_callback.hpp
index 1e96b2554b..b4cfdcedc0 100644
--- a/boost/asio/ssl/detail/verify_callback.hpp
+++ b/boost/asio/ssl/detail/verify_callback.hpp
@@ -2,7 +2,7 @@
// ssl/detail/verify_callback.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/detail/write_op.hpp b/boost/asio/ssl/detail/write_op.hpp
index 17ab95d67e..ec50cff54a 100644
--- a/boost/asio/ssl/detail/write_op.hpp
+++ b/boost/asio/ssl/detail/write_op.hpp
@@ -2,7 +2,7 @@
// ssl/detail/write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/error.hpp b/boost/asio/ssl/error.hpp
index 4a68d71703..e9ce78718c 100644
--- a/boost/asio/ssl/error.hpp
+++ b/boost/asio/ssl/error.hpp
@@ -2,7 +2,7 @@
// ssl/error.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -45,12 +45,24 @@ enum stream_errors
{
#if defined(GENERATING_DOCUMENTATION)
/// The underlying stream closed before the ssl stream gracefully shut down.
- stream_truncated
-#elif (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL)
- stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ)
-#else
- stream_truncated = 1
-#endif
+ stream_truncated,
+
+ /// The underlying SSL library returned a system error without providing
+ /// further information.
+ unspecified_system_error,
+
+ /// The underlying SSL library generated an unexpected result from a function
+ /// call.
+ unexpected_result
+#else // defined(GENERATING_DOCUMENTATION)
+# if (OPENSSL_VERSION_NUMBER < 0x10100000L) && !defined(OPENSSL_IS_BORINGSSL)
+ stream_truncated = ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHORT_READ),
+# else
+ stream_truncated = 1,
+# endif
+ unspecified_system_error = 2,
+ unexpected_result = 3
+#endif // defined(GENERATING_DOCUMENTATION)
};
extern BOOST_ASIO_DECL
diff --git a/boost/asio/ssl/impl/context.hpp b/boost/asio/ssl/impl/context.hpp
index 8f016830f9..f9ab3ad779 100644
--- a/boost/asio/ssl/impl/context.hpp
+++ b/boost/asio/ssl/impl/context.hpp
@@ -3,7 +3,7 @@
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
-// Copyright (c) 2005-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005-2019 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)
diff --git a/boost/asio/ssl/impl/context.ipp b/boost/asio/ssl/impl/context.ipp
index b331dea45d..0947a87564 100644
--- a/boost/asio/ssl/impl/context.ipp
+++ b/boost/asio/ssl/impl/context.ipp
@@ -3,7 +3,7 @@
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2005 Voipster / Indrek dot Juhani at voipster dot com
-// Copyright (c) 2005-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2005-2019 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)
diff --git a/boost/asio/ssl/impl/error.ipp b/boost/asio/ssl/impl/error.ipp
index a359619765..d77c051c9e 100644
--- a/boost/asio/ssl/impl/error.ipp
+++ b/boost/asio/ssl/impl/error.ipp
@@ -2,7 +2,7 @@
// ssl/impl/error.ipp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -77,6 +77,8 @@ public:
switch (value)
{
case stream_truncated: return "stream truncated";
+ case unspecified_system_error: return "unspecified system error";
+ case unexpected_result: return "unexpected result";
default: return "asio.ssl.stream error";
}
}
diff --git a/boost/asio/ssl/impl/rfc2818_verification.ipp b/boost/asio/ssl/impl/rfc2818_verification.ipp
index 63ce663bdc..3720509258 100644
--- a/boost/asio/ssl/impl/rfc2818_verification.ipp
+++ b/boost/asio/ssl/impl/rfc2818_verification.ipp
@@ -2,7 +2,7 @@
// ssl/impl/rfc2818_verification.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/impl/src.hpp b/boost/asio/ssl/impl/src.hpp
index 2e8859ea2b..4f965ed4ab 100644
--- a/boost/asio/ssl/impl/src.hpp
+++ b/boost/asio/ssl/impl/src.hpp
@@ -2,7 +2,7 @@
// impl/ssl/src.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/rfc2818_verification.hpp b/boost/asio/ssl/rfc2818_verification.hpp
index 047688b007..1e4e411658 100644
--- a/boost/asio/ssl/rfc2818_verification.hpp
+++ b/boost/asio/ssl/rfc2818_verification.hpp
@@ -2,7 +2,7 @@
// ssl/rfc2818_verification.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/stream.hpp b/boost/asio/ssl/stream.hpp
index 1acaceea45..2ae8c13a4a 100644
--- a/boost/asio/ssl/stream.hpp
+++ b/boost/asio/ssl/stream.hpp
@@ -2,7 +2,7 @@
// ssl/stream.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -20,6 +20,7 @@
#include <boost/asio/async_result.hpp>
#include <boost/asio/detail/buffer_sequence_adapter.hpp>
#include <boost/asio/detail/handler_type_requirements.hpp>
+#include <boost/asio/detail/non_const_lvalue.hpp>
#include <boost/asio/detail/noncopyable.hpp>
#include <boost/asio/detail/type_traits.hpp>
#include <boost/asio/ssl/context.hpp>
@@ -52,9 +53,9 @@ namespace ssl {
* @par Example
* To use the SSL stream template with an ip::tcp::socket, you would write:
* @code
- * boost::asio::io_context io_context;
+ * boost::asio::io_context my_context;
* boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
- * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+ * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
* @endcode
*
* @par Concepts:
@@ -97,16 +98,14 @@ public:
template <typename Arg>
stream(Arg&& arg, context& ctx)
: next_layer_(BOOST_ASIO_MOVE_CAST(Arg)(arg)),
- core_(ctx.native_handle(),
- next_layer_.lowest_layer().get_executor().context())
+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
{
}
#else // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
template <typename Arg>
stream(Arg& arg, context& ctx)
: next_layer_(arg),
- core_(ctx.native_handle(),
- next_layer_.lowest_layer().get_executor().context())
+ core_(ctx.native_handle(), next_layer_.lowest_layer().get_executor())
{
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -132,22 +131,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_context()
- {
- return next_layer_.lowest_layer().get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- boost::asio::io_context& get_io_service()
- {
- return next_layer_.lowest_layer().get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
@@ -159,7 +142,7 @@ public:
* suitable for passing to functions such as @c SSL_get_verify_result and
* @c SSL_get_peer_certificate:
* @code
- * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(io_context, ctx);
+ * boost::asio::ssl::stream<asio:ip::tcp::socket> sock(my_context, ctx);
*
* // ... establish connection and perform handshake ...
*
@@ -454,17 +437,9 @@ public:
async_handshake(handshake_type type,
BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a HandshakeHandler.
- BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
-
- boost::asio::async_completion<HandshakeHandler,
- void (boost::system::error_code)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::handshake_op(type), init.completion_handler);
-
- return init.result.get();
+ return async_initiate<HandshakeHandler,
+ void (boost::system::error_code)>(
+ initiate_async_handshake(), handler, this, type);
}
/// Start an asynchronous SSL handshake.
@@ -494,19 +469,9 @@ public:
async_handshake(handshake_type type, const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a BufferedHandshakeHandler.
- BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
- BufferedHandshakeHandler, handler) type_check;
-
- boost::asio::async_completion<BufferedHandshakeHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<BufferedHandshakeHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_buffered_handshake(), handler, this, type, buffers);
}
/// Shut down SSL on the stream.
@@ -553,17 +518,9 @@ public:
void (boost::system::error_code))
async_shutdown(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ShutdownHandler.
- BOOST_ASIO_SHUTDOWN_HANDLER_CHECK(ShutdownHandler, handler) type_check;
-
- boost::asio::async_completion<ShutdownHandler,
- void (boost::system::error_code)> init(handler);
-
- detail::async_io(next_layer_, core_, detail::shutdown_op(),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<ShutdownHandler,
+ void (boost::system::error_code)>(
+ initiate_async_shutdown(), handler, this);
}
/// Write some data to the stream.
@@ -644,18 +601,9 @@ public:
async_write_some(const ConstBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- detail::async_io(next_layer_, core_,
- detail::write_op<ConstBufferSequence>(buffers),
- init.completion_handler);
-
- return init.result.get();
+ return async_initiate<WriteHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the stream.
@@ -736,21 +684,97 @@ public:
async_read_some(const MutableBufferSequence& buffers,
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
{
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+ return async_initiate<ReadHandler,
+ void (boost::system::error_code, std::size_t)>(
+ initiate_async_read_some(), handler, this, buffers);
+ }
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
+private:
+ struct initiate_async_handshake
+ {
+ template <typename HandshakeHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
+ stream* self, handshake_type type) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a HandshakeHandler.
+ BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(HandshakeHandler, handler) type_check;
+
+ boost::asio::detail::non_const_lvalue<HandshakeHandler> handler2(handler);
+ detail::async_io(self->next_layer_, self->core_,
+ detail::handshake_op(type), handler2.value);
+ }
+ };
- detail::async_io(next_layer_, core_,
- detail::read_op<MutableBufferSequence>(buffers),
- init.completion_handler);
+ struct initiate_async_buffered_handshake
+ {
+ template <typename BufferedHandshakeHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler,
+ stream* self, handshake_type type,
+ const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your
+ // handler does not meet the documented type requirements for a
+ // BufferedHandshakeHandler.
+ BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK(
+ BufferedHandshakeHandler, handler) type_check;
+
+ boost::asio::detail::non_const_lvalue<
+ BufferedHandshakeHandler> handler2(handler);
+ detail::async_io(self->next_layer_, self->core_,
+ detail::buffered_handshake_op<ConstBufferSequence>(type, buffers),
+ handler2.value);
+ }
+ };
- return init.result.get();
- }
+ struct initiate_async_shutdown
+ {
+ template <typename ShutdownHandler>
+ void operator()(BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler,
+ stream* self) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ShutdownHandler.
+ BOOST_ASIO_HANDSHAKE_HANDLER_CHECK(ShutdownHandler, handler) type_check;
+
+ boost::asio::detail::non_const_lvalue<ShutdownHandler> handler2(handler);
+ detail::async_io(self->next_layer_, self->core_,
+ detail::shutdown_op(), handler2.value);
+ }
+ };
+
+ struct initiate_async_write_some
+ {
+ template <typename WriteHandler, typename ConstBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ stream* self, const ConstBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a WriteHandler.
+ BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
+
+ boost::asio::detail::non_const_lvalue<WriteHandler> handler2(handler);
+ detail::async_io(self->next_layer_, self->core_,
+ detail::write_op<ConstBufferSequence>(buffers), handler2.value);
+ }
+ };
+
+ struct initiate_async_read_some
+ {
+ template <typename ReadHandler, typename MutableBufferSequence>
+ void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
+ stream* self, const MutableBufferSequence& buffers) const
+ {
+ // If you get an error on the following line it means that your handler
+ // does not meet the documented type requirements for a ReadHandler.
+ BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
+
+ boost::asio::detail::non_const_lvalue<ReadHandler> handler2(handler);
+ detail::async_io(self->next_layer_, self->core_,
+ detail::read_op<MutableBufferSequence>(buffers), handler2.value);
+ }
+ };
-private:
Stream next_layer_;
detail::stream_core core_;
};
diff --git a/boost/asio/ssl/stream_base.hpp b/boost/asio/ssl/stream_base.hpp
index 5847214894..0fefde54f1 100644
--- a/boost/asio/ssl/stream_base.hpp
+++ b/boost/asio/ssl/stream_base.hpp
@@ -2,7 +2,7 @@
// ssl/stream_base.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/verify_context.hpp b/boost/asio/ssl/verify_context.hpp
index c5fdaf4adb..952ec917cd 100644
--- a/boost/asio/ssl/verify_context.hpp
+++ b/boost/asio/ssl/verify_context.hpp
@@ -2,7 +2,7 @@
// ssl/verify_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ssl/verify_mode.hpp b/boost/asio/ssl/verify_mode.hpp
index 9ae6050442..0dcf18af96 100644
--- a/boost/asio/ssl/verify_mode.hpp
+++ b/boost/asio/ssl/verify_mode.hpp
@@ -2,7 +2,7 @@
// ssl/verify_mode.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/steady_timer.hpp b/boost/asio/steady_timer.hpp
index ab30b9c8fd..5c88e975dc 100644
--- a/boost/asio/steady_timer.hpp
+++ b/boost/asio/steady_timer.hpp
@@ -2,7 +2,7 @@
// steady_timer.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/strand.hpp b/boost/asio/strand.hpp
index b82e988fe4..d08801bd90 100644
--- a/boost/asio/strand.hpp
+++ b/boost/asio/strand.hpp
@@ -2,7 +2,7 @@
// strand.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -272,6 +272,33 @@ private:
implementation_type impl_;
};
+/** @defgroup make_strand boost::asio::make_strand
+ *
+ * @brief The boost::asio::make_strand function creates a @ref strand object for
+ * an executor or execution context.
+ */
+/*@{*/
+
+/// Create a @ref strand object for an executor.
+template <typename Executor>
+inline strand<Executor> make_strand(const Executor& ex,
+ typename enable_if<is_executor<Executor>::value>::type* = 0)
+{
+ return strand<Executor>(ex);
+}
+
+/// Create a @ref strand object for an execution context.
+template <typename ExecutionContext>
+inline strand<typename ExecutionContext::executor_type>
+make_strand(ExecutionContext& ctx,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value>::type* = 0)
+{
+ return strand<typename ExecutionContext::executor_type>(ctx.get_executor());
+}
+
+/*@}*/
+
} // namespace asio
} // namespace boost
diff --git a/boost/asio/stream_socket_service.hpp b/boost/asio/stream_socket_service.hpp
deleted file mode 100644
index 04159ea66f..0000000000
--- a/boost/asio/stream_socket_service.hpp
+++ /dev/null
@@ -1,414 +0,0 @@
-//
-// stream_socket_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_STREAM_SOCKET_SERVICE_HPP
-#define BOOST_ASIO_STREAM_SOCKET_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_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/type_traits.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
-# include <boost/asio/detail/winrt_ssocket_service.hpp>
-#elif defined(BOOST_ASIO_HAS_IOCP)
-# include <boost/asio/detail/win_iocp_socket_service.hpp>
-#else
-# include <boost/asio/detail/reactive_socket_service.hpp>
-#endif
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a stream socket.
-template <typename Protocol>
-class stream_socket_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<stream_socket_service<Protocol> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The protocol type.
- typedef Protocol protocol_type;
-
- /// The endpoint type.
- typedef typename Protocol::endpoint endpoint_type;
-
-private:
- // The type of the platform-specific implementation.
-#if defined(BOOST_ASIO_WINDOWS_RUNTIME)
- typedef detail::winrt_ssocket_service<Protocol> service_impl_type;
-#elif defined(BOOST_ASIO_HAS_IOCP)
- typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
-#else
- typedef detail::reactive_socket_service<Protocol> service_impl_type;
-#endif
-
-public:
- /// The type of a stream socket implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native socket type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef typename service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new stream socket service for the specified io_context.
- explicit stream_socket_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- stream_socket_service<Protocol> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new stream socket implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new stream socket implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another stream socket implementation.
- void move_assign(implementation_type& impl,
- stream_socket_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-
- // All socket services have access to each other's implementations.
- template <typename Protocol1> friend class stream_socket_service;
-
- /// Move-construct a new stream socket implementation from another protocol
- /// type.
- template <typename Protocol1>
- void converting_move_construct(implementation_type& impl,
- stream_socket_service<Protocol1>& other_service,
- typename stream_socket_service<
- Protocol1>::implementation_type& other_impl,
- typename enable_if<is_convertible<
- Protocol1, Protocol>::value>::type* = 0)
- {
- service_impl_.template converting_move_construct<Protocol1>(
- impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a stream socket implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Open a stream socket.
- BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl,
- const protocol_type& protocol, boost::system::error_code& ec)
- {
- if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM))
- service_impl_.open(impl, protocol, ec);
- else
- ec = boost::asio::error::invalid_argument;
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Assign an existing native socket to a stream socket.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const protocol_type& protocol, const native_handle_type& native_socket,
- boost::system::error_code& ec)
- {
- service_impl_.assign(impl, protocol, native_socket, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the socket is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a stream socket implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Release ownership of the underlying socket.
- native_handle_type release(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.release(impl, ec);
- }
-
- /// Get the native socket implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the socket.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_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
- {
- return service_impl_.at_mark(impl, ec);
- }
-
- /// Determine the number of bytes available for reading.
- std::size_t available(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.available(impl, ec);
- }
-
- /// Bind the stream socket to the specified local endpoint.
- BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl,
- const endpoint_type& endpoint, boost::system::error_code& ec)
- {
- service_impl_.bind(impl, endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Connect the stream socket to the specified endpoint.
- BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl,
- const endpoint_type& peer_endpoint, boost::system::error_code& ec)
- {
- service_impl_.connect(impl, peer_endpoint, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Start an asynchronous connect.
- template <typename ConnectHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler,
- void (boost::system::error_code))
- async_connect(implementation_type& impl,
- const endpoint_type& peer_endpoint,
- BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
- {
- async_completion<ConnectHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Set a socket option.
- template <typename SettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
- const SettableSocketOption& option, boost::system::error_code& ec)
- {
- service_impl_.set_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get a socket option.
- template <typename GettableSocketOption>
- BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
- GettableSocketOption& option, boost::system::error_code& ec) const
- {
- service_impl_.get_option(impl, option, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform an IO control command on the socket.
- template <typename IoControlCommand>
- BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
- IoControlCommand& command, boost::system::error_code& ec)
- {
- service_impl_.io_control(impl, command, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the socket.
- bool non_blocking(const implementation_type& impl) const
- {
- return service_impl_.non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the socket.
- BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Gets the non-blocking mode of the native socket implementation.
- bool native_non_blocking(const implementation_type& impl) const
- {
- return service_impl_.native_non_blocking(impl);
- }
-
- /// Sets the non-blocking mode of the native socket implementation.
- BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
- bool mode, boost::system::error_code& ec)
- {
- service_impl_.native_non_blocking(impl, mode, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the local endpoint.
- endpoint_type local_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.local_endpoint(impl, ec);
- }
-
- /// Get the remote endpoint.
- endpoint_type remote_endpoint(const implementation_type& impl,
- boost::system::error_code& ec) const
- {
- return service_impl_.remote_endpoint(impl, ec);
- }
-
- /// Disable sends or receives on the socket.
- BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
- socket_base::shutdown_type what, boost::system::error_code& ec)
- {
- service_impl_.shutdown(impl, what, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Wait for the socket to become ready to read, ready to write, or to have
- /// pending error conditions.
- BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl,
- socket_base::wait_type w, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, w, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Asynchronously wait for the socket to become ready to read, ready to
- /// write, or to have pending error conditions.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl, socket_base::wait_type w,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, w, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Send the given data to the peer.
- template <typename ConstBufferSequence>
- std::size_t send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.send(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous send.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_send(implementation_type& impl,
- const ConstBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_send(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Receive some data from the peer.
- template <typename MutableBufferSequence>
- std::size_t receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags, boost::system::error_code& ec)
- {
- return service_impl_.receive(impl, buffers, flags, ec);
- }
-
- /// Start an asynchronous receive.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_receive(implementation_type& impl,
- const MutableBufferSequence& buffers,
- socket_base::message_flags flags,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_HPP
diff --git a/boost/asio/streambuf.hpp b/boost/asio/streambuf.hpp
index 737a631151..a66600d0f7 100644
--- a/boost/asio/streambuf.hpp
+++ b/boost/asio/streambuf.hpp
@@ -2,7 +2,7 @@
// streambuf.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/system_context.hpp b/boost/asio/system_context.hpp
index 22f6b19426..96d29f4249 100644
--- a/boost/asio/system_context.hpp
+++ b/boost/asio/system_context.hpp
@@ -2,7 +2,7 @@
// system_context.hpp
// ~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -60,6 +60,9 @@ private:
struct thread_function;
+ // Helper function to create the underlying scheduler.
+ BOOST_ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);
+
// The underlying scheduler.
detail::scheduler& scheduler_;
diff --git a/boost/asio/system_executor.hpp b/boost/asio/system_executor.hpp
index d6f5b7def8..5125046e8a 100644
--- a/boost/asio/system_executor.hpp
+++ b/boost/asio/system_executor.hpp
@@ -2,7 +2,7 @@
// system_executor.hpp
// ~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/system_timer.hpp b/boost/asio/system_timer.hpp
index c2ff9947b9..880feac0d8 100644
--- a/boost/asio/system_timer.hpp
+++ b/boost/asio/system_timer.hpp
@@ -2,7 +2,7 @@
// system_timer.hpp
// ~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/this_coro.hpp b/boost/asio/this_coro.hpp
new file mode 100644
index 0000000000..19c50b20e8
--- /dev/null
+++ b/boost/asio/this_coro.hpp
@@ -0,0 +1,47 @@
+//
+// this_coro.hpp
+// ~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_THIS_CORO_HPP
+#define BOOST_ASIO_THIS_CORO_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/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace this_coro {
+
+/// Awaitable type that returns the executor of the current coroutine.
+struct executor_t
+{
+ BOOST_ASIO_CONSTEXPR executor_t()
+ {
+ }
+};
+
+/// Awaitable object that returns the executor of the current coroutine.
+#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
+constexpr executor_t executor;
+#elif defined(BOOST_ASIO_MSVC)
+__declspec(selectany) executor_t executor;
+#endif
+
+} // namespace this_coro
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_THIS_CORO_HPP
diff --git a/boost/asio/thread_pool.hpp b/boost/asio/thread_pool.hpp
index ac5f00d091..765fa2aa21 100644
--- a/boost/asio/thread_pool.hpp
+++ b/boost/asio/thread_pool.hpp
@@ -2,7 +2,7 @@
// thread_pool.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -101,6 +101,9 @@ private:
friend class executor_type;
struct thread_function;
+ // Helper function to create the underlying scheduler.
+ BOOST_ASIO_DECL detail::scheduler& add_scheduler(detail::scheduler* s);
+
// The underlying scheduler.
detail::scheduler& scheduler_;
diff --git a/boost/asio/time_traits.hpp b/boost/asio/time_traits.hpp
index d11ea0050f..b161f468b5 100644
--- a/boost/asio/time_traits.hpp
+++ b/boost/asio/time_traits.hpp
@@ -2,7 +2,7 @@
// time_traits.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/buffer.hpp b/boost/asio/ts/buffer.hpp
index 2774935f1b..6357c34359 100644
--- a/boost/asio/ts/buffer.hpp
+++ b/boost/asio/ts/buffer.hpp
@@ -2,7 +2,7 @@
// ts/buffer.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/executor.hpp b/boost/asio/ts/executor.hpp
index df52817a35..e7b01af6ef 100644
--- a/boost/asio/ts/executor.hpp
+++ b/boost/asio/ts/executor.hpp
@@ -2,7 +2,7 @@
// ts/executor.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -15,7 +15,6 @@
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
-#include <boost/asio/handler_type.hpp>
#include <boost/asio/async_result.hpp>
#include <boost/asio/associated_allocator.hpp>
#include <boost/asio/execution_context.hpp>
diff --git a/boost/asio/ts/internet.hpp b/boost/asio/ts/internet.hpp
index 7448015734..1e1abce6b6 100644
--- a/boost/asio/ts/internet.hpp
+++ b/boost/asio/ts/internet.hpp
@@ -2,7 +2,7 @@
// ts/internet.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/io_context.hpp b/boost/asio/ts/io_context.hpp
index aea646cc4a..9ffb06258d 100644
--- a/boost/asio/ts/io_context.hpp
+++ b/boost/asio/ts/io_context.hpp
@@ -2,7 +2,7 @@
// ts/io_context.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/net.hpp b/boost/asio/ts/net.hpp
index dbac252849..dcafe69651 100644
--- a/boost/asio/ts/net.hpp
+++ b/boost/asio/ts/net.hpp
@@ -2,7 +2,7 @@
// ts/net.hpp
// ~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/netfwd.hpp b/boost/asio/ts/netfwd.hpp
index 10800baea4..d165e5bfeb 100644
--- a/boost/asio/ts/netfwd.hpp
+++ b/boost/asio/ts/netfwd.hpp
@@ -2,7 +2,7 @@
// ts/netfwd.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -59,26 +59,12 @@ struct time_traits;
#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-template <typename Clock, typename WaitTraits>
-class waitable_timer_service;
-
-#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
-
-template <typename TimeType, typename TimeTraits>
-class deadline_timer_service;
-
-#endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
#define BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL
template <typename Clock,
- typename WaitTraits = boost::asio::wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = wait_traits<Clock>,
+ typename Executor = executor>
class basic_waitable_timer;
#endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@@ -94,33 +80,51 @@ typedef basic_waitable_timer<chrono::high_resolution_clock>
#endif // defined(BOOST_ASIO_HAS_CHRONO)
-template <class Protocol BOOST_ASIO_SVC_TPARAM>
+#if !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_FWD_DECL
+
+template <typename Protocol, typename Executor = executor>
class basic_socket;
-template <typename Protocol BOOST_ASIO_SVC_TPARAM>
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_FWD_DECL)
+
+#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
+
+template <typename Protocol, typename Executor = executor>
class basic_datagram_socket;
-template <typename Protocol BOOST_ASIO_SVC_TPARAM>
+#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
+
+#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
+#define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
+
+// Forward declaration with defaulted arguments.
+template <typename Protocol, typename Executor = executor>
class basic_stream_socket;
-template <typename Protocol BOOST_ASIO_SVC_TPARAM>
+#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
+
+#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
+#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL
+
+template <typename Protocol, typename Executor = executor>
class basic_socket_acceptor;
+#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL)
+
#if !defined(BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
#define BOOST_ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments.
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
typename Clock = boost::posix_time::ptime,
- typename WaitTraits = time_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = time_traits<Clock> >
#else
typename Clock = chrono::steady_clock,
- typename WaitTraits = wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+ typename WaitTraits = wait_traits<Clock> >
#endif
class basic_socket_streambuf;
@@ -130,17 +134,14 @@ class basic_socket_streambuf;
#define BOOST_ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments.
-template <typename Protocol
- BOOST_ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
+template <typename Protocol,
#if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
typename Clock = boost::posix_time::ptime,
- typename WaitTraits = time_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
+ typename WaitTraits = time_traits<Clock> >
#else
typename Clock = chrono::steady_clock,
- typename WaitTraits = wait_traits<Clock>
- BOOST_ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
+ typename WaitTraits = wait_traits<Clock> >
#endif
class basic_socket_iostream;
@@ -181,9 +182,14 @@ class basic_resolver_entry;
template <typename InternetProtocol>
class basic_resolver_results;
-template <typename InternetProtocol BOOST_ASIO_SVC_TPARAM>
+#if !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+#define BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL
+
+template <typename InternetProtocol, typename Executor = executor>
class basic_resolver;
+#endif // !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
+
class tcp;
class udp;
diff --git a/boost/asio/ts/socket.hpp b/boost/asio/ts/socket.hpp
index 01e6855332..be7e82351c 100644
--- a/boost/asio/ts/socket.hpp
+++ b/boost/asio/ts/socket.hpp
@@ -2,7 +2,7 @@
// ts/socket.hpp
// ~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/ts/timer.hpp b/boost/asio/ts/timer.hpp
index adc6bf99c4..fec6245e38 100644
--- a/boost/asio/ts/timer.hpp
+++ b/boost/asio/ts/timer.hpp
@@ -2,7 +2,7 @@
// ts/timer.hpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/unyield.hpp b/boost/asio/unyield.hpp
index de3ed0275e..c6874d5cf3 100644
--- a/boost/asio/unyield.hpp
+++ b/boost/asio/unyield.hpp
@@ -2,7 +2,7 @@
// unyield.hpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/use_awaitable.hpp b/boost/asio/use_awaitable.hpp
new file mode 100644
index 0000000000..8764b3d2d2
--- /dev/null
+++ b/boost/asio/use_awaitable.hpp
@@ -0,0 +1,73 @@
+//
+// use_awaitable.hpp
+// ~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_USE_AWAITABLE_HPP
+#define BOOST_ASIO_USE_AWAITABLE_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_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#include <boost/asio/awaitable.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+
+/// A completion token that represents the currently executing coroutine.
+/**
+ * The @c use_awaitable_t class, with its value @c use_awaitable, is used to
+ * represent the currently executing coroutine. This completion token may be
+ * passed as a handler to an asynchronous operation. For example:
+ *
+ * @code awaitable<void> my_coroutine()
+ * {
+ * std::size_t n = co_await my_socket.async_read_some(buffer, use_awaitable);
+ * ...
+ * } @endcode
+ *
+ * When used with co_await, the initiating function (@c async_read_some in the
+ * above example) suspends the current coroutine. The coroutine is resumed when
+ * the asynchronous operation completes, and the result of the operation is
+ * returned.
+ */
+template <typename Executor = executor>
+struct use_awaitable_t
+{
+ BOOST_ASIO_CONSTEXPR use_awaitable_t()
+ {
+ }
+};
+
+/// A completion token object that represents the currently executing coroutine.
+/**
+ * See the documentation for boost::asio::use_awaitable_t for a usage example.
+ */
+#if defined(BOOST_ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
+constexpr use_awaitable_t<> use_awaitable;
+#elif defined(BOOST_ASIO_MSVC)
+__declspec(selectany) use_awaitable_t<> use_awaitable;
+#endif
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/impl/use_awaitable.hpp>
+
+#endif // defined(BOOST_ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
+
+#endif // BOOST_ASIO_USE_AWAITABLE_HPP
diff --git a/boost/asio/use_future.hpp b/boost/asio/use_future.hpp
index 01fb2760f3..45497efa08 100644
--- a/boost/asio/use_future.hpp
+++ b/boost/asio/use_future.hpp
@@ -2,7 +2,7 @@
// use_future.hpp
// ~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/uses_executor.hpp b/boost/asio/uses_executor.hpp
index 6398816fab..fb55b6751e 100644
--- a/boost/asio/uses_executor.hpp
+++ b/boost/asio/uses_executor.hpp
@@ -2,7 +2,7 @@
// uses_executor.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/version.hpp b/boost/asio/version.hpp
index bedf15bd0c..30d7b2348e 100644
--- a/boost/asio/version.hpp
+++ b/boost/asio/version.hpp
@@ -2,7 +2,7 @@
// version.hpp
// ~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -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 101202 // 1.12.2
+#define BOOST_ASIO_VERSION 101400 // 1.14.0
#endif // BOOST_ASIO_VERSION_HPP
diff --git a/boost/asio/wait_traits.hpp b/boost/asio/wait_traits.hpp
index 9f5be813a7..66719f23a9 100644
--- a/boost/asio/wait_traits.hpp
+++ b/boost/asio/wait_traits.hpp
@@ -2,7 +2,7 @@
// wait_traits.hpp
// ~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
diff --git a/boost/asio/waitable_timer_service.hpp b/boost/asio/waitable_timer_service.hpp
deleted file mode 100644
index 164aae90c6..0000000000
--- a/boost/asio/waitable_timer_service.hpp
+++ /dev/null
@@ -1,212 +0,0 @@
-//
-// waitable_timer_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_WAITABLE_TIMER_SERVICE_HPP
-#define BOOST_ASIO_WAITABLE_TIMER_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_ENABLE_OLD_SERVICES)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/chrono_time_traits.hpp>
-#include <boost/asio/detail/deadline_timer_service.hpp>
-#include <boost/asio/io_context.hpp>
-#include <boost/asio/wait_traits.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-
-/// Default service implementation for a timer.
-template <typename Clock,
- typename WaitTraits = boost::asio::wait_traits<Clock> >
-class waitable_timer_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<
- waitable_timer_service<Clock, WaitTraits> >
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
- /// The clock type.
- typedef Clock clock_type;
-
- /// The duration type of the clock.
- typedef typename clock_type::duration duration;
-
- /// The time point type of the clock.
- typedef typename clock_type::time_point time_point;
-
- /// The wait traits type.
- typedef WaitTraits traits_type;
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::deadline_timer_service<
- detail::chrono_time_traits<Clock, WaitTraits> > service_impl_type;
-
-public:
- /// The implementation type of the waitable timer.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef typename service_impl_type::implementation_type implementation_type;
-#endif
-
- /// Construct a new timer service for the specified io_context.
- explicit waitable_timer_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- waitable_timer_service<Clock, WaitTraits> >(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new timer implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
- /// Destroy a timer implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new timer implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another timer implementation.
- void move_assign(implementation_type& impl,
- waitable_timer_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Cancel any asynchronous wait operations associated with the timer.
- std::size_t cancel(implementation_type& impl, boost::system::error_code& ec)
- {
- return service_impl_.cancel(impl, ec);
- }
-
- /// Cancels one asynchronous wait operation associated with the timer.
- std::size_t cancel_one(implementation_type& impl,
- boost::system::error_code& ec)
- {
- return service_impl_.cancel_one(impl, ec);
- }
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use expiry().) Get the expiry time for the timer as an
- /// absolute time.
- time_point expires_at(const implementation_type& impl) const
- {
- return service_impl_.expiry(impl);
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the expiry time for the timer as an absolute time.
- time_point expiry(const implementation_type& impl) const
- {
- return service_impl_.expiry(impl);
- }
-
- /// Set the expiry time for the timer as an absolute time.
- std::size_t expires_at(implementation_type& impl,
- const time_point& expiry_time, boost::system::error_code& ec)
- {
- return service_impl_.expires_at(impl, expiry_time, ec);
- }
-
- /// Set the expiry time for the timer relative to now.
- std::size_t expires_after(implementation_type& impl,
- const duration& expiry_time, boost::system::error_code& ec)
- {
- return service_impl_.expires_after(impl, expiry_time, ec);
- }
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use expiry().) Get the expiry time for the timer relative to
- /// now.
- duration expires_from_now(const implementation_type& impl) const
- {
- typedef detail::chrono_time_traits<Clock, WaitTraits> traits;
- return traits::subtract(service_impl_.expiry(impl), traits::now());
- }
-
- /// (Deprecated: Use expires_after().) Set the expiry time for the timer
- /// relative to now.
- std::size_t expires_from_now(implementation_type& impl,
- const duration& expiry_time, boost::system::error_code& ec)
- {
- return service_impl_.expires_after(impl, expiry_time, ec);
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- // Perform a blocking wait on the timer.
- void wait(implementation_type& impl, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, ec);
- }
-
- // Start an asynchronous wait on the timer.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_WAITABLE_TIMER_SERVICE_HPP
diff --git a/boost/asio/windows/basic_handle.hpp b/boost/asio/windows/basic_handle.hpp
deleted file mode 100644
index ce7d0e8fa0..0000000000
--- a/boost/asio/windows/basic_handle.hpp
+++ /dev/null
@@ -1,275 +0,0 @@
-//
-// windows/basic_handle.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_WINDOWS_BASIC_HANDLE_HPP
-#define BOOST_ASIO_WINDOWS_BASIC_HANDLE_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
- || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
- || defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
- || 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/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace windows {
-
-/// Provides Windows handle functionality.
-/**
- * The windows::basic_handle class template provides the ability to wrap a
- * Windows handle.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-template <typename HandleService>
-class basic_handle
- : public basic_io_object<HandleService>
-{
-public:
- /// The native representation of a handle.
- typedef typename HandleService::native_handle_type native_handle_type;
-
- /// A basic_handle is always the lowest layer.
- typedef basic_handle<HandleService> lowest_layer_type;
-
- /// Construct a basic_handle without opening it.
- /**
- * This constructor creates a handle without opening it.
- *
- * @param io_context The io_context object that the handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- */
- explicit basic_handle(boost::asio::io_context& io_context)
- : basic_io_object<HandleService>(io_context)
- {
- }
-
- /// Construct a basic_handle on an existing native handle.
- /**
- * This constructor creates a handle object to hold an existing native handle.
- *
- * @param io_context The io_context object that the handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- *
- * @param handle A native handle.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- basic_handle(boost::asio::io_context& io_context,
- const native_handle_type& handle)
- : basic_io_object<HandleService>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_handle from another.
- /**
- * This constructor moves a handle from one object to another.
- *
- * @param other The other basic_handle object from which the move will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_handle(io_context&) constructor.
- */
- basic_handle(basic_handle&& other)
- : basic_io_object<HandleService>(
- BOOST_ASIO_MOVE_CAST(basic_handle)(other))
- {
- }
-
- /// Move-assign a basic_handle from another.
- /**
- * This assignment operator moves a handle from one object to another.
- *
- * @param other The other basic_handle object from which the move will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_handle(io_context&) constructor.
- */
- basic_handle& operator=(basic_handle&& other)
- {
- basic_io_object<HandleService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_handle)(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Get a reference to the lowest layer.
- /**
- * This function returns a reference to the lowest layer in a stack of
- * layers. Since a basic_handle cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A reference to the lowest layer in the stack of layers. Ownership
- * is not transferred to the caller.
- */
- lowest_layer_type& lowest_layer()
- {
- return *this;
- }
-
- /// Get a const reference to the lowest layer.
- /**
- * This function returns a const reference to the lowest layer in a stack of
- * layers. Since a basic_handle cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A const reference to the lowest layer in the stack of layers.
- * Ownership is not transferred to the caller.
- */
- const lowest_layer_type& lowest_layer() const
- {
- return *this;
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void assign(const native_handle_type& handle)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
- boost::system::error_code& ec)
- {
- this->get_service().assign(this->get_implementation(), handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open() const
- {
- return this->get_service().is_open(this->get_implementation());
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void close()
- {
- boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "close");
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
- {
- this->get_service().close(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle representation.
- /**
- * This function may be used to obtain the underlying representation of the
- * handle. This is intended to allow access to native handle functionality
- * that is not otherwise provided.
- */
- native_handle_type native_handle()
- {
- return this->get_service().native_handle(this->get_implementation());
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
-protected:
- /// Protected destructor to prevent deletion through this type.
- ~basic_handle()
- {
- }
-};
-
-} // namespace windows
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
- // || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
- // || defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_WINDOWS_BASIC_HANDLE_HPP
diff --git a/boost/asio/windows/basic_object_handle.hpp b/boost/asio/windows/basic_object_handle.hpp
index b4a2565e23..9519bc735e 100644
--- a/boost/asio/windows/basic_object_handle.hpp
+++ b/boost/asio/windows/basic_object_handle.hpp
@@ -2,7 +2,7 @@
// windows/basic_object_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -18,15 +18,20 @@
#include <boost/asio/detail/config.hpp>
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_object_handle_service.hpp>
#include <boost/asio/error.hpp>
-#include <boost/asio/windows/basic_handle.hpp>
-#include <boost/asio/windows/object_handle_service.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
#include <boost/asio/detail/push_options.hpp>
@@ -36,86 +41,284 @@ namespace windows {
/// Provides object-oriented handle functionality.
/**
- * The windows::basic_object_handle class template provides asynchronous and
- * blocking object-oriented handle functionality.
+ * The windows::basic_object_handle class provides asynchronous and blocking
+ * object-oriented handle functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename ObjectHandleService = object_handle_service>
+template <typename Executor = executor>
class basic_object_handle
- : public basic_handle<ObjectHandleService>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a handle.
- typedef typename ObjectHandleService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef boost::asio::detail::win_object_handle_service::native_handle_type
+ native_handle_type;
+#endif
+
+ /// An object handle is always the lowest layer.
+ typedef basic_object_handle lowest_layer_type;
- /// Construct a basic_object_handle without opening it.
+ /// Construct an object handle without opening it.
/**
* This constructor creates an object handle without opening it.
*
- * @param io_context The io_context object that the object handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
+ * @param ex The I/O executor that the object handle will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * object handle.
*/
- explicit basic_object_handle(boost::asio::io_context& io_context)
- : basic_handle<ObjectHandleService>(io_context)
+ explicit basic_object_handle(const executor_type& ex)
+ : impl_(ex)
{
}
- /// Construct a basic_object_handle on an existing native handle.
+ /// Construct an object handle without opening it.
+ /**
+ * This constructor creates an object handle without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the object handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the object handle.
+ */
+ template <typename ExecutionContext>
+ explicit basic_object_handle(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value,
+ basic_object_handle
+ >::type* = 0)
+ : impl_(context)
+ {
+ }
+
+ /// Construct an object handle on an existing native handle.
/**
* This constructor creates an object handle object to hold an existing native
* handle.
*
- * @param io_context The io_context object that the object handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
+ * @param ex The I/O executor that the object handle will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the
+ * object handle.
*
* @param native_handle The new underlying handle implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_object_handle(boost::asio::io_context& io_context,
+ basic_object_handle(const executor_type& ex,
const native_handle_type& native_handle)
- : basic_handle<ObjectHandleService>(io_context, native_handle)
+ : impl_(ex)
{
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct an object handle on an existing native handle.
+ /**
+ * This constructor creates an object handle object to hold an existing native
+ * handle.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the object handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the object handle.
+ *
+ * @param native_handle The new underlying handle implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_object_handle(ExecutionContext& context,
+ const native_handle_type& native_handle,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_object_handle from another.
+ /// Move-construct an object handle from another.
/**
* This constructor moves an object handle from one object to another.
*
- * @param other The other basic_object_handle object from which the move will
+ * @param other The other object handle object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_object_handle(io_context&) constructor.
+ * constructed using the @c basic_object_handle(const executor_type&)
+ * constructor.
*/
basic_object_handle(basic_object_handle&& other)
- : basic_handle<ObjectHandleService>(
- BOOST_ASIO_MOVE_CAST(basic_object_handle)(other))
+ : impl_(std::move(other.impl_))
{
}
- /// Move-assign a basic_object_handle from another.
+ /// Move-assign an object handle from another.
/**
* This assignment operator moves an object handle from one object to another.
*
- * @param other The other basic_object_handle object from which the move will
+ * @param other The other object handle object from which the move will
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_object_handle(io_context&) constructor.
+ * constructed using the @c basic_object_handle(const executor_type&)
+ * constructor.
*/
basic_object_handle& operator=(basic_object_handle&& other)
{
- basic_handle<ObjectHandleService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_object_handle)(other));
+ impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
+ /// Get a reference to the lowest layer.
+ /**
+ * This function returns a reference to the lowest layer in a stack of
+ * layers. Since an object handle cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A reference to the lowest layer in the stack of layers. Ownership
+ * is not transferred to the caller.
+ */
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ /// Get a const reference to the lowest layer.
+ /**
+ * This function returns a const reference to the lowest layer in a stack of
+ * layers. Since an object handle cannot contain any further layers, it simply
+ * returns a reference to itself.
+ *
+ * @return A const reference to the lowest layer in the stack of layers.
+ * Ownership is not transferred to the caller.
+ */
+ const lowest_layer_type& lowest_layer() const
+ {
+ return *this;
+ }
+
+ /// Assign an existing native handle to the handle.
+ /*
+ * This function opens the handle to hold an existing native handle.
+ *
+ * @param handle A native handle.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void assign(const native_handle_type& handle)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Assign an existing native handle to the handle.
+ /*
+ * This function opens the handle to hold an existing native handle.
+ *
+ * @param handle A native handle.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().assign(impl_.get_implementation(), handle, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the handle is open.
+ bool is_open() const
+ {
+ return impl_.get_service().is_open(impl_.get_implementation());
+ }
+
+ /// Close the handle.
+ /**
+ * This function is used to close the handle. Any asynchronous read or write
+ * operations will be cancelled immediately, and will complete with the
+ * boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void close()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "close");
+ }
+
+ /// Close the handle.
+ /**
+ * This function is used to close the handle. Any asynchronous read or write
+ * operations will be cancelled immediately, and will complete with the
+ * boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+ {
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get the native handle representation.
+ /**
+ * This function may be used to obtain the underlying representation of the
+ * handle. This is intended to allow access to native handle functionality
+ * that is not otherwise provided.
+ */
+ native_handle_type native_handle()
+ {
+ return impl_.get_service().native_handle(impl_.get_implementation());
+ }
+
+ /// Cancel all asynchronous operations associated with the handle.
+ /**
+ * This function causes all outstanding asynchronous read or write operations
+ * to finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void cancel()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "cancel");
+ }
+
+ /// Cancel all asynchronous operations associated with the handle.
+ /**
+ * This function causes all outstanding asynchronous read or write operations
+ * to finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+ {
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
/// Perform a blocking wait on the object handle.
/**
* This function is used to wait for the object handle to be set to the
@@ -127,7 +330,7 @@ public:
void wait()
{
boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
boost::asio::detail::throw_error(ec, "wait");
}
@@ -141,7 +344,7 @@ public:
*/
void wait(boost::system::error_code& ec)
{
- this->get_service().wait(this->get_implementation(), ec);
+ impl_.get_service().wait(impl_.get_implementation(), ec);
}
/// Start an asynchronous wait on the object handle.
@@ -156,18 +359,31 @@ public:
* const boost::system::error_code& error // Result of operation.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename WaitHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (boost::system::error_code))
async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
{
- return this->get_service().async_wait(this->get_implementation(),
- BOOST_ASIO_MOVE_CAST(WaitHandler)(handler));
+ boost::asio::async_completion<WaitHandler,
+ void (boost::system::error_code)> init(handler);
+
+ impl_.get_service().async_wait(impl_.get_implementation(),
+ init.completion_handler, impl_.get_implementation_executor());
+
+ return init.result.get();
}
+
+private:
+ // Disallow copying and assignment.
+ basic_object_handle(const basic_object_handle&) BOOST_ASIO_DELETED;
+ basic_object_handle& operator=(const basic_object_handle&) BOOST_ASIO_DELETED;
+
+ boost::asio::detail::io_object_impl<
+ boost::asio::detail::win_object_handle_service, Executor> impl_;
};
} // namespace windows
@@ -179,6 +395,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_WINDOWS_BASIC_OBJECT_HANDLE_HPP
diff --git a/boost/asio/windows/basic_overlapped_handle.hpp b/boost/asio/windows/basic_overlapped_handle.hpp
new file mode 100644
index 0000000000..ccce21fecb
--- /dev/null
+++ b/boost/asio/windows/basic_overlapped_handle.hpp
@@ -0,0 +1,355 @@
+//
+// windows/basic_overlapped_handle.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2019 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_WINDOWS_BASIC_OVERLAPPED_HANDLE_HPP
+#define BOOST_ASIO_WINDOWS_BASIC_OVERLAPPED_HANDLE_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_WINDOWS_RANDOM_ACCESS_HANDLE) \
+ || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
+ || defined(GENERATING_DOCUMENTATION)
+
+#include <cstddef>
+#include <boost/asio/async_result.hpp>
+#include <boost/asio/detail/io_object_impl.hpp>
+#include <boost/asio/detail/throw_error.hpp>
+#include <boost/asio/detail/win_iocp_handle_service.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/execution_context.hpp>
+#include <boost/asio/executor.hpp>
+
+#if defined(BOOST_ASIO_HAS_MOVE)
+# include <utility>
+#endif // defined(BOOST_ASIO_HAS_MOVE)
+
+#include <boost/asio/detail/push_options.hpp>
+
+namespace boost {
+namespace asio {
+namespace windows {
+
+/// Provides Windows handle functionality for objects that support
+/// overlapped I/O.
+/**
+ * The windows::overlapped_handle class provides the ability to wrap a Windows
+ * handle. The underlying object referred to by the handle must support
+ * overlapped I/O.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ */
+template <typename Executor = executor>
+class basic_overlapped_handle
+{
+public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
+ /// The native representation of a handle.
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef boost::asio::detail::win_iocp_handle_service::native_handle_type
+ native_handle_type;
+#endif
+
+ /// An overlapped_handle is always the lowest layer.
+ typedef basic_overlapped_handle lowest_layer_type;
+
+ /// Construct an overlapped handle without opening it.
+ /**
+ * This constructor creates an overlapped handle without opening it.
+ *
+ * @param ex The I/O executor that the overlapped handle will use, by default,
+ * to dispatch handlers for any asynchronous operations performed on the
+ * overlapped handle.
+ */
+ explicit basic_overlapped_handle(const executor_type& ex)
+ : impl_(ex)
+ {
+ }
+
+ /// Construct an overlapped handle without opening it.
+ /**
+ * This constructor creates an overlapped handle without opening it.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the overlapped handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the overlapped handle.
+ */
+ template <typename ExecutionContext>
+ explicit basic_overlapped_handle(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value,
+ basic_overlapped_handle
+ >::type* = 0)
+ : impl_(context)
+ {
+ }
+
+ /// Construct an overlapped handle on an existing native handle.
+ /**
+ * This constructor creates an overlapped handle object to hold an existing
+ * native handle.
+ *
+ * @param ex The I/O executor that the overlapped handle will use, by default,
+ * to dispatch handlers for any asynchronous operations performed on the
+ * overlapped handle.
+ *
+ * @param native_handle The new underlying handle implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ basic_overlapped_handle(const executor_type& ex,
+ const native_handle_type& native_handle)
+ : impl_(ex)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Construct an overlapped handle on an existing native handle.
+ /**
+ * This constructor creates an overlapped handle object to hold an existing
+ * native handle.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the overlapped handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the overlapped handle.
+ *
+ * @param native_handle The new underlying handle implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_overlapped_handle(ExecutionContext& context,
+ const native_handle_type& native_handle,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), native_handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+ /// Move-construct an overlapped handle from another.
+ /**
+ * This constructor moves a handle from one object to another.
+ *
+ * @param other The other overlapped handle object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c overlapped_handle(const executor_type&)
+ * constructor.
+ */
+ basic_overlapped_handle(basic_overlapped_handle&& other)
+ : impl_(std::move(other.impl_))
+ {
+ }
+
+ /// Move-assign an overlapped handle from another.
+ /**
+ * This assignment operator moves a handle from one object to another.
+ *
+ * @param other The other overlapped handle object from which the move will
+ * occur.
+ *
+ * @note Following the move, the moved-from object is in the same state as if
+ * constructed using the @c overlapped_handle(const executor_type&)
+ * constructor.
+ */
+ basic_overlapped_handle& operator=(basic_overlapped_handle&& other)
+ {
+ impl_ = std::move(other.impl_);
+ return *this;
+ }
+#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
+
+ /// Get the executor associated with the object.
+ executor_type get_executor() BOOST_ASIO_NOEXCEPT
+ {
+ return impl_.get_executor();
+ }
+
+ /// Get a reference to the lowest layer.
+ /**
+ * This function returns a reference to the lowest layer in a stack of
+ * layers. Since an overlapped_handle cannot contain any further layers, it
+ * simply returns a reference to itself.
+ *
+ * @return A reference to the lowest layer in the stack of layers. Ownership
+ * is not transferred to the caller.
+ */
+ lowest_layer_type& lowest_layer()
+ {
+ return *this;
+ }
+
+ /// Get a const reference to the lowest layer.
+ /**
+ * This function returns a const reference to the lowest layer in a stack of
+ * layers. Since an overlapped_handle cannot contain any further layers, it
+ * simply returns a reference to itself.
+ *
+ * @return A const reference to the lowest layer in the stack of layers.
+ * Ownership is not transferred to the caller.
+ */
+ const lowest_layer_type& lowest_layer() const
+ {
+ return *this;
+ }
+
+ /// Assign an existing native handle to the handle.
+ /*
+ * This function opens the handle to hold an existing native handle.
+ *
+ * @param handle A native handle.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void assign(const native_handle_type& handle)
+ {
+ boost::system::error_code ec;
+ impl_.get_service().assign(impl_.get_implementation(), handle, ec);
+ boost::asio::detail::throw_error(ec, "assign");
+ }
+
+ /// Assign an existing native handle to the handle.
+ /*
+ * This function opens the handle to hold an existing native handle.
+ *
+ * @param handle A native handle.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
+ boost::system::error_code& ec)
+ {
+ impl_.get_service().assign(impl_.get_implementation(), handle, ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Determine whether the handle is open.
+ bool is_open() const
+ {
+ return impl_.get_service().is_open(impl_.get_implementation());
+ }
+
+ /// Close the handle.
+ /**
+ * This function is used to close the handle. Any asynchronous read or write
+ * operations will be cancelled immediately, and will complete with the
+ * boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void close()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "close");
+ }
+
+ /// Close the handle.
+ /**
+ * This function is used to close the handle. Any asynchronous read or write
+ * operations will be cancelled immediately, and will complete with the
+ * boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
+ {
+ impl_.get_service().close(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+ /// Get the native handle representation.
+ /**
+ * This function may be used to obtain the underlying representation of the
+ * handle. This is intended to allow access to native handle functionality
+ * that is not otherwise provided.
+ */
+ native_handle_type native_handle()
+ {
+ return impl_.get_service().native_handle(impl_.get_implementation());
+ }
+
+ /// Cancel all asynchronous operations associated with the handle.
+ /**
+ * This function causes all outstanding asynchronous read or write operations
+ * to finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ void cancel()
+ {
+ boost::system::error_code ec;
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ boost::asio::detail::throw_error(ec, "cancel");
+ }
+
+ /// Cancel all asynchronous operations associated with the handle.
+ /**
+ * This function causes all outstanding asynchronous read or write operations
+ * to finish immediately, and the handlers for cancelled operations will be
+ * passed the boost::asio::error::operation_aborted error.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ */
+ BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
+ {
+ impl_.get_service().cancel(impl_.get_implementation(), ec);
+ BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
+ }
+
+protected:
+ /// Protected destructor to prevent deletion through this type.
+ /**
+ * This function destroys the handle, cancelling any outstanding asynchronous
+ * wait operations associated with the handle as if by calling @c cancel.
+ */
+ ~basic_overlapped_handle()
+ {
+ }
+
+ boost::asio::detail::io_object_impl<
+ boost::asio::detail::win_iocp_handle_service, Executor> impl_;
+
+private:
+ // Disallow copying and assignment.
+ basic_overlapped_handle(const basic_overlapped_handle&) BOOST_ASIO_DELETED;
+ basic_overlapped_handle& operator=(
+ const basic_overlapped_handle&) BOOST_ASIO_DELETED;
+};
+
+} // namespace windows
+} // namespace asio
+} // namespace boost
+
+#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_OVERLAPPED_HANDLE_HPP
diff --git a/boost/asio/windows/basic_random_access_handle.hpp b/boost/asio/windows/basic_random_access_handle.hpp
index 53765e1766..5f0d6d48c6 100644
--- a/boost/asio/windows/basic_random_access_handle.hpp
+++ b/boost/asio/windows/basic_random_access_handle.hpp
@@ -2,7 +2,7 @@
// windows/basic_random_access_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,19 +16,11 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#include <boost/asio/windows/basic_overlapped_handle.hpp>
#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#include <cstddef>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#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/push_options.hpp>
namespace boost {
@@ -37,89 +29,136 @@ namespace windows {
/// Provides random-access handle functionality.
/**
- * The windows::basic_random_access_handle class template provides asynchronous
- * and blocking random-access handle functionality.
+ * The windows::basic_random_access_handle class provides asynchronous and
+ * blocking random-access handle functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
-template <typename RandomAccessHandleService = random_access_handle_service>
+template <typename Executor = executor>
class basic_random_access_handle
- : public basic_handle<RandomAccessHandleService>
+ : public basic_overlapped_handle<Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a handle.
- typedef typename RandomAccessHandleService::native_handle_type
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef boost::asio::detail::win_iocp_handle_service::native_handle_type
native_handle_type;
+#endif
- /// Construct a basic_random_access_handle without opening it.
+ /// Construct a random-access handle without opening it.
+ /**
+ * This constructor creates a random-access handle without opening it.
+ *
+ * @param ex The I/O executor that the random-access handle will use, by
+ * default, to dispatch handlers for any asynchronous operations performed on
+ * the random-access handle.
+ */
+ explicit basic_random_access_handle(const executor_type& ex)
+ : basic_overlapped_handle<Executor>(ex)
+ {
+ }
+
+ /// Construct a random-access handle without opening it.
/**
* This constructor creates a random-access handle without opening it. The
- * handle needs to be opened before data can be written to or read from it.
+ * handle needs to be opened or assigned before data can be sent or received
+ * on it.
*
- * @param io_context The io_context object that the random-access handle will
- * use to dispatch handlers for any asynchronous operations performed on the
- * handle.
+ * @param context An execution context which provides the I/O executor that
+ * the random-access handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the random-access handle.
*/
- explicit basic_random_access_handle(boost::asio::io_context& io_context)
- : basic_handle<RandomAccessHandleService>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_random_access_handle(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value,
+ basic_random_access_handle
+ >::type* = 0)
+ : basic_overlapped_handle<Executor>(context)
{
}
- /// Construct a basic_random_access_handle on an existing native handle.
+ /// Construct a random-access handle on an existing native handle.
/**
* This constructor creates a random-access handle object to hold an existing
* native handle.
*
- * @param io_context The io_context object that the random-access handle will
- * use to dispatch handlers for any asynchronous operations performed on the
- * handle.
+ * @param ex The I/O executor that the random-access handle will use, by
+ * default, to dispatch handlers for any asynchronous operations performed on
+ * the random-access handle.
*
* @param handle The new underlying handle implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_random_access_handle(boost::asio::io_context& io_context,
+ basic_random_access_handle(const executor_type& ex,
const native_handle_type& handle)
- : basic_handle<RandomAccessHandleService>(io_context, handle)
+ : basic_overlapped_handle<Executor>(ex, handle)
+ {
+ }
+
+ /// Construct a random-access handle on an existing native handle.
+ /**
+ * This constructor creates a random-access handle object to hold an existing
+ * native handle.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the random-access handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the random-access handle.
+ *
+ * @param handle The new underlying handle implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_random_access_handle(ExecutionContext& context,
+ const native_handle_type& handle,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_overlapped_handle<Executor>(context, handle)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_random_access_handle from another.
+ /// Move-construct a random-access handle from another.
/**
* This constructor moves a random-access handle from one object to another.
*
- * @param other The other basic_random_access_handle object from which the
+ * @param other The other random-access handle object from which the
* move will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_random_access_handle(io_context&)
+ * constructed using the @c basic_random_access_handle(const executor_type&)
* constructor.
*/
basic_random_access_handle(basic_random_access_handle&& other)
- : basic_handle<RandomAccessHandleService>(
- BOOST_ASIO_MOVE_CAST(basic_random_access_handle)(other))
+ : basic_overlapped_handle<Executor>(std::move(other))
{
}
- /// Move-assign a basic_random_access_handle from another.
+ /// Move-assign a random-access handle from another.
/**
* This assignment operator moves a random-access handle from one object to
* another.
*
- * @param other The other basic_random_access_handle object from which the
+ * @param other The other random-access handle object from which the
* move will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_random_access_handle(io_context&)
+ * constructed using the @c basic_random_access_handle(const executor_type&)
* constructor.
*/
basic_random_access_handle& operator=(basic_random_access_handle&& other)
{
- basic_handle<RandomAccessHandleService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_random_access_handle)(other));
+ basic_overlapped_handle<Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -158,8 +197,8 @@ public:
const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().write_some_at(
- this->get_implementation(), offset, buffers, ec);
+ std::size_t s = this->impl_.get_service().write_some_at(
+ this->impl_.get_implementation(), offset, buffers, ec);
boost::asio::detail::throw_error(ec, "write_some_at");
return s;
}
@@ -186,8 +225,8 @@ public:
std::size_t write_some_at(uint64_t offset,
const ConstBufferSequence& buffers, boost::system::error_code& ec)
{
- return this->get_service().write_some_at(
- this->get_implementation(), offset, buffers, ec);
+ return this->impl_.get_service().write_some_at(
+ this->impl_.get_implementation(), offset, buffers, ec);
}
/// Start an asynchronous write at the specified offset.
@@ -210,9 +249,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write_at function if you need to ensure that
@@ -238,8 +277,15 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
- return this->get_service().async_write_some_at(this->get_implementation(),
- offset, buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ boost::asio::async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->impl_.get_service().async_write_some_at(
+ this->impl_.get_implementation(), offset,
+ buffers, init.completion_handler,
+ this->impl_.get_implementation_executor());
+
+ return init.result.get();
}
/// Read some data from the handle at the specified offset.
@@ -277,8 +323,8 @@ public:
const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().read_some_at(
- this->get_implementation(), offset, buffers, ec);
+ std::size_t s = this->impl_.get_service().read_some_at(
+ this->impl_.get_implementation(), offset, buffers, ec);
boost::asio::detail::throw_error(ec, "read_some_at");
return s;
}
@@ -306,8 +352,8 @@ public:
std::size_t read_some_at(uint64_t offset,
const MutableBufferSequence& buffers, boost::system::error_code& ec)
{
- return this->get_service().read_some_at(
- this->get_implementation(), offset, buffers, ec);
+ return this->impl_.get_service().read_some_at(
+ this->impl_.get_implementation(), offset, buffers, ec);
}
/// Start an asynchronous read at the specified offset.
@@ -330,9 +376,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read_at function if you need to ensure that
@@ -359,8 +405,15 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
- return this->get_service().async_read_some_at(this->get_implementation(),
- offset, buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ boost::asio::async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->impl_.get_service().async_read_some_at(
+ this->impl_.get_implementation(), offset,
+ buffers, init.completion_handler,
+ this->impl_.get_implementation_executor());
+
+ return init.result.get();
}
};
@@ -373,6 +426,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_WINDOWS_BASIC_RANDOM_ACCESS_HANDLE_HPP
diff --git a/boost/asio/windows/basic_stream_handle.hpp b/boost/asio/windows/basic_stream_handle.hpp
index 8063987983..f8d50d552c 100644
--- a/boost/asio/windows/basic_stream_handle.hpp
+++ b/boost/asio/windows/basic_stream_handle.hpp
@@ -2,7 +2,7 @@
// windows/basic_stream_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,19 +16,11 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
+#include <boost/asio/windows/basic_overlapped_handle.hpp>
#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#include <cstddef>
-#include <boost/asio/detail/handler_type_requirements.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/windows/basic_handle.hpp>
-#include <boost/asio/windows/stream_handle_service.hpp>
-
#include <boost/asio/detail/push_options.hpp>
namespace boost {
@@ -37,8 +29,8 @@ namespace windows {
/// Provides stream-oriented handle functionality.
/**
- * The windows::basic_stream_handle class template provides asynchronous and
- * blocking stream-oriented handle functionality.
+ * The windows::basic_stream_handle class provides asynchronous and blocking
+ * stream-oriented handle functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
@@ -47,78 +39,126 @@ namespace windows {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
-template <typename StreamHandleService = stream_handle_service>
+template <typename Executor = executor>
class basic_stream_handle
- : public basic_handle<StreamHandleService>
+ : public basic_overlapped_handle<Executor>
{
public:
+ /// The type of the executor associated with the object.
+ typedef Executor executor_type;
+
/// The native representation of a handle.
- typedef typename StreamHandleService::native_handle_type native_handle_type;
+#if defined(GENERATING_DOCUMENTATION)
+ typedef implementation_defined native_handle_type;
+#else
+ typedef boost::asio::detail::win_iocp_handle_service::native_handle_type
+ native_handle_type;
+#endif
- /// Construct a basic_stream_handle without opening it.
+ /// Construct a stream handle without opening it.
+ /**
+ * This constructor creates a stream handle without opening it.
+ *
+ * @param ex The I/O executor that the stream handle will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the stream
+ * handle.
+ */
+ explicit basic_stream_handle(const executor_type& ex)
+ : basic_overlapped_handle<Executor>(ex)
+ {
+ }
+
+ /// Construct a stream handle without opening it.
/**
* This constructor creates a stream handle without opening it. The handle
- * needs to be opened and then connected or accepted before data can be sent
- * or received on it.
+ * needs to be opened or assigned before data can be sent or received on it.
*
- * @param io_context The io_context object that the stream handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
+ * @param context An execution context which provides the I/O executor that
+ * the stream handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the stream handle.
*/
- explicit basic_stream_handle(boost::asio::io_context& io_context)
- : basic_handle<StreamHandleService>(io_context)
+ template <typename ExecutionContext>
+ explicit basic_stream_handle(ExecutionContext& context,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value,
+ basic_stream_handle
+ >::type* = 0)
+ : basic_overlapped_handle<Executor>(context)
{
}
- /// Construct a basic_stream_handle on an existing native handle.
+ /// Construct a stream handle on an existing native handle.
/**
* This constructor creates a stream handle object to hold an existing native
* handle.
*
- * @param io_context The io_context object that the stream handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
+ * @param ex The I/O executor that the stream handle will use, by default, to
+ * dispatch handlers for any asynchronous operations performed on the stream
+ * handle.
*
* @param handle The new underlying handle implementation.
*
* @throws boost::system::system_error Thrown on failure.
*/
- basic_stream_handle(boost::asio::io_context& io_context,
- const native_handle_type& handle)
- : basic_handle<StreamHandleService>(io_context, handle)
+ basic_stream_handle(const executor_type& ex, const native_handle_type& handle)
+ : basic_overlapped_handle<Executor>(ex, handle)
+ {
+ }
+
+ /// Construct a stream handle on an existing native handle.
+ /**
+ * This constructor creates a stream handle object to hold an existing native
+ * handle.
+ *
+ * @param context An execution context which provides the I/O executor that
+ * the stream handle will use, by default, to dispatch handlers for any
+ * asynchronous operations performed on the stream handle.
+ *
+ * @param handle The new underlying handle implementation.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+ template <typename ExecutionContext>
+ basic_stream_handle(ExecutionContext& context,
+ const native_handle_type& handle,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : basic_overlapped_handle<Executor>(context, handle)
{
}
#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a basic_stream_handle from another.
+ /// Move-construct a stream handle from another.
/**
* This constructor moves a stream handle from one object to another.
*
- * @param other The other basic_stream_handle object from which the move
+ * @param other The other stream handle object from which the move
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_handle(io_context&) constructor.
+ * constructed using the @c basic_stream_handle(const executor_type&)
+ * constructor.
*/
basic_stream_handle(basic_stream_handle&& other)
- : basic_handle<StreamHandleService>(
- BOOST_ASIO_MOVE_CAST(basic_stream_handle)(other))
+ : basic_overlapped_handle<Executor>(std::move(other))
{
}
- /// Move-assign a basic_stream_handle from another.
+ /// Move-assign a stream handle from another.
/**
* This assignment operator moves a stream handle from one object to
* another.
*
- * @param other The other basic_stream_handle object from which the move
- * will occur.
+ * @param other The other stream handle object from which the move will occur.
*
* @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c basic_stream_handle(io_context&) constructor.
+ * constructed using the @c basic_stream_handle(const executor_type&)
+ * constructor.
*/
basic_stream_handle& operator=(basic_stream_handle&& other)
{
- basic_handle<StreamHandleService>::operator=(
- BOOST_ASIO_MOVE_CAST(basic_stream_handle)(other));
+ basic_overlapped_handle<Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -154,8 +194,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = this->impl_.get_service().write_some(
+ this->impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "write_some");
return s;
}
@@ -180,8 +220,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
+ return this->impl_.get_service().write_some(
+ this->impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous write.
@@ -202,9 +242,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The write operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -229,8 +269,15 @@ public:
// not meet the documented type requirements for a WriteHandler.
BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
- return this->get_service().async_write_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
+ boost::asio::async_completion<WriteHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->impl_.get_service().async_write_some(
+ this->impl_.get_implementation(),
+ buffers, init.completion_handler,
+ this->impl_.get_implementation_executor());
+
+ return init.result.get();
}
/// Read some data from the handle.
@@ -265,8 +312,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers)
{
boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ std::size_t s = this->impl_.get_service().read_some(
+ this->impl_.get_implementation(), buffers, ec);
boost::asio::detail::throw_error(ec, "read_some");
return s;
}
@@ -292,8 +339,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
boost::system::error_code& ec)
{
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
+ return this->impl_.get_service().read_some(
+ this->impl_.get_implementation(), buffers, ec);
}
/// Start an asynchronous read.
@@ -314,9 +361,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @note The read operation may not read all of the requested number of bytes.
* Consider using the @ref async_read function if you need to ensure that the
@@ -342,8 +389,15 @@ public:
// not meet the documented type requirements for a ReadHandler.
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
- return this->get_service().async_read_some(this->get_implementation(),
- buffers, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
+ boost::asio::async_completion<ReadHandler,
+ void (boost::system::error_code, std::size_t)> init(handler);
+
+ this->impl_.get_service().async_read_some(
+ this->impl_.get_implementation(),
+ buffers, init.completion_handler,
+ this->impl_.get_implementation_executor());
+
+ return init.result.get();
}
};
@@ -356,6 +410,4 @@ public:
#endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_WINDOWS_BASIC_STREAM_HANDLE_HPP
diff --git a/boost/asio/windows/object_handle.hpp b/boost/asio/windows/object_handle.hpp
index 45eb23f4d8..6cde16627a 100644
--- a/boost/asio/windows/object_handle.hpp
+++ b/boost/asio/windows/object_handle.hpp
@@ -2,7 +2,7 @@
// windows/object_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -21,362 +21,19 @@
#if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/win_object_handle_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/windows/basic_object_handle.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#define BOOST_ASIO_SVC_T boost::asio::detail::win_object_handle_service
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/windows/basic_object_handle.hpp>
namespace boost {
namespace asio {
namespace windows {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of an object handle.
+/// Typedef for the typical usage of an object handle.
typedef basic_object_handle<> object_handle;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides object-oriented handle functionality.
-/**
- * The windows::object_handle class provides asynchronous and blocking
- * object-oriented handle functionality.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-class object_handle
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
-{
-public:
- /// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
-
- /// The native representation of a handle.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
-#endif
-
- /// An object_handle is always the lowest layer.
- typedef object_handle lowest_layer_type;
-
- /// Construct an object_handle without opening it.
- /**
- * This constructor creates an object handle without opening it.
- *
- * @param io_context The io_context object that the object handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- */
- explicit object_handle(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- }
-
- /// Construct an object_handle on an existing native handle.
- /**
- * This constructor creates an object handle object to hold an existing native
- * handle.
- *
- * @param io_context The io_context object that the object handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- *
- * @param native_handle The new underlying handle implementation.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- object_handle(boost::asio::io_context& io_context,
- const native_handle_type& native_handle)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), native_handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct an object_handle from another.
- /**
- * This constructor moves an object handle from one object to another.
- *
- * @param other The other object_handle object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c object_handle(io_context&) constructor.
- */
- object_handle(object_handle&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
- {
- }
-
- /// Move-assign an object_handle from another.
- /**
- * This assignment operator moves an object handle from one object to another.
- *
- * @param other The other object_handle object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c object_handle(io_context&) constructor.
- */
- object_handle& operator=(object_handle&& other)
- {
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the executor associated with the object.
- executor_type get_executor() BOOST_ASIO_NOEXCEPT
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
- }
-
- /// Get a reference to the lowest layer.
- /**
- * This function returns a reference to the lowest layer in a stack of
- * layers. Since an object_handle cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A reference to the lowest layer in the stack of layers. Ownership
- * is not transferred to the caller.
- */
- lowest_layer_type& lowest_layer()
- {
- return *this;
- }
-
- /// Get a const reference to the lowest layer.
- /**
- * This function returns a const reference to the lowest layer in a stack of
- * layers. Since an object_handle cannot contain any further layers, it simply
- * returns a reference to itself.
- *
- * @return A const reference to the lowest layer in the stack of layers.
- * Ownership is not transferred to the caller.
- */
- const lowest_layer_type& lowest_layer() const
- {
- return *this;
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void assign(const native_handle_type& handle)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
- boost::system::error_code& ec)
- {
- this->get_service().assign(this->get_implementation(), handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open() const
- {
- return this->get_service().is_open(this->get_implementation());
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void close()
- {
- boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "close");
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
- {
- this->get_service().close(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle representation.
- /**
- * This function may be used to obtain the underlying representation of the
- * handle. This is intended to allow access to native handle functionality
- * that is not otherwise provided.
- */
- native_handle_type native_handle()
- {
- return this->get_service().native_handle(this->get_implementation());
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Perform a blocking wait on the object handle.
- /**
- * This function is used to wait for the object handle to be set to the
- * signalled state. This function blocks and does not return until the object
- * handle has been set to the signalled state.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void wait()
- {
- boost::system::error_code ec;
- this->get_service().wait(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "wait");
- }
-
- /// Perform a blocking wait on the object handle.
- /**
- * This function is used to wait for the object handle to be set to the
- * signalled state. This function blocks and does not return until the object
- * handle has been set to the signalled state.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- void wait(boost::system::error_code& ec)
- {
- this->get_service().wait(this->get_implementation(), ec);
- }
-
- /// Start an asynchronous wait on the object handle.
- /**
- * This function is be used to initiate an asynchronous wait against the
- * object handle. It always returns immediately.
- *
- * @param handler The handler to be called when the object handle is set to
- * the signalled state. Copies will be made of the handler as required. The
- * function signature of the handler must be:
- * @code void handler(
- * const boost::system::error_code& error // Result of operation.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- */
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- boost::asio::async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- this->get_service().async_wait(this->get_implementation(),
- init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace windows
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
-#undef BOOST_ASIO_SVC_T
-
#endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/windows/object_handle_service.hpp b/boost/asio/windows/object_handle_service.hpp
deleted file mode 100644
index 6ff8197990..0000000000
--- a/boost/asio/windows/object_handle_service.hpp
+++ /dev/null
@@ -1,185 +0,0 @@
-//
-// windows/object_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
-// Copyright (c) 2011 Boris Schaeling (boris@highscore.de)
-//
-// 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_WINDOWS_OBJECT_HANDLE_SERVICE_HPP
-#define BOOST_ASIO_WINDOWS_OBJECT_HANDLE_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/win_object_handle_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace windows {
-
-/// Default service implementation for an object handle.
-class object_handle_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<object_handle_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::win_object_handle_service service_impl_type;
-
-public:
- /// The type of an object handle implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native handle type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new object handle service for the specified io_context.
- explicit object_handle_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<object_handle_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new object handle implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new object handle implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another object handle implementation.
- void move_assign(implementation_type& impl,
- object_handle_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy an object handle implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Assign an existing native handle to an object handle.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const native_handle_type& handle, boost::system::error_code& ec)
- {
- service_impl_.assign(impl, handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close an object handle implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- // Wait for a signaled state.
- void wait(implementation_type& impl, boost::system::error_code& ec)
- {
- service_impl_.wait(impl, ec);
- }
-
- /// Start an asynchronous wait.
- template <typename WaitHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler,
- void (boost::system::error_code))
- async_wait(implementation_type& impl,
- BOOST_ASIO_MOVE_ARG(WaitHandler) handler)
- {
- boost::asio::async_completion<WaitHandler,
- void (boost::system::error_code)> init(handler);
-
- service_impl_.async_wait(impl, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace windows
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_WINDOWS_OBJECT_HANDLE)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_WINDOWS_OBJECT_HANDLE_SERVICE_HPP
diff --git a/boost/asio/windows/overlapped_handle.hpp b/boost/asio/windows/overlapped_handle.hpp
index 16dcbedbb6..e87e7b35c0 100644
--- a/boost/asio/windows/overlapped_handle.hpp
+++ b/boost/asio/windows/overlapped_handle.hpp
@@ -2,7 +2,7 @@
// windows/overlapped_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -17,317 +17,25 @@
#include <boost/asio/detail/config.hpp>
-#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
|| defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/basic_io_object.hpp>
-#include <boost/asio/detail/throw_error.hpp>
-#include <boost/asio/detail/win_iocp_handle_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#if defined(BOOST_ASIO_HAS_MOVE)
-# include <utility>
-#endif // defined(BOOST_ASIO_HAS_MOVE)
-
-#define BOOST_ASIO_SVC_T boost::asio::detail::win_iocp_handle_service
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/windows/basic_overlapped_handle.hpp>
namespace boost {
namespace asio {
namespace windows {
-/// Provides Windows handle functionality for objects that support
-/// overlapped I/O.
-/**
- * The windows::overlapped_handle class provides the ability to wrap a Windows
- * handle. The underlying object referred to by the handle must support
- * overlapped I/O.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-class overlapped_handle
- : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T>
-{
-public:
- /// The type of the executor associated with the object.
- typedef io_context::executor_type executor_type;
-
- /// The native representation of a handle.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef BOOST_ASIO_SVC_T::native_handle_type native_handle_type;
-#endif
-
- /// An overlapped_handle is always the lowest layer.
- typedef overlapped_handle lowest_layer_type;
-
- /// Construct an overlapped_handle without opening it.
- /**
- * This constructor creates a handle without opening it.
- *
- * @param io_context The io_context object that the handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- */
- explicit overlapped_handle(boost::asio::io_context& io_context)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- }
-
- /// Construct an overlapped_handle on an existing native handle.
- /**
- * This constructor creates a handle object to hold an existing native handle.
- *
- * @param io_context The io_context object that the handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- *
- * @param handle A native handle.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- overlapped_handle(boost::asio::io_context& io_context,
- const native_handle_type& handle)
- : basic_io_object<BOOST_ASIO_SVC_T>(io_context)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct an overlapped_handle from another.
- /**
- * This constructor moves a handle from one object to another.
- *
- * @param other The other overlapped_handle object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c overlapped_handle(io_context&) constructor.
- */
- overlapped_handle(overlapped_handle&& other)
- : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other))
- {
- }
-
- /// Move-assign an overlapped_handle from another.
- /**
- * This assignment operator moves a handle from one object to another.
- *
- * @param other The other overlapped_handle object from which the move will
- * occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c overlapped_handle(io_context&) constructor.
- */
- overlapped_handle& operator=(overlapped_handle&& other)
- {
- basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
-#if !defined(BOOST_ASIO_NO_DEPRECATED)
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_context()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context();
- }
-
- /// (Deprecated: Use get_executor().) Get the io_context associated with the
- /// object.
- /**
- * This function may be used to obtain the io_context object that the I/O
- * object uses to dispatch handlers for asynchronous operations.
- *
- * @return A reference to the io_context object that the I/O object will use
- * to dispatch handlers. Ownership is not transferred to the caller.
- */
- boost::asio::io_context& get_io_service()
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service();
- }
-#endif // !defined(BOOST_ASIO_NO_DEPRECATED)
-
- /// Get the executor associated with the object.
- executor_type get_executor() BOOST_ASIO_NOEXCEPT
- {
- return basic_io_object<BOOST_ASIO_SVC_T>::get_executor();
- }
-
- /// Get a reference to the lowest layer.
- /**
- * This function returns a reference to the lowest layer in a stack of
- * layers. Since an overlapped_handle cannot contain any further layers, it
- * simply returns a reference to itself.
- *
- * @return A reference to the lowest layer in the stack of layers. Ownership
- * is not transferred to the caller.
- */
- lowest_layer_type& lowest_layer()
- {
- return *this;
- }
-
- /// Get a const reference to the lowest layer.
- /**
- * This function returns a const reference to the lowest layer in a stack of
- * layers. Since an overlapped_handle cannot contain any further layers, it
- * simply returns a reference to itself.
- *
- * @return A const reference to the lowest layer in the stack of layers.
- * Ownership is not transferred to the caller.
- */
- const lowest_layer_type& lowest_layer() const
- {
- return *this;
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void assign(const native_handle_type& handle)
- {
- boost::system::error_code ec;
- this->get_service().assign(this->get_implementation(), handle, ec);
- boost::asio::detail::throw_error(ec, "assign");
- }
-
- /// Assign an existing native handle to the handle.
- /*
- * This function opens the handle to hold an existing native handle.
- *
- * @param handle A native handle.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID assign(const native_handle_type& handle,
- boost::system::error_code& ec)
- {
- this->get_service().assign(this->get_implementation(), handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open() const
- {
- return this->get_service().is_open(this->get_implementation());
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void close()
- {
- boost::system::error_code ec;
- this->get_service().close(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "close");
- }
-
- /// Close the handle.
- /**
- * This function is used to close the handle. Any asynchronous read or write
- * operations will be cancelled immediately, and will complete with the
- * boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec)
- {
- this->get_service().close(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle representation.
- /**
- * This function may be used to obtain the underlying representation of the
- * handle. This is intended to allow access to native handle functionality
- * that is not otherwise provided.
- */
- native_handle_type native_handle()
- {
- return this->get_service().native_handle(this->get_implementation());
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- void cancel()
- {
- boost::system::error_code ec;
- this->get_service().cancel(this->get_implementation(), ec);
- boost::asio::detail::throw_error(ec, "cancel");
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- /**
- * This function causes all outstanding asynchronous read or write operations
- * to finish immediately, and the handlers for cancelled operations will be
- * passed the boost::asio::error::operation_aborted error.
- *
- * @param ec Set to indicate what error occurred, if any.
- */
- BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec)
- {
- this->get_service().cancel(this->get_implementation(), ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
-protected:
- /// Protected destructor to prevent deletion through this type.
- /**
- * This function destroys the handle, cancelling any outstanding asynchronous
- * wait operations associated with the handle as if by calling @c cancel.
- */
- ~overlapped_handle()
- {
- }
-};
+/// Typedef for the typical usage of an overlapped handle.
+typedef basic_overlapped_handle<> overlapped_handle;
} // namespace windows
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
-#undef BOOST_ASIO_SVC_T
-
#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
// || defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
-#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
#endif // BOOST_ASIO_WINDOWS_OVERLAPPED_HANDLE_HPP
diff --git a/boost/asio/windows/overlapped_ptr.hpp b/boost/asio/windows/overlapped_ptr.hpp
index 8c95ce45f9..a891248ceb 100644
--- a/boost/asio/windows/overlapped_ptr.hpp
+++ b/boost/asio/windows/overlapped_ptr.hpp
@@ -2,7 +2,7 @@
// windows/overlapped_ptr.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -50,10 +50,24 @@ public:
}
/// Construct an overlapped_ptr to contain the specified handler.
- template <typename Handler>
- explicit overlapped_ptr(boost::asio::io_context& io_context,
- BOOST_ASIO_MOVE_ARG(Handler) handler)
- : impl_(io_context, BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ template <typename ExecutionContext, typename Handler>
+ explicit overlapped_ptr(ExecutionContext& context,
+ BOOST_ASIO_MOVE_ARG(Handler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ : impl_(context.get_executor(), BOOST_ASIO_MOVE_CAST(Handler)(handler))
+ {
+ }
+
+ /// Construct an overlapped_ptr to contain the specified handler.
+ template <typename Executor, typename Handler>
+ explicit overlapped_ptr(const Executor& ex,
+ BOOST_ASIO_MOVE_ARG(Handler) handler,
+ typename enable_if<
+ is_executor<Executor>::value
+ >::type* = 0)
+ : impl_(ex, BOOST_ASIO_MOVE_CAST(Handler)(handler))
{
}
@@ -70,11 +84,24 @@ public:
/// Reset to contain the specified handler, freeing any current OVERLAPPED
/// object.
- template <typename Handler>
- void reset(boost::asio::io_context& io_context,
- BOOST_ASIO_MOVE_ARG(Handler) handler)
+ template <typename ExecutionContext, typename Handler>
+ void reset(ExecutionContext& context, BOOST_ASIO_MOVE_ARG(Handler) handler,
+ typename enable_if<
+ is_convertible<ExecutionContext&, execution_context&>::value
+ >::type* = 0)
+ {
+ impl_.reset(context.get_executor(), BOOST_ASIO_MOVE_CAST(Handler)(handler));
+ }
+
+ /// Reset to contain the specified handler, freeing any current OVERLAPPED
+ /// object.
+ template <typename Executor, typename Handler>
+ void reset(const Executor& ex, BOOST_ASIO_MOVE_ARG(Handler) handler,
+ typename enable_if<
+ is_executor<Executor>::value
+ >::type* = 0)
{
- impl_.reset(io_context, BOOST_ASIO_MOVE_CAST(Handler)(handler));
+ impl_.reset(ex, BOOST_ASIO_MOVE_CAST(Handler)(handler));
}
/// Get the contained OVERLAPPED object.
diff --git a/boost/asio/windows/random_access_handle.hpp b/boost/asio/windows/random_access_handle.hpp
index 4ff62d39df..77ae022f5d 100644
--- a/boost/asio/windows/random_access_handle.hpp
+++ b/boost/asio/windows/random_access_handle.hpp
@@ -2,7 +2,7 @@
// windows/random_access_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,364 +16,23 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-#include <boost/asio/windows/overlapped_handle.hpp>
#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/windows/basic_random_access_handle.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/windows/basic_random_access_handle.hpp>
namespace boost {
namespace asio {
namespace windows {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of a random-access handle.
+/// Typedef for the typical usage of a random-access handle.
typedef basic_random_access_handle<> random_access_handle;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides random-access handle functionality.
-/**
- * The windows::random_access_handle class provides asynchronous and
- * blocking random-access handle functionality.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- */
-class random_access_handle
- : public overlapped_handle
-{
-public:
- /// Construct a random_access_handle without opening it.
- /**
- * This constructor creates a random-access handle without opening it. The
- * handle needs to be opened before data can be written to or read from it.
- *
- * @param io_context The io_context object that the random-access handle will
- * use to dispatch handlers for any asynchronous operations performed on the
- * handle.
- */
- explicit random_access_handle(boost::asio::io_context& io_context)
- : overlapped_handle(io_context)
- {
- }
-
- /// Construct a random_access_handle on an existing native handle.
- /**
- * This constructor creates a random-access handle object to hold an existing
- * native handle.
- *
- * @param io_context The io_context object that the random-access handle will
- * use to dispatch handlers for any asynchronous operations performed on the
- * handle.
- *
- * @param handle The new underlying handle implementation.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- random_access_handle(boost::asio::io_context& io_context,
- const native_handle_type& handle)
- : overlapped_handle(io_context, handle)
- {
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a random_access_handle from another.
- /**
- * This constructor moves a random-access handle from one object to another.
- *
- * @param other The other random_access_handle object from which the
- * move will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c random_access_handle(io_context&)
- * constructor.
- */
- random_access_handle(random_access_handle&& other)
- : overlapped_handle(std::move(other))
- {
- }
-
- /// Move-assign a random_access_handle from another.
- /**
- * This assignment operator moves a random-access handle from one object to
- * another.
- *
- * @param other The other random_access_handle object from which the
- * move will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c random_access_handle(io_context&)
- * constructor.
- */
- random_access_handle& operator=(random_access_handle&& other)
- {
- overlapped_handle::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Write some data to the handle at the specified offset.
- /**
- * This function is used to write data to the random-access handle. The
- * function call will block until one or more bytes of the data has been
- * written successfully, or until an error occurs.
- *
- * @param offset The offset at which the data will be written.
- *
- * @param buffers One or more data buffers to be written to the handle.
- *
- * @returns The number of bytes written.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The write_some_at operation may not write all of the data. Consider
- * using the @ref write_at function if you need to ensure that all data is
- * written before the blocking operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.write_some_at(42, boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some_at(uint64_t offset,
- const ConstBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().write_some_at(
- this->get_implementation(), offset, buffers, ec);
- boost::asio::detail::throw_error(ec, "write_some_at");
- return s;
- }
-
- /// Write some data to the handle at the specified offset.
- /**
- * This function is used to write data to the random-access handle. The
- * function call will block until one or more bytes of the data has been
- * written successfully, or until an error occurs.
- *
- * @param offset The offset at which the data will be written.
- *
- * @param buffers One or more data buffers to be written to the handle.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes written. Returns 0 if an error occurred.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write_at function if you need to ensure that
- * all data is written before the blocking operation completes.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some_at(uint64_t offset,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return this->get_service().write_some_at(
- this->get_implementation(), offset, buffers, ec);
- }
-
- /// Start an asynchronous write at the specified offset.
- /**
- * This function is used to asynchronously write data to the random-access
- * handle. The function call always returns immediately.
- *
- * @param offset The offset at which the data will be written.
- *
- * @param buffers One or more data buffers to be written to the handle.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the write operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes written.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The write operation may not transmit all of the data to the peer.
- * Consider using the @ref async_write_at function if you need to ensure that
- * all data is written before the asynchronous operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.async_write_some_at(42, boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some_at(uint64_t offset,
- const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_write_some_at(this->get_implementation(),
- offset, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the handle at the specified offset.
- /**
- * This function is used to read data from the random-access handle. The
- * function call will block until one or more bytes of data has been read
- * successfully, or until an error occurs.
- *
- * @param offset The offset at which the data will be read.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @returns The number of bytes read.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read_at function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.read_some_at(42, boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some_at(uint64_t offset,
- const MutableBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().read_some_at(
- this->get_implementation(), offset, buffers, ec);
- boost::asio::detail::throw_error(ec, "read_some_at");
- return s;
- }
-
- /// Read some data from the handle at the specified offset.
- /**
- * This function is used to read data from the random-access handle. The
- * function call will block until one or more bytes of data has been read
- * successfully, or until an error occurs.
- *
- * @param offset The offset at which the data will be read.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes read. Returns 0 if an error occurred.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read_at function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some_at(uint64_t offset,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return this->get_service().read_some_at(
- this->get_implementation(), offset, buffers, ec);
- }
-
- /// Start an asynchronous read at the specified offset.
- /**
- * This function is used to asynchronously read data from the random-access
- * handle. The function call always returns immediately.
- *
- * @param offset The offset at which the data will be read.
- *
- * @param buffers One or more buffers into which the data will be read.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the read operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes read.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The read operation may not read all of the requested number of bytes.
- * Consider using the @ref async_read_at function if you need to ensure that
- * the requested amount of data is read before the asynchronous operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.async_read_some_at(42, boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some_at(uint64_t offset,
- const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_read_some_at(this->get_implementation(),
- offset, buffers, init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace windows
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/windows/random_access_handle_service.hpp b/boost/asio/windows/random_access_handle_service.hpp
deleted file mode 100644
index 0ec0773acb..0000000000
--- a/boost/asio/windows/random_access_handle_service.hpp
+++ /dev/null
@@ -1,216 +0,0 @@
-//
-// windows/random_access_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP
-#define BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/cstdint.hpp>
-#include <boost/asio/detail/win_iocp_handle_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace windows {
-
-/// Default service implementation for a random-access handle.
-class random_access_handle_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<random_access_handle_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::win_iocp_handle_service service_impl_type;
-
-public:
- /// The type of a random-access handle implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native handle type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new random-access handle service for the specified io_context.
- explicit random_access_handle_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<
- random_access_handle_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new random-access handle implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new random-access handle implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another random-access handle implementation.
- void move_assign(implementation_type& impl,
- random_access_handle_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a random-access handle implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Assign an existing native handle to a random-access handle.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const native_handle_type& handle, boost::system::error_code& ec)
- {
- service_impl_.assign(impl, handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a random-access handle implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Write the given data at the specified offset.
- template <typename ConstBufferSequence>
- std::size_t write_some_at(implementation_type& impl, uint64_t offset,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.write_some_at(impl, offset, buffers, ec);
- }
-
- /// Start an asynchronous write at the specified offset.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some_at(implementation_type& impl,
- uint64_t offset, const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_write_some_at(impl,
- offset, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the specified offset.
- template <typename MutableBufferSequence>
- std::size_t read_some_at(implementation_type& impl, uint64_t offset,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.read_some_at(impl, offset, buffers, ec);
- }
-
- /// Start an asynchronous read at the specified offset.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some_at(implementation_type& impl,
- uint64_t offset, const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_read_some_at(impl,
- offset, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace windows
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_WINDOWS_RANDOM_ACCESS_HANDLE)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_WINDOWS_RANDOM_ACCESS_HANDLE_SERVICE_HPP
diff --git a/boost/asio/windows/stream_handle.hpp b/boost/asio/windows/stream_handle.hpp
index a8962b6b12..56e7db033b 100644
--- a/boost/asio/windows/stream_handle.hpp
+++ b/boost/asio/windows/stream_handle.hpp
@@ -2,7 +2,7 @@
// windows/stream_handle.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -16,348 +16,23 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include <boost/asio/detail/config.hpp>
-#include <boost/asio/windows/overlapped_handle.hpp>
#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
|| defined(GENERATING_DOCUMENTATION)
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-# include <boost/asio/windows/basic_stream_handle.hpp>
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#include <boost/asio/detail/push_options.hpp>
+#include <boost/asio/windows/basic_stream_handle.hpp>
namespace boost {
namespace asio {
namespace windows {
-#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-// Typedef for the typical usage of a stream-oriented handle.
+/// Typedef for the typical usage of a stream-oriented handle.
typedef basic_stream_handle<> stream_handle;
-#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-/// Provides stream-oriented handle functionality.
-/**
- * The windows::stream_handle class provides asynchronous and blocking
- * stream-oriented handle functionality.
- *
- * @par Thread Safety
- * @e Distinct @e objects: Safe.@n
- * @e Shared @e objects: Unsafe.
- *
- * @par Concepts:
- * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
- */
-class stream_handle
- : public overlapped_handle
-{
-public:
- /// Construct a stream_handle without opening it.
- /**
- * This constructor creates a stream handle without opening it. The handle
- * needs to be opened and then connected or accepted before data can be sent
- * or received on it.
- *
- * @param io_context The io_context object that the stream handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- */
- explicit stream_handle(boost::asio::io_context& io_context)
- : overlapped_handle(io_context)
- {
- }
-
- /// Construct a stream_handle on an existing native handle.
- /**
- * This constructor creates a stream handle object to hold an existing native
- * handle.
- *
- * @param io_context The io_context object that the stream handle will use to
- * dispatch handlers for any asynchronous operations performed on the handle.
- *
- * @param handle The new underlying handle implementation.
- *
- * @throws boost::system::system_error Thrown on failure.
- */
- stream_handle(boost::asio::io_context& io_context,
- const native_handle_type& handle)
- : overlapped_handle(io_context, handle)
- {
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a stream_handle from another.
- /**
- * This constructor moves a stream handle from one object to another.
- *
- * @param other The other stream_handle object from which the move
- * will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c stream_handle(io_context&) constructor.
- */
- stream_handle(stream_handle&& other)
- : overlapped_handle(std::move(other))
- {
- }
-
- /// Move-assign a stream_handle from another.
- /**
- * This assignment operator moves a stream handle from one object to
- * another.
- *
- * @param other The other stream_handle object from which the move
- * will occur.
- *
- * @note Following the move, the moved-from object is in the same state as if
- * constructed using the @c stream_handle(io_context&) constructor.
- */
- stream_handle& operator=(stream_handle&& other)
- {
- overlapped_handle::operator=(std::move(other));
- return *this;
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Write some data to the handle.
- /**
- * This function is used to write data to the stream handle. The function call
- * will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the handle.
- *
- * @returns The number of bytes written.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.write_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "write_some");
- return s;
- }
-
- /// Write some data to the handle.
- /**
- * This function is used to write data to the stream handle. The function call
- * will block until one or more bytes of the data has been written
- * successfully, or until an error occurs.
- *
- * @param buffers One or more data buffers to be written to the handle.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes written. Returns 0 if an error occurred.
- *
- * @note The write_some operation may not transmit all of the data to the
- * peer. Consider using the @ref write function if you need to ensure that
- * all data is written before the blocking operation completes.
- */
- template <typename ConstBufferSequence>
- std::size_t write_some(const ConstBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().write_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous write.
- /**
- * This function is used to asynchronously write data to the stream handle.
- * The function call always returns immediately.
- *
- * @param buffers One or more data buffers to be written to the handle.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the write operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes written.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The write operation may not transmit all of the data to the peer.
- * Consider using the @ref async_write function if you need to ensure that all
- * data is written before the asynchronous operation completes.
- *
- * @par Example
- * To write a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.async_write_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on writing multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a WriteHandler.
- BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
-
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_write_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the handle.
- /**
- * This function is used to read data from the stream handle. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @returns The number of bytes read.
- *
- * @throws boost::system::system_error Thrown on failure. An error code of
- * boost::asio::error::eof indicates that the connection was closed by the
- * peer.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.read_some(boost::asio::buffer(data, size));
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers)
- {
- boost::system::error_code ec;
- std::size_t s = this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- boost::asio::detail::throw_error(ec, "read_some");
- return s;
- }
-
- /// Read some data from the handle.
- /**
- * This function is used to read data from the stream handle. The function
- * call will block until one or more bytes of data has been read successfully,
- * or until an error occurs.
- *
- * @param buffers One or more buffers into which the data will be read.
- *
- * @param ec Set to indicate what error occurred, if any.
- *
- * @returns The number of bytes read. Returns 0 if an error occurred.
- *
- * @note The read_some operation may not read all of the requested number of
- * bytes. Consider using the @ref read function if you need to ensure that
- * the requested amount of data is read before the blocking operation
- * completes.
- */
- template <typename MutableBufferSequence>
- std::size_t read_some(const MutableBufferSequence& buffers,
- boost::system::error_code& ec)
- {
- return this->get_service().read_some(
- this->get_implementation(), buffers, ec);
- }
-
- /// Start an asynchronous read.
- /**
- * This function is used to asynchronously read data from the stream handle.
- * The function call always returns immediately.
- *
- * @param buffers One or more buffers into which the data will be read.
- * Although the buffers object may be copied as necessary, ownership of the
- * underlying memory blocks is retained by the caller, which must guarantee
- * that they remain valid until the handler is called.
- *
- * @param handler The handler to be called when the read operation completes.
- * Copies will be made of the handler as required. The function signature of
- * the handler must be:
- * @code void handler(
- * const boost::system::error_code& error, // Result of operation.
- * std::size_t bytes_transferred // Number of bytes read.
- * ); @endcode
- * Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation
- * of the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
- *
- * @note The read operation may not read all of the requested number of bytes.
- * Consider using the @ref async_read function if you need to ensure that the
- * requested amount of data is read before the asynchronous operation
- * completes.
- *
- * @par Example
- * To read into a single data buffer use the @ref buffer function as follows:
- * @code
- * handle.async_read_some(boost::asio::buffer(data, size), handler);
- * @endcode
- * See the @ref buffer documentation for information on reading into multiple
- * buffers in one go, and how to use it with arrays, boost::array or
- * std::vector.
- */
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- // If you get an error on the following line it means that your handler does
- // not meet the documented type requirements for a ReadHandler.
- BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
-
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- this->get_service().async_read_some(
- this->get_implementation(), buffers, init.completion_handler);
-
- return init.result.get();
- }
-};
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
} // namespace windows
} // namespace asio
} // namespace boost
-#include <boost/asio/detail/pop_options.hpp>
-
#endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
// || defined(GENERATING_DOCUMENTATION)
diff --git a/boost/asio/windows/stream_handle_service.hpp b/boost/asio/windows/stream_handle_service.hpp
deleted file mode 100644
index d3d47d2236..0000000000
--- a/boost/asio/windows/stream_handle_service.hpp
+++ /dev/null
@@ -1,212 +0,0 @@
-//
-// windows/stream_handle_service.hpp
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-//
-// Copyright (c) 2003-2018 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_WINDOWS_STREAM_HANDLE_SERVICE_HPP
-#define BOOST_ASIO_WINDOWS_STREAM_HANDLE_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_ENABLE_OLD_SERVICES)
-
-#if defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE) \
- || defined(GENERATING_DOCUMENTATION)
-
-#include <cstddef>
-#include <boost/asio/async_result.hpp>
-#include <boost/asio/detail/win_iocp_handle_service.hpp>
-#include <boost/asio/error.hpp>
-#include <boost/asio/io_context.hpp>
-
-#include <boost/asio/detail/push_options.hpp>
-
-namespace boost {
-namespace asio {
-namespace windows {
-
-/// Default service implementation for a stream handle.
-class stream_handle_service
-#if defined(GENERATING_DOCUMENTATION)
- : public boost::asio::io_context::service
-#else
- : public boost::asio::detail::service_base<stream_handle_service>
-#endif
-{
-public:
-#if defined(GENERATING_DOCUMENTATION)
- /// The unique service identifier.
- static boost::asio::io_context::id id;
-#endif
-
-private:
- // The type of the platform-specific implementation.
- typedef detail::win_iocp_handle_service service_impl_type;
-
-public:
- /// The type of a stream handle implementation.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined implementation_type;
-#else
- typedef service_impl_type::implementation_type implementation_type;
-#endif
-
- /// The native handle type.
-#if defined(GENERATING_DOCUMENTATION)
- typedef implementation_defined native_handle_type;
-#else
- typedef service_impl_type::native_handle_type native_handle_type;
-#endif
-
- /// Construct a new stream handle service for the specified io_context.
- explicit stream_handle_service(boost::asio::io_context& io_context)
- : boost::asio::detail::service_base<stream_handle_service>(io_context),
- service_impl_(io_context)
- {
- }
-
- /// Construct a new stream handle implementation.
- void construct(implementation_type& impl)
- {
- service_impl_.construct(impl);
- }
-
-#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
- /// Move-construct a new stream handle implementation.
- void move_construct(implementation_type& impl,
- implementation_type& other_impl)
- {
- service_impl_.move_construct(impl, other_impl);
- }
-
- /// Move-assign from another stream handle implementation.
- void move_assign(implementation_type& impl,
- stream_handle_service& other_service,
- implementation_type& other_impl)
- {
- service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
- }
-#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
-
- /// Destroy a stream handle implementation.
- void destroy(implementation_type& impl)
- {
- service_impl_.destroy(impl);
- }
-
- /// Assign an existing native handle to a stream handle.
- BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl,
- const native_handle_type& handle, boost::system::error_code& ec)
- {
- service_impl_.assign(impl, handle, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Determine whether the handle is open.
- bool is_open(const implementation_type& impl) const
- {
- return service_impl_.is_open(impl);
- }
-
- /// Close a stream handle implementation.
- BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.close(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Get the native handle implementation.
- native_handle_type native_handle(implementation_type& impl)
- {
- return service_impl_.native_handle(impl);
- }
-
- /// Cancel all asynchronous operations associated with the handle.
- BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
- boost::system::error_code& ec)
- {
- service_impl_.cancel(impl, ec);
- BOOST_ASIO_SYNC_OP_VOID_RETURN(ec);
- }
-
- /// Write the given data to the stream.
- template <typename ConstBufferSequence>
- std::size_t write_some(implementation_type& impl,
- const ConstBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.write_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous write.
- template <typename ConstBufferSequence, typename WriteHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
- void (boost::system::error_code, std::size_t))
- async_write_some(implementation_type& impl,
- const ConstBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
- {
- boost::asio::async_completion<WriteHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_write_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
- /// Read some data from the stream.
- template <typename MutableBufferSequence>
- std::size_t read_some(implementation_type& impl,
- const MutableBufferSequence& buffers, boost::system::error_code& ec)
- {
- return service_impl_.read_some(impl, buffers, ec);
- }
-
- /// Start an asynchronous read.
- template <typename MutableBufferSequence, typename ReadHandler>
- BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
- void (boost::system::error_code, std::size_t))
- async_read_some(implementation_type& impl,
- const MutableBufferSequence& buffers,
- BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
- {
- boost::asio::async_completion<ReadHandler,
- void (boost::system::error_code, std::size_t)> init(handler);
-
- service_impl_.async_read_some(impl, buffers, init.completion_handler);
-
- return init.result.get();
- }
-
-private:
- // Destroy all user-defined handler objects owned by the service.
- void shutdown()
- {
- service_impl_.shutdown();
- }
-
- // The platform-specific implementation.
- service_impl_type service_impl_;
-};
-
-} // namespace windows
-} // namespace asio
-} // namespace boost
-
-#include <boost/asio/detail/pop_options.hpp>
-
-#endif // defined(BOOST_ASIO_HAS_WINDOWS_STREAM_HANDLE)
- // || defined(GENERATING_DOCUMENTATION)
-
-#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
-
-#endif // BOOST_ASIO_WINDOWS_STREAM_HANDLE_SERVICE_HPP
diff --git a/boost/asio/write.hpp b/boost/asio/write.hpp
index e3f4d09cb7..041f163b40 100644
--- a/boost/asio/write.hpp
+++ b/boost/asio/write.hpp
@@ -2,7 +2,7 @@
// write.hpp
// ~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -224,6 +224,8 @@ std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type* = 0);
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Write all of the supplied data to a stream before returning.
/**
* This function is used to write a certain number of bytes of data to a stream.
@@ -251,11 +253,12 @@ std::size_t write(SyncWriteStream& s, const ConstBufferSequence& buffers,
* s, buffers,
* boost::asio::transfer_all()); @endcode
*/
-template <typename SyncWriteStream, typename DynamicBuffer>
+template <typename SyncWriteStream, typename DynamicBuffer_v1>
std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Write all of the supplied data to a stream before returning.
@@ -285,12 +288,13 @@ std::size_t write(SyncWriteStream& s,
* s, buffers,
* boost::asio::transfer_all(), ec); @endcode
*/
-template <typename SyncWriteStream, typename DynamicBuffer>
+template <typename SyncWriteStream, typename DynamicBuffer_v1>
std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Write a certain amount of data to a stream before returning.
@@ -329,13 +333,14 @@ std::size_t write(SyncWriteStream& s,
*
* @throws boost::system::system_error Thrown on failure.
*/
-template <typename SyncWriteStream, typename DynamicBuffer,
+template <typename SyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Write a certain amount of data to a stream before returning.
@@ -375,13 +380,14 @@ std::size_t write(SyncWriteStream& s,
* @returns The number of bytes written. If an error occurs, returns the total
* number of bytes successfully transferred prior to the error.
*/
-template <typename SyncWriteStream, typename DynamicBuffer,
+template <typename SyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition>
std::size_t write(SyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition, boost::system::error_code& ec,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -529,6 +535,163 @@ std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Write all of the supplied data to a stream before returning.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * write_some function.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the SyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Successfully written data is automatically consumed from the buffers.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::write(
+ * s, buffers,
+ * boost::asio::transfer_all()); @endcode
+ */
+template <typename SyncWriteStream, typename DynamicBuffer_v2>
+std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Write all of the supplied data to a stream before returning.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * write_some function.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the SyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Successfully written data is automatically consumed from the buffers.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @note This overload is equivalent to calling:
+ * @code boost::asio::write(
+ * s, buffers,
+ * boost::asio::transfer_all(), ec); @endcode
+ */
+template <typename SyncWriteStream, typename DynamicBuffer_v2>
+std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Write a certain amount of data to a stream before returning.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li 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.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the SyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Successfully written data is automatically consumed from the buffers.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest write_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the write operation is complete. A
+ * non-zero return value indicates the maximum number of bytes to be written on
+ * the next call to the stream's write_some function.
+ *
+ * @returns The number of bytes transferred.
+ *
+ * @throws boost::system::system_error Thrown on failure.
+ */
+template <typename SyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Write a certain amount of data to a stream before returning.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li 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.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the SyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Successfully written data is automatically consumed from the buffers.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest write_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the write operation is complete. A
+ * non-zero return value indicates the maximum number of bytes to be written on
+ * the next call to the stream's write_some function.
+ *
+ * @param ec Set to indicate what error occurred, if any.
+ *
+ * @returns The number of bytes written. If an error occurs, returns the total
+ * number of bytes successfully transferred prior to the error.
+ */
+template <typename SyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition>
+std::size_t write(SyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition, boost::system::error_code& ec,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
/*@}*/
/**
@@ -578,9 +741,9 @@ std::size_t write(SyncWriteStream& s, basic_streambuf<Allocator>& b,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
@@ -654,9 +817,9 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
@@ -679,6 +842,8 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
is_const_buffer_sequence<ConstBufferSequence>::value
>::type* = 0);
+#if !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
/// Start an asynchronous operation to write all of the supplied data to a
/// stream.
/**
@@ -718,19 +883,20 @@ async_write(AsyncWriteStream& s, const ConstBufferSequence& buffers,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncWriteStream,
- typename DynamicBuffer, typename WriteHandler>
+ typename DynamicBuffer_v1, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
/// Start an asynchronous operation to write a certain amount of data to a
@@ -786,20 +952,21 @@ async_write(AsyncWriteStream& s,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
-template <typename AsyncWriteStream, typename DynamicBuffer,
+template <typename AsyncWriteStream, typename DynamicBuffer_v1,
typename CompletionCondition, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (boost::system::error_code, std::size_t))
async_write(AsyncWriteStream& s,
- BOOST_ASIO_MOVE_ARG(DynamicBuffer) buffers,
+ BOOST_ASIO_MOVE_ARG(DynamicBuffer_v1) buffers,
CompletionCondition completion_condition,
BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
typename enable_if<
- is_dynamic_buffer<typename decay<DynamicBuffer>::type>::value
+ is_dynamic_buffer_v1<typename decay<DynamicBuffer_v1>::type>::value
+ && !is_dynamic_buffer_v2<typename decay<DynamicBuffer_v1>::type>::value
>::type* = 0);
#if !defined(BOOST_ASIO_NO_EXTENSIONS)
@@ -842,9 +1009,9 @@ async_write(AsyncWriteStream& s,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncWriteStream, typename Allocator, typename WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -903,9 +1070,9 @@ async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
* // of the buffer sizes.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncWriteStream, typename Allocator,
typename CompletionCondition, typename WriteHandler>
@@ -917,6 +1084,128 @@ async_write(AsyncWriteStream& s, basic_streambuf<Allocator>& b,
#endif // !defined(BOOST_ASIO_NO_IOSTREAM)
#endif // !defined(BOOST_ASIO_NO_EXTENSIONS)
+#endif // !defined(BOOST_ASIO_NO_DYNAMIC_BUFFER_V1)
+
+/// Start an asynchronous operation to write all of the supplied data to a
+/// stream.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li An error occurred.
+ *
+ * This operation is implemented in terms of zero or more calls to the stream's
+ * async_write_some function, and is known as a <em>composed operation</em>. 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.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the AsyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called. Successfully written
+ * data is automatically consumed from the buffers.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ *
+ * std::size_t bytes_transferred // Number of bytes written from the
+ * // buffers. If an error occurred,
+ * // this will be less than the sum
+ * // of the buffer sizes.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+template <typename AsyncWriteStream,
+ typename DynamicBuffer_v2, typename WriteHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
+
+/// Start an asynchronous operation to write a certain amount of data to a
+/// stream.
+/**
+ * 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:
+ *
+ * @li All of the data in the supplied dynamic buffer sequence has been written.
+ *
+ * @li 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 <em>composed operation</em>. 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.
+ *
+ * @param s The stream to which the data is to be written. The type must support
+ * the AsyncWriteStream concept.
+ *
+ * @param buffers The dynamic buffer sequence from which data will be written.
+ * Although the buffers object may be copied as necessary, ownership of the
+ * underlying memory blocks is retained by the caller, which must guarantee
+ * that they remain valid until the handler is called. Successfully written
+ * data is automatically consumed from the buffers.
+ *
+ * @param completion_condition The function object to be called to determine
+ * whether the write operation is complete. The signature of the function object
+ * must be:
+ * @code std::size_t completion_condition(
+ * // Result of latest async_write_some operation.
+ * const boost::system::error_code& error,
+ *
+ * // Number of bytes transferred so far.
+ * std::size_t bytes_transferred
+ * ); @endcode
+ * A return value of 0 indicates that the write operation is complete. A
+ * non-zero return value indicates the maximum number of bytes to be written on
+ * the next call to the stream's async_write_some function.
+ *
+ * @param handler The handler to be called when the write operation completes.
+ * Copies will be made of the handler as required. The function signature of the
+ * handler must be:
+ * @code void handler(
+ * const boost::system::error_code& error, // Result of operation.
+ *
+ * std::size_t bytes_transferred // Number of bytes written from the
+ * // buffers. If an error occurred,
+ * // this will be less than the sum
+ * // of the buffer sizes.
+ * ); @endcode
+ * Regardless of whether the asynchronous operation completes immediately or
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
+ */
+template <typename AsyncWriteStream, typename DynamicBuffer_v2,
+ typename CompletionCondition, typename WriteHandler>
+BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
+ void (boost::system::error_code, std::size_t))
+async_write(AsyncWriteStream& s, DynamicBuffer_v2 buffers,
+ CompletionCondition completion_condition,
+ BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
+ typename enable_if<
+ is_dynamic_buffer_v2<DynamicBuffer_v2>::value
+ >::type* = 0);
/*@}*/
diff --git a/boost/asio/write_at.hpp b/boost/asio/write_at.hpp
index 6330214bd3..d874327c5a 100644
--- a/boost/asio/write_at.hpp
+++ b/boost/asio/write_at.hpp
@@ -2,7 +2,7 @@
// write_at.hpp
// ~~~~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)
@@ -443,9 +443,9 @@ std::size_t write_at(SyncRandomAccessWriteDevice& d, uint64_t offset,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
@@ -521,9 +521,9 @@ async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*
* @par Example
* To write a single data buffer use the @ref buffer function as follows:
@@ -588,9 +588,9 @@ async_write_at(AsyncRandomAccessWriteDevice& d,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
typename WriteHandler>
@@ -654,9 +654,9 @@ async_write_at(AsyncRandomAccessWriteDevice& d, uint64_t offset,
* std::size_t bytes_transferred
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
- * not, the handler will not be invoked from within this function. Invocation of
- * the handler will be performed in a manner equivalent to using
- * boost::asio::io_context::post().
+ * not, the handler will not be invoked from within this function. On
+ * immediate completion, invocation of the handler will be performed in a
+ * manner equivalent to using boost::asio::post().
*/
template <typename AsyncRandomAccessWriteDevice, typename Allocator,
typename CompletionCondition, typename WriteHandler>
diff --git a/boost/asio/yield.hpp b/boost/asio/yield.hpp
index 5ed7f9ae4f..36628ff98b 100644
--- a/boost/asio/yield.hpp
+++ b/boost/asio/yield.hpp
@@ -2,7 +2,7 @@
// yield.hpp
// ~~~~~~~~~
//
-// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2019 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)