Version in base suite: 26.4.11-0+deb11u1 Base version: galera-4_26.4.11-0+deb11u1 Target version: galera-4_26.4.14-0+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/g/galera-4/galera-4_26.4.11-0+deb11u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/g/galera-4/galera-4_26.4.14-0+deb11u1.dsc .clang-format | 58 DartConfiguration.tcl | 115 GALERA_GIT_REVISION | 2 GALERA_REVISION | 1 GALERA_VERSION | 2 SConstruct | 2 asio/asio.hpp | 59 asio/asio/associated_allocator.hpp | 131 asio/asio/associated_executor.hpp | 149 asio/asio/async_result.hpp | 328 +- asio/asio/awaitable.hpp | 123 asio/asio/basic_datagram_socket.hpp | 476 ++- asio/asio/basic_deadline_timer.hpp | 240 + asio/asio/basic_io_object.hpp | 127 asio/asio/basic_raw_socket.hpp | 479 ++- asio/asio/basic_seq_packet_socket.hpp | 335 +- asio/asio/basic_serial_port.hpp | 386 +- asio/asio/basic_signal_set.hpp | 277 + asio/asio/basic_socket.hpp | 680 +++- asio/asio/basic_socket_acceptor.hpp | 1606 +++++++++- asio/asio/basic_socket_iostream.hpp | 229 + asio/asio/basic_socket_streambuf.hpp | 688 ++-- asio/asio/basic_stream_socket.hpp | 387 +- asio/asio/basic_streambuf.hpp | 115 asio/asio/basic_streambuf_fwd.hpp | 5 asio/asio/basic_waitable_timer.hpp | 341 +- asio/asio/bind_executor.hpp | 580 +++ asio/asio/buffer.hpp | 2633 +++++++++-------- asio/asio/buffered_read_stream.hpp | 26 asio/asio/buffered_read_stream_fwd.hpp | 2 asio/asio/buffered_stream.hpp | 17 asio/asio/buffered_stream_fwd.hpp | 2 asio/asio/buffered_write_stream.hpp | 26 asio/asio/buffered_write_stream_fwd.hpp | 2 asio/asio/buffers_iterator.hpp | 82 asio/asio/co_spawn.hpp | 88 asio/asio/completion_condition.hpp | 2 asio/asio/compose.hpp | 136 asio/asio/connect.hpp | 710 +++- asio/asio/coroutine.hpp | 14 asio/asio/datagram_socket_service.hpp | 432 -- asio/asio/deadline_timer.hpp | 2 asio/asio/deadline_timer_service.hpp | 171 - asio/asio/defer.hpp | 117 asio/asio/detached.hpp | 62 asio/asio/detail/addressof.hpp | 38 asio/asio/detail/array.hpp | 2 asio/asio/detail/array_fwd.hpp | 2 asio/asio/detail/assert.hpp | 2 asio/asio/detail/atomic_count.hpp | 2 asio/asio/detail/base_from_completion_cond.hpp | 7 asio/asio/detail/bind_handler.hpp | 481 ++- asio/asio/detail/buffer_resize_guard.hpp | 2 asio/asio/detail/buffer_sequence_adapter.hpp | 263 + asio/asio/detail/buffered_stream_storage.hpp | 2 asio/asio/detail/call_stack.hpp | 4 asio/asio/detail/chrono.hpp | 66 asio/asio/detail/chrono_time_traits.hpp | 2 asio/asio/detail/completion_handler.hpp | 14 asio/asio/detail/concurrency_hint.hpp | 94 asio/asio/detail/conditionally_enabled_event.hpp | 112 asio/asio/detail/conditionally_enabled_mutex.hpp | 149 asio/asio/detail/config.hpp | 506 +++ asio/asio/detail/consuming_buffers.hpp | 452 +- asio/asio/detail/cstddef.hpp | 31 asio/asio/detail/cstdint.hpp | 16 asio/asio/detail/date_time_fwd.hpp | 2 asio/asio/detail/deadline_timer_service.hpp | 89 asio/asio/detail/dependent_type.hpp | 2 asio/asio/detail/descriptor_ops.hpp | 6 asio/asio/detail/descriptor_read_op.hpp | 35 asio/asio/detail/descriptor_write_op.hpp | 35 asio/asio/detail/dev_poll_reactor.hpp | 42 asio/asio/detail/epoll_reactor.hpp | 58 asio/asio/detail/event.hpp | 2 asio/asio/detail/eventfd_select_interrupter.hpp | 2 asio/asio/detail/executor_function.hpp | 104 asio/asio/detail/executor_op.hpp | 84 asio/asio/detail/fd_set_adapter.hpp | 2 asio/asio/detail/fenced_block.hpp | 6 asio/asio/detail/function.hpp | 38 asio/asio/detail/functional.hpp | 38 asio/asio/detail/future.hpp | 33 asio/asio/detail/gcc_arm_fenced_block.hpp | 4 asio/asio/detail/gcc_hppa_fenced_block.hpp | 4 asio/asio/detail/gcc_sync_fenced_block.hpp | 4 asio/asio/detail/gcc_x86_fenced_block.hpp | 4 asio/asio/detail/global.hpp | 52 asio/asio/detail/handler_alloc_helpers.hpp | 166 + asio/asio/detail/handler_cont_helpers.hpp | 4 asio/asio/detail/handler_invoke_helpers.hpp | 4 asio/asio/detail/handler_tracking.hpp | 97 asio/asio/detail/handler_type_requirements.hpp | 176 - asio/asio/detail/handler_work.hpp | 113 asio/asio/detail/hash_map.hpp | 8 asio/asio/detail/impl/buffer_sequence_adapter.ipp | 12 asio/asio/detail/impl/descriptor_ops.ipp | 25 asio/asio/detail/impl/dev_poll_reactor.hpp | 21 asio/asio/detail/impl/dev_poll_reactor.ipp | 52 asio/asio/detail/impl/epoll_reactor.hpp | 21 asio/asio/detail/impl/epoll_reactor.ipp | 223 + asio/asio/detail/impl/eventfd_select_interrupter.ipp | 2 asio/asio/detail/impl/handler_tracking.ipp | 107 asio/asio/detail/impl/kqueue_reactor.hpp | 25 asio/asio/detail/impl/kqueue_reactor.ipp | 116 asio/asio/detail/impl/null_event.ipp | 74 asio/asio/detail/impl/pipe_select_interrupter.ipp | 2 asio/asio/detail/impl/posix_event.ipp | 14 asio/asio/detail/impl/posix_mutex.ipp | 2 asio/asio/detail/impl/posix_thread.ipp | 12 asio/asio/detail/impl/posix_tss_ptr.ipp | 2 asio/asio/detail/impl/reactive_descriptor_service.ipp | 40 asio/asio/detail/impl/reactive_serial_port_service.ipp | 13 asio/asio/detail/impl/reactive_socket_service_base.ipp | 52 asio/asio/detail/impl/resolver_service_base.ipp | 94 asio/asio/detail/impl/scheduler.ipp | 617 +++ asio/asio/detail/impl/select_reactor.hpp | 21 asio/asio/detail/impl/select_reactor.ipp | 72 asio/asio/detail/impl/service_registry.hpp | 66 asio/asio/detail/impl/service_registry.ipp | 69 asio/asio/detail/impl/signal_set_service.ipp | 64 asio/asio/detail/impl/socket_ops.ipp | 191 + asio/asio/detail/impl/socket_select_interrupter.ipp | 2 asio/asio/detail/impl/strand_executor_service.hpp | 179 + asio/asio/detail/impl/strand_executor_service.ipp | 134 asio/asio/detail/impl/strand_service.hpp | 26 asio/asio/detail/impl/strand_service.ipp | 29 asio/asio/detail/impl/task_io_service.hpp | 78 asio/asio/detail/impl/task_io_service.ipp | 474 --- asio/asio/detail/impl/throw_error.ipp | 2 asio/asio/detail/impl/timer_queue_ptime.ipp | 17 asio/asio/detail/impl/timer_queue_set.ipp | 2 asio/asio/detail/impl/win_event.ipp | 7 asio/asio/detail/impl/win_iocp_handle_service.ipp | 50 asio/asio/detail/impl/win_iocp_io_context.hpp | 103 asio/asio/detail/impl/win_iocp_io_context.ipp | 593 +++ asio/asio/detail/impl/win_iocp_io_service.hpp | 130 asio/asio/detail/impl/win_iocp_io_service.ipp | 538 --- asio/asio/detail/impl/win_iocp_serial_port_service.ipp | 24 asio/asio/detail/impl/win_iocp_socket_service_base.ipp | 114 asio/asio/detail/impl/win_mutex.ipp | 7 asio/asio/detail/impl/win_object_handle_service.ipp | 39 asio/asio/detail/impl/win_static_mutex.ipp | 2 asio/asio/detail/impl/win_thread.ipp | 9 asio/asio/detail/impl/win_tss_ptr.ipp | 6 asio/asio/detail/impl/winrt_ssocket_service_base.ipp | 57 asio/asio/detail/impl/winrt_timer_scheduler.hpp | 21 asio/asio/detail/impl/winrt_timer_scheduler.ipp | 19 asio/asio/detail/impl/winsock_init.ipp | 2 asio/asio/detail/io_control.hpp | 52 asio/asio/detail/io_object_executor.hpp | 167 + asio/asio/detail/io_object_impl.hpp | 193 + asio/asio/detail/is_buffer_sequence.hpp | 312 ++ asio/asio/detail/is_executor.hpp | 126 asio/asio/detail/keyword_tss_ptr.hpp | 2 asio/asio/detail/kqueue_reactor.hpp | 50 asio/asio/detail/local_free_on_block_exit.hpp | 2 asio/asio/detail/macos_fenced_block.hpp | 3 asio/asio/detail/memory.hpp | 70 asio/asio/detail/mutex.hpp | 2 asio/asio/detail/non_const_lvalue.hpp | 54 asio/asio/detail/noncopyable.hpp | 2 asio/asio/detail/null_event.hpp | 22 asio/asio/detail/null_fenced_block.hpp | 4 asio/asio/detail/null_global.hpp | 59 asio/asio/detail/null_mutex.hpp | 2 asio/asio/detail/null_reactor.hpp | 19 asio/asio/detail/null_signal_blocker.hpp | 2 asio/asio/detail/null_socket_service.hpp | 126 asio/asio/detail/null_static_mutex.hpp | 2 asio/asio/detail/null_thread.hpp | 8 asio/asio/detail/null_tss_ptr.hpp | 2 asio/asio/detail/object_pool.hpp | 27 asio/asio/detail/old_win_sdk_compat.hpp | 2 asio/asio/detail/op_queue.hpp | 8 asio/asio/detail/operation.hpp | 6 asio/asio/detail/pipe_select_interrupter.hpp | 2 asio/asio/detail/pop_options.hpp | 18 asio/asio/detail/posix_event.hpp | 38 asio/asio/detail/posix_fd_set_adapter.hpp | 2 asio/asio/detail/posix_global.hpp | 80 asio/asio/detail/posix_mutex.hpp | 2 asio/asio/detail/posix_signal_blocker.hpp | 2 asio/asio/detail/posix_static_mutex.hpp | 2 asio/asio/detail/posix_thread.hpp | 6 asio/asio/detail/posix_tss_ptr.hpp | 2 asio/asio/detail/push_options.hpp | 23 asio/asio/detail/reactive_descriptor_service.hpp | 143 asio/asio/detail/reactive_null_buffers_op.hpp | 24 asio/asio/detail/reactive_serial_port_service.hpp | 34 asio/asio/detail/reactive_socket_accept_op.hpp | 140 asio/asio/detail/reactive_socket_connect_op.hpp | 30 asio/asio/detail/reactive_socket_recv_op.hpp | 40 asio/asio/detail/reactive_socket_recvfrom_op.hpp | 31 asio/asio/detail/reactive_socket_recvmsg_op.hpp | 32 asio/asio/detail/reactive_socket_send_op.hpp | 46 asio/asio/detail/reactive_socket_sendto_op.hpp | 33 asio/asio/detail/reactive_socket_service.hpp | 164 - asio/asio/detail/reactive_socket_service_base.hpp | 194 - asio/asio/detail/reactive_wait_op.hpp | 92 asio/asio/detail/reactor.hpp | 4 asio/asio/detail/reactor_fwd.hpp | 4 asio/asio/detail/reactor_op.hpp | 10 asio/asio/detail/reactor_op_queue.hpp | 2 asio/asio/detail/recycling_allocator.hpp | 106 asio/asio/detail/regex_fwd.hpp | 2 asio/asio/detail/resolve_endpoint_op.hpp | 67 asio/asio/detail/resolve_op.hpp | 98 asio/asio/detail/resolve_query_op.hpp | 148 asio/asio/detail/resolver_service.hpp | 74 asio/asio/detail/resolver_service_base.hpp | 58 asio/asio/detail/scheduler.hpp | 224 + asio/asio/detail/scheduler_operation.hpp | 78 asio/asio/detail/scheduler_thread_info.hpp | 40 asio/asio/detail/scoped_lock.hpp | 2 asio/asio/detail/scoped_ptr.hpp | 10 asio/asio/detail/select_interrupter.hpp | 2 asio/asio/detail/select_reactor.hpp | 55 asio/asio/detail/service_registry.hpp | 88 asio/asio/detail/shared_ptr.hpp | 38 asio/asio/detail/signal_blocker.hpp | 2 asio/asio/detail/signal_handler.hpp | 22 asio/asio/detail/signal_init.hpp | 2 asio/asio/detail/signal_op.hpp | 2 asio/asio/detail/signal_set_service.hpp | 47 asio/asio/detail/socket_holder.hpp | 2 asio/asio/detail/socket_ops.hpp | 15 asio/asio/detail/socket_option.hpp | 2 asio/asio/detail/socket_select_interrupter.hpp | 2 asio/asio/detail/socket_types.hpp | 16 asio/asio/detail/solaris_fenced_block.hpp | 3 asio/asio/detail/static_mutex.hpp | 2 asio/asio/detail/std_event.hpp | 2 asio/asio/detail/std_fenced_block.hpp | 62 asio/asio/detail/std_global.hpp | 70 asio/asio/detail/std_mutex.hpp | 2 asio/asio/detail/std_static_mutex.hpp | 2 asio/asio/detail/std_thread.hpp | 8 asio/asio/detail/strand_executor_service.hpp | 142 asio/asio/detail/strand_service.hpp | 20 asio/asio/detail/string_view.hpp | 47 asio/asio/detail/task_io_service.hpp | 201 - asio/asio/detail/task_io_service_operation.hpp | 76 asio/asio/detail/task_io_service_thread_info.hpp | 40 asio/asio/detail/thread.hpp | 14 asio/asio/detail/thread_context.hpp | 42 asio/asio/detail/thread_group.hpp | 95 asio/asio/detail/thread_info_base.hpp | 65 asio/asio/detail/throw_error.hpp | 2 asio/asio/detail/throw_exception.hpp | 2 asio/asio/detail/timer_queue.hpp | 33 asio/asio/detail/timer_queue_base.hpp | 2 asio/asio/detail/timer_queue_ptime.hpp | 16 asio/asio/detail/timer_queue_set.hpp | 2 asio/asio/detail/timer_scheduler.hpp | 4 asio/asio/detail/timer_scheduler_fwd.hpp | 4 asio/asio/detail/tss_ptr.hpp | 2 asio/asio/detail/type_traits.hpp | 30 asio/asio/detail/variadic_templates.hpp | 114 asio/asio/detail/wait_handler.hpp | 22 asio/asio/detail/wait_op.hpp | 2 asio/asio/detail/weak_ptr.hpp | 38 asio/asio/detail/win_event.hpp | 23 asio/asio/detail/win_fd_set_adapter.hpp | 2 asio/asio/detail/win_fenced_block.hpp | 3 asio/asio/detail/win_global.hpp | 71 asio/asio/detail/win_iocp_handle_read_op.hpp | 22 asio/asio/detail/win_iocp_handle_service.hpp | 105 asio/asio/detail/win_iocp_handle_write_op.hpp | 21 asio/asio/detail/win_iocp_io_context.hpp | 338 ++ asio/asio/detail/win_iocp_io_service.hpp | 315 -- asio/asio/detail/win_iocp_null_buffers_op.hpp | 24 asio/asio/detail/win_iocp_operation.hpp | 15 asio/asio/detail/win_iocp_overlapped_op.hpp | 20 asio/asio/detail/win_iocp_overlapped_ptr.hpp | 53 asio/asio/detail/win_iocp_serial_port_service.hpp | 34 asio/asio/detail/win_iocp_socket_accept_op.hpp | 157 - asio/asio/detail/win_iocp_socket_connect_op.hpp | 26 asio/asio/detail/win_iocp_socket_recv_op.hpp | 21 asio/asio/detail/win_iocp_socket_recvfrom_op.hpp | 22 asio/asio/detail/win_iocp_socket_recvmsg_op.hpp | 21 asio/asio/detail/win_iocp_socket_send_op.hpp | 21 asio/asio/detail/win_iocp_socket_service.hpp | 174 - asio/asio/detail/win_iocp_socket_service_base.hpp | 224 - asio/asio/detail/win_iocp_thread_info.hpp | 2 asio/asio/detail/win_iocp_wait_op.hpp | 123 asio/asio/detail/win_mutex.hpp | 2 asio/asio/detail/win_object_handle_service.hpp | 44 asio/asio/detail/win_static_mutex.hpp | 2 asio/asio/detail/win_thread.hpp | 6 asio/asio/detail/win_tss_ptr.hpp | 2 asio/asio/detail/winapp_thread.hpp | 124 asio/asio/detail/wince_thread.hpp | 16 asio/asio/detail/winrt_async_manager.hpp | 41 asio/asio/detail/winrt_async_op.hpp | 2 asio/asio/detail/winrt_resolve_op.hpp | 36 asio/asio/detail/winrt_resolver_service.hpp | 95 asio/asio/detail/winrt_socket_connect_op.hpp | 22 asio/asio/detail/winrt_socket_recv_op.hpp | 21 asio/asio/detail/winrt_socket_send_op.hpp | 21 asio/asio/detail/winrt_ssocket_service.hpp | 42 asio/asio/detail/winrt_ssocket_service_base.hpp | 83 asio/asio/detail/winrt_timer_scheduler.hpp | 34 asio/asio/detail/winrt_utils.hpp | 8 asio/asio/detail/winsock_init.hpp | 2 asio/asio/detail/work_dispatcher.hpp | 73 asio/asio/detail/wrapped_handler.hpp | 2 asio/asio/dispatch.hpp | 108 asio/asio/error.hpp | 30 asio/asio/error_code.hpp | 16 asio/asio/execution_context.hpp | 412 ++ asio/asio/executor.hpp | 341 ++ asio/asio/executor_work_guard.hpp | 170 + asio/asio/generic/basic_endpoint.hpp | 2 asio/asio/generic/datagram_protocol.hpp | 2 asio/asio/generic/detail/endpoint.hpp | 2 asio/asio/generic/detail/impl/endpoint.ipp | 5 asio/asio/generic/raw_protocol.hpp | 2 asio/asio/generic/seq_packet_protocol.hpp | 2 asio/asio/generic/stream_protocol.hpp | 2 asio/asio/handler_alloc_hook.hpp | 2 asio/asio/handler_continuation_hook.hpp | 2 asio/asio/handler_invoke_hook.hpp | 8 asio/asio/handler_type.hpp | 112 asio/asio/high_resolution_timer.hpp | 27 asio/asio/impl/awaitable.hpp | 422 ++ asio/asio/impl/buffered_read_stream.hpp | 186 - asio/asio/impl/buffered_write_stream.hpp | 188 - asio/asio/impl/co_spawn.hpp | 138 asio/asio/impl/compose.hpp | 419 ++ asio/asio/impl/connect.hpp | 720 +++- asio/asio/impl/defer.hpp | 91 asio/asio/impl/detached.hpp | 130 asio/asio/impl/dispatch.hpp | 91 asio/asio/impl/error.ipp | 2 asio/asio/impl/error_code.ipp | 84 asio/asio/impl/execution_context.hpp | 109 asio/asio/impl/execution_context.ipp | 82 asio/asio/impl/executor.hpp | 387 ++ asio/asio/impl/executor.ipp | 38 asio/asio/impl/handler_alloc_hook.ipp | 39 asio/asio/impl/io_context.hpp | 353 ++ asio/asio/impl/io_context.ipp | 175 + asio/asio/impl/io_service.hpp | 152 asio/asio/impl/io_service.ipp | 155 - asio/asio/impl/post.hpp | 91 asio/asio/impl/read.hpp | 988 ++++-- asio/asio/impl/read_at.hpp | 621 +--- asio/asio/impl/read_until.hpp | 2475 +++++++++++++-- asio/asio/impl/redirect_error.hpp | 372 ++ asio/asio/impl/serial_port_base.hpp | 2 asio/asio/impl/serial_port_base.ipp | 60 asio/asio/impl/spawn.hpp | 309 + asio/asio/impl/src.cpp | 2 asio/asio/impl/src.hpp | 16 asio/asio/impl/system_context.hpp | 34 asio/asio/impl/system_context.ipp | 80 asio/asio/impl/system_executor.hpp | 85 asio/asio/impl/thread_pool.hpp | 127 asio/asio/impl/thread_pool.ipp | 87 asio/asio/impl/use_awaitable.hpp | 276 + asio/asio/impl/use_future.hpp | 895 +++++ asio/asio/impl/write.hpp | 1083 ++++-- asio/asio/impl/write_at.hpp | 685 +--- asio/asio/io_context.hpp | 872 +++++ asio/asio/io_context_strand.hpp | 374 ++ asio/asio/io_service.hpp | 749 ---- asio/asio/io_service_strand.hpp | 20 asio/asio/ip/address.hpp | 146 asio/asio/ip/address_v4.hpp | 180 - asio/asio/ip/address_v4_iterator.hpp | 162 + asio/asio/ip/address_v4_range.hpp | 134 asio/asio/ip/address_v6.hpp | 185 - asio/asio/ip/address_v6_iterator.hpp | 183 + asio/asio/ip/address_v6_range.hpp | 129 asio/asio/ip/bad_address_cast.hpp | 53 asio/asio/ip/basic_endpoint.hpp | 55 asio/asio/ip/basic_resolver.hpp | 880 +++++ asio/asio/ip/basic_resolver_entry.hpp | 27 asio/asio/ip/basic_resolver_iterator.hpp | 136 asio/asio/ip/basic_resolver_query.hpp | 2 asio/asio/ip/basic_resolver_results.hpp | 311 ++ asio/asio/ip/detail/endpoint.hpp | 42 asio/asio/ip/detail/impl/endpoint.ipp | 47 asio/asio/ip/detail/socket_option.hpp | 35 asio/asio/ip/host_name.hpp | 2 asio/asio/ip/icmp.hpp | 2 asio/asio/ip/impl/address.hpp | 42 asio/asio/ip/impl/address.ipp | 135 asio/asio/ip/impl/address_v4.hpp | 42 asio/asio/ip/impl/address_v4.ipp | 128 asio/asio/ip/impl/address_v6.hpp | 42 asio/asio/ip/impl/address_v6.ipp | 158 - asio/asio/ip/impl/basic_endpoint.hpp | 16 asio/asio/ip/impl/host_name.ipp | 2 asio/asio/ip/impl/network_v4.hpp | 54 asio/asio/ip/impl/network_v4.ipp | 216 + asio/asio/ip/impl/network_v6.hpp | 53 asio/asio/ip/impl/network_v6.ipp | 185 + asio/asio/ip/multicast.hpp | 16 asio/asio/ip/network_v4.hpp | 261 + asio/asio/ip/network_v6.hpp | 235 + asio/asio/ip/resolver_base.hpp | 129 asio/asio/ip/resolver_query_base.hpp | 93 asio/asio/ip/resolver_service.hpp | 176 - asio/asio/ip/tcp.hpp | 6 asio/asio/ip/udp.hpp | 2 asio/asio/ip/unicast.hpp | 6 asio/asio/ip/v6_only.hpp | 6 asio/asio/is_executor.hpp | 46 asio/asio/is_read_buffered.hpp | 2 asio/asio/is_write_buffered.hpp | 2 asio/asio/local/basic_endpoint.hpp | 10 asio/asio/local/connect_pair.hpp | 49 asio/asio/local/datagram_protocol.hpp | 2 asio/asio/local/detail/endpoint.hpp | 8 asio/asio/local/detail/impl/endpoint.ipp | 12 asio/asio/local/stream_protocol.hpp | 2 asio/asio/packaged_task.hpp | 126 asio/asio/placeholders.hpp | 32 asio/asio/posix/basic_descriptor.hpp | 328 +- asio/asio/posix/basic_stream_descriptor.hpp | 190 - asio/asio/posix/descriptor.hpp | 37 asio/asio/posix/descriptor_base.hpp | 41 asio/asio/posix/stream_descriptor.hpp | 2 asio/asio/posix/stream_descriptor_service.hpp | 260 - asio/asio/post.hpp | 113 asio/asio/raw_socket_service.hpp | 432 -- asio/asio/read.hpp | 660 ++++ asio/asio/read_at.hpp | 43 asio/asio/read_until.hpp | 1954 ++++++++++++ asio/asio/redirect_error.hpp | 66 asio/asio/seq_packet_socket_service.hpp | 380 -- asio/asio/serial_port.hpp | 2 asio/asio/serial_port_base.hpp | 22 asio/asio/serial_port_service.hpp | 253 - asio/asio/signal_set.hpp | 2 asio/asio/signal_set_service.hpp | 134 asio/asio/socket_acceptor_service.hpp | 302 - asio/asio/socket_base.hpp | 131 asio/asio/spawn.hpp | 107 asio/asio/ssl.hpp | 5 asio/asio/ssl/basic_context.hpp | 40 asio/asio/ssl/context.hpp | 95 asio/asio/ssl/context_base.hpp | 30 asio/asio/ssl/context_service.hpp | 40 asio/asio/ssl/detail/buffered_handshake_op.hpp | 50 asio/asio/ssl/detail/engine.hpp | 24 asio/asio/ssl/detail/handshake_op.hpp | 10 asio/asio/ssl/detail/impl/engine.ipp | 73 asio/asio/ssl/detail/impl/openssl_init.ipp | 12 asio/asio/ssl/detail/io.hpp | 72 asio/asio/ssl/detail/openssl_init.hpp | 4 asio/asio/ssl/detail/openssl_types.hpp | 7 asio/asio/ssl/detail/password_callback.hpp | 14 asio/asio/ssl/detail/read_op.hpp | 12 asio/asio/ssl/detail/shutdown_op.hpp | 22 asio/asio/ssl/detail/stream_core.hpp | 47 asio/asio/ssl/detail/verify_callback.hpp | 10 asio/asio/ssl/detail/write_op.hpp | 12 asio/asio/ssl/error.hpp | 35 asio/asio/ssl/impl/context.hpp | 20 asio/asio/ssl/impl/context.ipp | 449 +- asio/asio/ssl/impl/error.ipp | 4 asio/asio/ssl/impl/rfc2818_verification.ipp | 20 asio/asio/ssl/impl/src.hpp | 2 asio/asio/ssl/old/basic_context.hpp | 434 -- asio/asio/ssl/old/context_service.hpp | 174 - asio/asio/ssl/old/detail/openssl_context_service.hpp | 394 -- asio/asio/ssl/old/detail/openssl_operation.hpp | 524 --- asio/asio/ssl/old/detail/openssl_stream_service.hpp | 571 --- asio/asio/ssl/old/stream.hpp | 501 --- asio/asio/ssl/old/stream_service.hpp | 184 - asio/asio/ssl/rfc2818_verification.hpp | 20 asio/asio/ssl/stream.hpp | 286 + asio/asio/ssl/stream_base.hpp | 2 asio/asio/ssl/stream_service.hpp | 40 asio/asio/ssl/verify_context.hpp | 12 asio/asio/ssl/verify_mode.hpp | 2 asio/asio/steady_timer.hpp | 27 asio/asio/strand.hpp | 409 +- asio/asio/stream_socket_service.hpp | 376 -- asio/asio/streambuf.hpp | 2 asio/asio/system_context.hpp | 81 asio/asio/system_error.hpp | 2 asio/asio/system_executor.hpp | 129 asio/asio/system_timer.hpp | 23 asio/asio/this_coro.hpp | 45 asio/asio/thread.hpp | 8 asio/asio/thread_pool.hpp | 235 + asio/asio/time_traits.hpp | 2 asio/asio/ts/buffer.hpp | 24 asio/asio/ts/executor.hpp | 34 asio/asio/ts/internet.hpp | 40 asio/asio/ts/io_context.hpp | 20 asio/asio/ts/net.hpp | 26 asio/asio/ts/netfwd.hpp | 203 + asio/asio/ts/socket.hpp | 27 asio/asio/ts/timer.hpp | 26 asio/asio/unyield.hpp | 2 asio/asio/use_awaitable.hpp | 71 asio/asio/use_future.hpp | 74 asio/asio/uses_executor.hpp | 71 asio/asio/version.hpp | 4 asio/asio/wait_traits.hpp | 19 asio/asio/waitable_timer_service.hpp | 168 - asio/asio/windows/basic_handle.hpp | 281 - asio/asio/windows/basic_object_handle.hpp | 288 + asio/asio/windows/basic_overlapped_handle.hpp | 353 ++ asio/asio/windows/basic_random_access_handle.hpp | 165 - asio/asio/windows/basic_stream_handle.hpp | 168 - asio/asio/windows/object_handle.hpp | 2 asio/asio/windows/object_handle_service.hpp | 177 - asio/asio/windows/overlapped_handle.hpp | 39 asio/asio/windows/overlapped_ptr.hpp | 47 asio/asio/windows/random_access_handle.hpp | 2 asio/asio/windows/random_access_handle_service.hpp | 220 - asio/asio/windows/stream_handle.hpp | 2 asio/asio/windows/stream_handle_service.hpp | 218 - asio/asio/write.hpp | 645 ++++ asio/asio/write_at.hpp | 43 asio/asio/yield.hpp | 2 cmake/asio.cmake | 4 debian/changelog | 19 debian/galera-arbitrator-4.garb.default | 4 debian/galera-arbitrator-4.garb.init | 1 debian/patches/series | 1 debian/patches/small_gcache_size_for_salsa.patch | 25 debian/salsa-ci.yml | 14 galera/src/CMakeLists.txt | 1 galera/src/SConscript | 1 galera/src/certification.cpp | 9 galera/src/event_service.cpp | 48 galera/src/event_service.hpp | 54 galera/src/galera-sym.map | 2 galera/src/ist.cpp | 10 galera/src/progress_callback.hpp | 4 galera/src/replicator.cpp | 2 galera/src/replicator_smm.cpp | 2 galera/src/replicator_smm_params.cpp | 9 galera/src/wsrep_provider.cpp | 121 galera/tests/progress_check.cpp | 4 galerautils/src/CMakeLists.txt | 1 galerautils/src/SConscript | 1 galerautils/src/gu_asio.cpp | 65 galerautils/src/gu_asio.hpp | 6 galerautils/src/gu_asio_datagram.cpp | 2 galerautils/src/gu_asio_socket_util.hpp | 2 galerautils/src/gu_asio_stream_react.cpp | 175 - galerautils/src/gu_asio_stream_react.hpp | 7 galerautils/src/gu_asio_utils.hpp | 12 galerautils/src/gu_config.cpp | 30 galerautils/src/gu_config.h | 4 galerautils/src/gu_config.hpp | 108 galerautils/src/gu_datetime.cpp | 263 + galerautils/src/gu_datetime.hpp | 29 galerautils/src/gu_event_service.cpp | 48 galerautils/src/gu_event_service.hpp | 54 galerautils/src/gu_utils.hpp | 12 galerautils/tests/CMakeLists.txt | 1 galerautils/tests/SConscript | 1 galerautils/tests/gu_asio_test.cpp | 174 - galerautils/tests/gu_datetime_test.cpp | 85 galerautils/tests/gu_tests++.hpp | 2 galerautils/tests/gu_utils_test++.cpp | 71 galerautils/tests/gu_utils_test++.hpp | 10 garb/files/freebsd/garb.sh | 2 garb/files/garb-systemd | 1 garb/files/garb.cnf | 4 garb/files/garb.sh | 1 garb/garb_config.cpp | 11 garb/garb_config.hpp | 2 garb/garb_main.cpp | 26 garb/garb_recv_loop.hpp | 3 gcache/src/gcache_params.cpp | 21 gcomm/src/conf.cpp | 11 gcomm/src/defaults.cpp | 5 gcomm/src/defaults.hpp | 85 gcomm/src/evs_proto.cpp | 1 gcomm/src/gmcast_proto.cpp | 12 gcomm/src/pc_proto.cpp | 1 gcomm/src/view.cpp | 13 gcomm/test/check_trace.cpp | 1 gcomm/test/ssl_test.cpp | 1 gcs/src/gcs.cpp | 2 gcs/src/gcs_gcomm.cpp | 1 gcs/src/gcs_group.cpp | 4 gcs/src/gcs_params.cpp | 54 gcs/src/gcs_params.hpp | 2 gcs/src/unit_tests/gcs_core_test.cpp | 46 gcs/src/unit_tests/gcs_memb_test.cpp | 6 scripts/packages/codership-galera.spec | 375 ++ tests/scripts/action.sh | 18 wsrep/src/wsrep_config_service.h | 116 594 files changed, 44868 insertions(+), 20467 deletions(-) diff -Nru galera-4-26.4.11/.clang-format galera-4-26.4.14/.clang-format --- galera-4-26.4.11/.clang-format 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/.clang-format 2023-02-24 08:38:48.000000000 +0000 @@ -0,0 +1,58 @@ +--- +Language: Cpp +# BasedOnStyle: WebKit +AccessModifierOffset: -4 +ConstructorInitializerIndentWidth: 4 +AlignEscapedNewlinesLeft: false +AlignTrailingComments: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AlwaysBreakTemplateDeclarations: false +AlwaysBreakBeforeMultilineStrings: false +BreakBeforeBinaryOperators: true +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BinPackParameters: true +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: false +DerivePointerAlignment: false +ExperimentalAutoDetectBinPacking: false +IndentCaseLabels: false +IndentWrappedFunctionNames: false +IndentFunctionDeclarationAfterType: false +MaxEmptyLinesToKeep: 1 +KeepEmptyLinesAtTheStartOfBlocks: true +NamespaceIndentation: All +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakString: 1000 +PenaltyBreakFirstLessLess: 120 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +SpacesBeforeTrailingComments: 1 +Cpp11BracedListStyle: false +Standard: Cpp11 +IndentWidth: 4 +TabWidth: 8 +UseTab: Never +BreakBeforeBraces: Allman +SpacesInParentheses: false +SpacesInAngles: false +SpaceInEmptyParentheses: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: true +SpaceBeforeAssignmentOperators: true +ContinuationIndentWidth: 4 +CommentPragmas: '^ IWYU pragma:' +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +SpaceBeforeParens: ControlStatements +DisableFormat: false +... + diff -Nru galera-4-26.4.11/DartConfiguration.tcl galera-4-26.4.14/DartConfiguration.tcl --- galera-4-26.4.11/DartConfiguration.tcl 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/DartConfiguration.tcl 2023-02-24 08:38:51.000000000 +0000 @@ -0,0 +1,115 @@ +# This file is configured by CMake automatically as DartConfiguration.tcl +# If you choose not to use CMake, this file may be hand configured, by +# filling in the required variables. + + +# Configuration directories and files +SourceDirectory: /var/lib/jenkins/workspace/aws-galera-4-sourcetar +BuildDirectory: /var/lib/jenkins/workspace/aws-galera-4-sourcetar + +# Where to place the cost data store +CostDataFile: + +# Site is something like machine.domain, i.e. pragmatic.crd +Site: master + +# Build name is osname-revision-compiler, i.e. Linux-2.4.2-2smp-c++ +BuildName: Linux-c++ + +# Subprojects +LabelsForSubprojects: + +# Submission information +IsCDash: +CDashVersion: +QueryCDashVersion: +DropSite: +DropLocation: +DropSiteUser: +DropSitePassword: +DropSiteMode: +DropMethod: http +TriggerSite: +ScpCommand: /usr/bin/scp + +# Dashboard start time +NightlyStartTime: 00:00:00 EDT + +# Commands for the build/test/submit cycle +ConfigureCommand: "/usr/bin/cmake" "/var/lib/jenkins/workspace/aws-galera-4-sourcetar" +MakeCommand: /usr/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}" -- -i +DefaultCTestConfigurationType: Release + +# version control +UpdateVersionOnly: + +# CVS options +# Default is "-d -P -A" +CVSCommand: CVSCOMMAND-NOTFOUND +CVSUpdateOptions: -d -A -P + +# Subversion options +SVNCommand: /usr/bin/svn +SVNOptions: +SVNUpdateOptions: + +# Git options +GITCommand: /usr/bin/git +GITInitSubmodules: +GITUpdateOptions: +GITUpdateCustom: + +# Perforce options +P4Command: P4COMMAND-NOTFOUND +P4Client: +P4Options: +P4UpdateOptions: +P4UpdateCustom: + +# Generic update command +UpdateCommand: /usr/bin/git +UpdateOptions: +UpdateType: git + +# Compiler info +Compiler: /usr/bin/c++ +CompilerVersion: 7.5.0 + +# Dynamic analysis (MemCheck) +PurifyCommand: +ValgrindCommand: +ValgrindCommandOptions: +MemoryCheckType: +MemoryCheckSanitizerOptions: +MemoryCheckCommand: /usr/bin/valgrind +MemoryCheckCommandOptions: +MemoryCheckSuppressionFile: + +# Coverage +CoverageCommand: /usr/bin/gcov +CoverageExtraFlags: -l + +# Cluster commands +SlurmBatchCommand: SLURM_SBATCH_COMMAND-NOTFOUND +SlurmRunCommand: SLURM_SRUN_COMMAND-NOTFOUND + +# Testing options +# TimeOut is the amount of time in seconds to wait for processes +# to complete during testing. After TimeOut seconds, the +# process will be summarily terminated. +# Currently set to 25 minutes +TimeOut: 1500 + +# During parallel testing CTest will not start a new test if doing +# so would cause the system load to exceed this value. +TestLoad: + +UseLaunchers: +CurlOptions: +# warning, if you add new options here that have to do with submit, +# you have to update cmCTestSubmitCommand.cxx + +# For CTest submissions that timeout, these options +# specify behavior for retrying the submission +CTestSubmitRetryDelay: 5 +CTestSubmitRetryCount: 3 diff -Nru galera-4-26.4.11/GALERA_GIT_REVISION galera-4-26.4.14/GALERA_GIT_REVISION --- galera-4-26.4.11/GALERA_GIT_REVISION 2022-02-09 11:02:13.000000000 +0000 +++ galera-4-26.4.14/GALERA_GIT_REVISION 2023-02-24 08:38:50.000000000 +0000 @@ -1 +1 @@ -7b59af73 \ No newline at end of file +456ad404 \ No newline at end of file diff -Nru galera-4-26.4.11/GALERA_REVISION galera-4-26.4.14/GALERA_REVISION --- galera-4-26.4.11/GALERA_REVISION 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/GALERA_REVISION 2023-02-24 08:38:50.000000000 +0000 @@ -0,0 +1 @@ +456ad404 \ No newline at end of file diff -Nru galera-4-26.4.11/GALERA_VERSION galera-4-26.4.14/GALERA_VERSION --- galera-4-26.4.11/GALERA_VERSION 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/GALERA_VERSION 2023-02-24 08:38:48.000000000 +0000 @@ -1,4 +1,4 @@ GALERA_VERSION_WSREP_API=26 GALERA_VERSION_MAJOR=4 -GALERA_VERSION_MINOR=11 +GALERA_VERSION_MINOR=14 GALERA_VERSION_EXTRA= diff -Nru galera-4-26.4.11/SConstruct galera-4-26.4.14/SConstruct --- galera-4-26.4.11/SConstruct 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/SConstruct 2023-02-24 08:38:48.000000000 +0000 @@ -163,7 +163,7 @@ install = ARGUMENTS.get('install', None) version_script = int(ARGUMENTS.get('version_script', 1)) -GALERA_VER = ARGUMENTS.get('version', '4.11') +GALERA_VER = ARGUMENTS.get('version', '4.14') GALERA_REV = ARGUMENTS.get('revno', 'XXXX') # Attempt to read from file if not given diff -Nru galera-4-26.4.11/asio/asio/associated_allocator.hpp galera-4-26.4.14/asio/asio/associated_allocator.hpp --- galera-4-26.4.11/asio/asio/associated_allocator.hpp 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/asio/asio/associated_allocator.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -0,0 +1,131 @@ +// +// associated_allocator.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 ASIO_ASSOCIATED_ALLOCATOR_HPP +#define ASIO_ASSOCIATED_ALLOCATOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include +#include "asio/detail/type_traits.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct associated_allocator_check +{ + typedef void type; +}; + +template +struct associated_allocator_impl +{ + typedef E type; + + static type get(const T&, const E& e) ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_allocator_impl::type> +{ + typedef typename T::allocator_type type; + + static type get(const T& t, const E&) ASIO_NOEXCEPT + { + return t.get_allocator(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the allocator associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Allocator shall be a type meeting the Allocator requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c a is an object of type @c + * Allocator. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Allocator requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,a) and with return type @c type. + */ +template > +struct associated_allocator +{ + /// If @c T has a nested type @c allocator_type, T::allocator_type. + /// Otherwise @c Allocator. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_allocator_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c allocator_type, returns + /// t.get_allocator(). Otherwise returns @c a. + static type get(const T& t, + const Allocator& a = Allocator()) ASIO_NOEXCEPT + { + return detail::associated_allocator_impl::get(t, a); + } +}; + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t) ASIO_NOEXCEPT +{ + return associated_allocator::get(t); +} + +/// Helper function to obtain an object's associated allocator. +/** + * @returns associated_allocator::get(t, a) + */ +template +inline typename associated_allocator::type +get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT +{ + return associated_allocator::get(t, a); +} + +#if defined(ASIO_HAS_ALIAS_TEMPLATES) + +template > +using associated_allocator_t + = typename associated_allocator::type; + +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ASSOCIATED_ALLOCATOR_HPP diff -Nru galera-4-26.4.11/asio/asio/associated_executor.hpp galera-4-26.4.14/asio/asio/associated_executor.hpp --- galera-4-26.4.11/asio/asio/associated_executor.hpp 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/asio/asio/associated_executor.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -0,0 +1,149 @@ +// +// associated_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 ASIO_ASSOCIATED_EXECUTOR_HPP +#define ASIO_ASSOCIATED_EXECUTOR_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/is_executor.hpp" +#include "asio/system_executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +template +struct associated_executor_check +{ + typedef void type; +}; + +template +struct associated_executor_impl +{ + typedef E type; + + static type get(const T&, const E& e) ASIO_NOEXCEPT + { + return e; + } +}; + +template +struct associated_executor_impl::type> +{ + typedef typename T::executor_type type; + + static type get(const T& t, const E&) ASIO_NOEXCEPT + { + return t.get_executor(); + } +}; + +} // namespace detail + +/// Traits type used to obtain the executor associated with an object. +/** + * A program may specialise this traits type if the @c T template parameter in + * the specialisation is a user-defined type. The template parameter @c + * Executor shall be a type meeting the Executor requirements. + * + * Specialisations shall meet the following requirements, where @c t is a const + * reference to an object of type @c T, and @c e is an object of type @c + * Executor. + * + * @li Provide a nested typedef @c type that identifies a type meeting the + * Executor requirements. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t) and with return type @c type. + * + * @li Provide a noexcept static member function named @c get, callable as @c + * get(t,e) and with return type @c type. + */ +template +struct associated_executor +{ + /// If @c T has a nested type @c executor_type, T::executor_type. + /// Otherwise @c Executor. +#if defined(GENERATING_DOCUMENTATION) + typedef see_below type; +#else // defined(GENERATING_DOCUMENTATION) + typedef typename detail::associated_executor_impl::type type; +#endif // defined(GENERATING_DOCUMENTATION) + + /// If @c T has a nested type @c executor_type, returns + /// t.get_executor(). Otherwise returns @c ex. + static type get(const T& t, + const Executor& ex = Executor()) ASIO_NOEXCEPT + { + return detail::associated_executor_impl::get(t, ex); + } +}; + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t) ASIO_NOEXCEPT +{ + return associated_executor::get(t); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ex) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, const Executor& ex, + typename enable_if::value>::type* = 0) ASIO_NOEXCEPT +{ + return associated_executor::get(t, ex); +} + +/// Helper function to obtain an object's associated executor. +/** + * @returns associated_executor::get(t, ctx.get_executor()) + */ +template +inline typename associated_executor::type +get_associated_executor(const T& t, ExecutionContext& ctx, + typename enable_if::value>::type* = 0) ASIO_NOEXCEPT +{ + return associated_executor::get(t, ctx.get_executor()); +} + +#if defined(ASIO_HAS_ALIAS_TEMPLATES) + +template +using associated_executor_t = typename associated_executor::type; + +#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#endif // ASIO_ASSOCIATED_EXECUTOR_HPP diff -Nru galera-4-26.4.11/asio/asio/async_result.hpp galera-4-26.4.14/asio/asio/async_result.hpp --- galera-4-26.4.11/asio/asio/async_result.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/async_result.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // async_result.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,7 +16,8 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include "asio/handler_type.hpp" +#include "asio/detail/type_traits.hpp" +#include "asio/detail/variadic_templates.hpp" #include "asio/detail/push_options.hpp" @@ -24,71 +25,332 @@ /// An interface for customising the behaviour of an initiating function. /** - * This template may be specialised for user-defined handler types. + * The async_result traits class is used for determining: + * + * @li the concrete completion handler type to be called at the end of the + * asynchronous operation; + * + * @li the initiating function return type; and + * + * @li how the return value of the initiating function is obtained. + * + * The trait allows the handler and return types 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. + * The primary template assumes that the CompletionToken is the completion + * handler. */ -template +template class async_result { public: + /// The concrete completion handler type for the specific signature. + typedef CompletionToken completion_handler_type; + /// The return type of the initiating function. - typedef void type; + typedef void return_type; /// 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. + * to initialise some state associated with the completion handler, which is + * then returned from the initiating function. */ - explicit async_result(Handler&) + explicit async_result(completion_handler_type& h) { + (void)h; } /// Obtain the value to be returned from the initiating function. - type get() + return_type get() { } -}; -namespace detail { +#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \ + || defined(GENERATING_DOCUMENTATION) + + /// Initiate the asynchronous operation that will produce the result, and + /// obtain the value to be returned from the initiating function. + template + static return_type initiate( + ASIO_MOVE_ARG(Initiation) initiation, + ASIO_MOVE_ARG(RawCompletionToken) token, + ASIO_MOVE_ARG(Args)... args) + { + ASIO_MOVE_CAST(Initiation)(initiation)( + ASIO_MOVE_CAST(RawCompletionToken)(token), + ASIO_MOVE_CAST(Args)(args)...); + } + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) -// Helper template to deduce the true type of a handler, capture a local copy -// of the handler, and then create an async_result for the handler. -template -struct async_result_init + template + static return_type initiate( + ASIO_MOVE_ARG(Initiation) initiation, + ASIO_MOVE_ARG(RawCompletionToken) token) + { + ASIO_MOVE_CAST(Initiation)(initiation)( + ASIO_MOVE_CAST(RawCompletionToken)(token)); + } + +#define ASIO_PRIVATE_INITIATE_DEF(n) \ + template \ + static return_type initiate( \ + ASIO_MOVE_ARG(Initiation) initiation, \ + ASIO_MOVE_ARG(RawCompletionToken) token, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + ASIO_MOVE_CAST(Initiation)(initiation)( \ + ASIO_MOVE_CAST(RawCompletionToken)(token), \ + ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) +#undef ASIO_PRIVATE_INITIATE_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + // || defined(GENERATING_DOCUMENTATION) + +private: + async_result(const async_result&) ASIO_DELETED; + async_result& operator=(const async_result&) 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 +/// handler. +template +struct async_completion { - explicit async_result_init(ASIO_MOVE_ARG(Handler) orig_handler) - : handler(ASIO_MOVE_CAST(Handler)(orig_handler)), - result(handler) + /// The real handler type to be used for the asynchronous operation. + typedef typename asio::async_result< + typename decay::type, + Signature>::completion_handler_type completion_handler_type; + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Constructor. + /** + * The constructor creates the concrete completion handler and makes the link + * between the handler and the asynchronous result. + */ + explicit async_completion(CompletionToken& token) + : completion_handler(static_cast::value, + completion_handler_type&, CompletionToken&&>::type>(token)), + result(completion_handler) + { + } +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + explicit async_completion(typename decay::type& token) + : completion_handler(token), + result(completion_handler) { } - typename handler_type::type handler; - async_result::type> result; + explicit async_completion(const typename decay::type& token) + : completion_handler(token), + result(completion_handler) + { + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// A copy of, or reference to, a real handler object. +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + typename conditional< + is_same::value, + completion_handler_type&, completion_handler_type>::type completion_handler; +#else // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + completion_handler_type completion_handler; +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// The result of the asynchronous operation's initiating function. + async_result::type, Signature> result; }; -template -struct async_result_type_helper +namespace detail { + +template +struct async_result_helper + : async_result::type, Signature> { - typedef typename async_result< - typename handler_type::type - >::type type; }; -} // namespace detail -} // namespace asio +struct async_result_memfns_base +{ + void initiate(); +}; -#include "asio/detail/pop_options.hpp" +template +struct async_result_memfns_derived + : T, async_result_memfns_base +{ +}; + +template +struct async_result_memfns_check +{ +}; + +template +char (&async_result_initiate_memfn_helper(...))[2]; + +template +char async_result_initiate_memfn_helper( + async_result_memfns_check< + void (async_result_memfns_base::*)(), + &async_result_memfns_derived::initiate>*); + +template +struct async_result_has_initiate_memfn + : integral_constant::type, Signature> + >(0)) != 1> +{ +}; + +} // namespace detail #if defined(GENERATING_DOCUMENTATION) -# define ASIO_INITFN_RESULT_TYPE(h, sig) \ +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ void_or_deduced #elif defined(_MSC_VER) && (_MSC_VER < 1500) -# define ASIO_INITFN_RESULT_TYPE(h, sig) \ - typename ::asio::detail::async_result_type_helper::type +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::asio::detail::async_result_helper< \ + ct, sig>::return_type +#define ASIO_HANDLER_TYPE(ct, sig) \ + typename ::asio::detail::async_result_helper< \ + ct, sig>::completion_handler_type #else -# define ASIO_INITFN_RESULT_TYPE(h, sig) \ +# define ASIO_INITFN_RESULT_TYPE(ct, sig) \ + typename ::asio::async_result< \ + typename ::asio::decay::type, sig>::return_type +#define ASIO_HANDLER_TYPE(ct, sig) \ typename ::asio::async_result< \ - typename ::asio::handler_type::type>::type + typename ::asio::decay::type, sig>::completion_handler_type #endif +#if defined(GENERATING_DOCUMENTATION) + +template +ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) +async_initiate(ASIO_MOVE_ARG(Initiation) initiation, + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken), + ASIO_MOVE_ARG(Args)... args); + +#elif defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline typename enable_if< + detail::async_result_has_initiate_memfn::value, + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(ASIO_MOVE_ARG(Initiation) initiation, + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, + ASIO_MOVE_ARG(Args)... args) +{ + return async_result::type, + Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), + ASIO_MOVE_CAST(CompletionToken)(token), + ASIO_MOVE_CAST(Args)(args)...); +} + +template +inline typename enable_if< + !detail::async_result_has_initiate_memfn::value, + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(ASIO_MOVE_ARG(Initiation) initiation, + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, + ASIO_MOVE_ARG(Args)... args) +{ + async_completion completion(token); + + ASIO_MOVE_CAST(Initiation)(initiation)( + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, + Signature))(completion.completion_handler), + ASIO_MOVE_CAST(Args)(args)...); + + return completion.result.get(); +} + +#else // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +template +inline typename enable_if< + detail::async_result_has_initiate_memfn::value, + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(ASIO_MOVE_ARG(Initiation) initiation, + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) +{ + return async_result::type, + Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), + ASIO_MOVE_CAST(CompletionToken)(token)); +} + +template +inline typename enable_if< + !detail::async_result_has_initiate_memfn::value, + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type +async_initiate(ASIO_MOVE_ARG(Initiation) initiation, + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token) +{ + async_completion completion(token); + + ASIO_MOVE_CAST(Initiation)(initiation)( + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, + Signature))(completion.completion_handler)); + + return completion.result.get(); +} + +#define ASIO_PRIVATE_INITIATE_DEF(n) \ + template \ + inline typename enable_if< \ + detail::async_result_has_initiate_memfn< \ + CompletionToken, Signature>::value, \ + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ + async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \ + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + return async_result::type, \ + Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), \ + ASIO_MOVE_CAST(CompletionToken)(token), \ + ASIO_VARIADIC_MOVE_ARGS(n)); \ + } \ + \ + template \ + inline typename enable_if< \ + !detail::async_result_has_initiate_memfn< \ + CompletionToken, Signature>::value, \ + ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type \ + async_initiate(ASIO_MOVE_ARG(Initiation) initiation, \ + ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \ + ASIO_VARIADIC_MOVE_PARAMS(n)) \ + { \ + async_completion completion(token); \ + \ + ASIO_MOVE_CAST(Initiation)(initiation)( \ + ASIO_MOVE_CAST(ASIO_HANDLER_TYPE(CompletionToken, \ + Signature))(completion.completion_handler), \ + ASIO_VARIADIC_MOVE_ARGS(n)); \ + \ + return completion.result.get(); \ + } \ + /**/ + ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_INITIATE_DEF) +#undef ASIO_PRIVATE_INITIATE_DEF + +#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES) + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + #endif // ASIO_ASYNC_RESULT_HPP diff -Nru galera-4-26.4.11/asio/asio/awaitable.hpp galera-4-26.4.14/asio/asio/awaitable.hpp --- galera-4-26.4.11/asio/asio/awaitable.hpp 1970-01-01 00:00:00.000000000 +0000 +++ galera-4-26.4.14/asio/asio/awaitable.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -0,0 +1,123 @@ +// +// 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 ASIO_AWAITABLE_HPP +#define ASIO_AWAITABLE_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include "asio/detail/config.hpp" + +#if defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#include +#include "asio/executor.hpp" + +#include "asio/detail/push_options.hpp" + +namespace asio { +namespace detail { + +using std::experimental::coroutine_handle; +using std::experimental::suspend_always; + +template class awaitable_thread; +template class awaitable_frame; + +} // namespace detail + +/// The return type of a coroutine or asynchronous operation. +template +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 + void await_suspend( + detail::coroutine_handle> h) + { + frame_->push_frame(&h.promise()); + } + + // Support for co_await keyword. + T await_resume() + { + return frame_->get(); + } + +#endif // !defined(GENERATING_DOCUMENTATION) + +private: + template friend class detail::awaitable_thread; + template 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* a) + : frame_(a) + { + } + + detail::awaitable_frame* frame_; +}; + +} // namespace asio + +#include "asio/detail/pop_options.hpp" + +#include "asio/impl/awaitable.hpp" + +#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION) + +#endif // ASIO_AWAITABLE_HPP diff -Nru galera-4-26.4.11/asio/asio/basic_datagram_socket.hpp galera-4-26.4.14/asio/asio/basic_datagram_socket.hpp --- galera-4-26.4.11/asio/asio/basic_datagram_socket.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_datagram_socket.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_datagram_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,8 +18,8 @@ #include "asio/detail/config.hpp" #include #include "asio/basic_socket.hpp" -#include "asio/datagram_socket_service.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" @@ -28,6 +28,15 @@ namespace asio { +#if !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) +#define ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_datagram_socket; + +#endif // !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL) + /// Provides datagram-oriented socket functionality. /** * The basic_datagram_socket class template provides asynchronous and blocking @@ -37,18 +46,29 @@ * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_datagram_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename DatagramSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_datagram_socket other; + }; /// The native representation of a socket. - typedef typename DatagramSocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -61,12 +81,29 @@ * 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_service The io_service 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(asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_datagram_socket(const executor_type& ex) + : basic_socket(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. + */ + template + explicit basic_datagram_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -74,17 +111,37 @@ /** * This constructor creates and opens a datagram socket. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_datagram_socket(asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_datagram_socket(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -95,18 +152,42 @@ * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. + */ + basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint) + : basic_socket(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 asio::system_error Thrown on failure. */ - basic_datagram_socket(asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + template + basic_datagram_socket(ExecutionContext& context, + const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -115,9 +196,8 @@ * This constructor creates a datagram socket object to hold an existing * native socket. * - * @param io_service The io_service 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. * @@ -125,10 +205,34 @@ * * @throws asio::system_error Thrown on failure. */ - basic_datagram_socket(asio::io_service& io_service, + basic_datagram_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_datagram_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -141,11 +245,11 @@ * 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_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ basic_datagram_socket(basic_datagram_socket&& other) - : basic_socket( - ASIO_MOVE_CAST(basic_datagram_socket)(other)) + : basic_socket(std::move(other)) { } @@ -158,12 +262,12 @@ * 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_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ basic_datagram_socket& operator=(basic_datagram_socket&& other) { - basic_socket::operator=( - ASIO_MOVE_CAST(basic_datagram_socket)(other)); + basic_socket::operator=(std::move(other)); return *this; } @@ -176,15 +280,16 @@ * 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_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ - template - basic_datagram_socket( - basic_datagram_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - ASIO_MOVE_CAST2(basic_datagram_socket< - Protocol1, DatagramSocketService1>)(other)) + template + basic_datagram_socket(basic_datagram_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -198,20 +303,30 @@ * 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_service&) constructor. + * constructed using the @c basic_datagram_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_datagram_socket>::type& operator=( - basic_datagram_socket&& other) - { - basic_socket::operator=( - ASIO_MOVE_CAST2(basic_datagram_socket< - Protocol1, DatagramSocketService1>)(other)); + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_datagram_socket& + >::type operator=(basic_datagram_socket&& other) + { + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_datagram_socket() + { + } + /// Send some data on a connected socket. /** * This function is used to send data on the datagram socket. The function @@ -238,8 +353,8 @@ std::size_t send(const ConstBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "send"); return s; } @@ -266,8 +381,8 @@ socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "send"); return s; } @@ -293,8 +408,8 @@ std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::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 +430,9 @@ * 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 - * asio::io_service::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 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 @@ -338,12 +453,10 @@ async_send(const ConstBufferSequence& buffers, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. @@ -366,9 +479,9 @@ * 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 - * asio::io_service::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 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 @@ -381,12 +494,9 @@ socket_base::message_flags flags, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Send a datagram to the specified endpoint. @@ -419,8 +529,8 @@ const endpoint_type& destination) { asio::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); asio::detail::throw_error(ec, "send_to"); return s; } @@ -446,8 +556,8 @@ const endpoint_type& destination, socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "send_to"); return s; } @@ -473,7 +583,7 @@ const endpoint_type& destination, socket_base::message_flags flags, asio::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); } @@ -498,9 +608,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -521,13 +631,10 @@ const endpoint_type& destination, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, + destination, socket_base::message_flags(0)); } /// Start an asynchronous send. @@ -553,9 +660,9 @@ * 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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(WriteHandler, @@ -564,13 +671,9 @@ const endpoint_type& destination, socket_base::message_flags flags, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, destination, flags); } /// Receive some data on a connected socket. @@ -601,8 +704,8 @@ std::size_t receive(const MutableBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "receive"); return s; } @@ -630,8 +733,8 @@ socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "receive"); return s; } @@ -658,8 +761,8 @@ std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::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. @@ -680,9 +783,9 @@ * 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 - * asio::io_service::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 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 @@ -704,12 +807,10 @@ async_receive(const MutableBufferSequence& buffers, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. @@ -732,9 +833,9 @@ * 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 - * asio::io_service::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 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 @@ -747,12 +848,9 @@ socket_base::message_flags flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, buffers, flags); } /// Receive a datagram with the endpoint of the sender. @@ -786,8 +884,8 @@ endpoint_type& sender_endpoint) { asio::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); asio::detail::throw_error(ec, "receive_from"); return s; } @@ -813,8 +911,8 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "receive_from"); return s; } @@ -840,8 +938,8 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::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. @@ -867,9 +965,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -887,13 +985,10 @@ endpoint_type& sender_endpoint, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, this, buffers, + &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. @@ -921,9 +1016,9 @@ * 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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(ReadHandler, @@ -932,14 +1027,85 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - ASIO_MOVE_CAST(ReadHandler)(handler)); - } + return async_initiate( + initiate_async_receive_from(), handler, + this, buffers, &sender_endpoint, flags); + } + +private: + struct initiate_async_send + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_send_to + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue 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 -Nru galera-4-26.4.11/asio/asio/basic_deadline_timer.hpp galera-4-26.4.14/asio/asio/basic_deadline_timer.hpp --- galera-4-26.4.11/asio/asio/basic_deadline_timer.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_deadline_timer.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_deadline_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,11 +21,15 @@ || defined(GENERATING_DOCUMENTATION) #include -#include "asio/basic_io_object.hpp" -#include "asio/deadline_timer_service.hpp" +#include "asio/detail/deadline_timer_service.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/io_object_impl.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" +#include "asio/time_traits.hpp" #include "asio/detail/push_options.hpp" @@ -50,7 +54,7 @@ * Performing a blocking wait: * @code * // Construct a timer without setting an expiry time. - * asio::deadline_timer timer(io_service); + * asio::deadline_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_from_now(boost::posix_time::seconds(5)); @@ -73,7 +77,7 @@ * ... * * // Construct a timer with an absolute expiry time. - * asio::deadline_timer timer(io_service, + * asio::deadline_timer timer(my_context, * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); * * // Start an asynchronous wait. @@ -121,11 +125,13 @@ */ template , - typename TimerService = deadline_timer_service > + typename Executor = executor> class basic_deadline_timer - : public basic_io_object { public: + /// The type of the executor associated with the object. + typedef Executor executor_type; + /// The time traits type. typedef TimeTraits traits_type; @@ -141,11 +147,30 @@ * expires_at() or expires_from_now() functions must be called to set an * expiry time before the timer can be waited on. * - * @param io_service The io_service 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(asio::io_service& io_service) - : basic_io_object(io_service) + 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. + */ + template + explicit basic_deadline_timer(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -153,18 +178,40 @@ /** * This constructor creates a timer and sets the expiry time. * - * @param io_service The io_service 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(asio::io_service& io_service, - const time_type& expiry_time) - : basic_io_object(io_service) + basic_deadline_timer(const executor_type& ex, const time_type& expiry_time) + : impl_(ex) { asio::error_code ec; - this->service.expires_at(this->implementation, expiry_time, ec); + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); + 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 + basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); } @@ -172,21 +219,98 @@ /** * This constructor creates a timer and sets the expiry time. * - * @param io_service The io_service 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(asio::io_service& io_service, + basic_deadline_timer(const executor_type& ex, const duration_type& expiry_time) - : basic_io_object(io_service) + : impl_(ex) { asio::error_code ec; - this->service.expires_from_now(this->implementation, expiry_time, ec); + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); 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 + basic_deadline_timer(ExecutionContext& context, + const duration_type& expiry_time, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); + asio::detail::throw_error(ec, "expires_from_now"); + } + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_deadline_timer from another. + /** + * This constructor moves a timer from one object to another. + * + * @param other The other basic_deadline_timer 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_deadline_timer(const executor_type&) + * constructor. + */ + basic_deadline_timer(basic_deadline_timer&& other) + : impl_(std::move(other.impl_)) + { + } + + /// Move-assign a basic_deadline_timer from another. + /** + * This assignment operator moves a timer from one object to another. Cancels + * any outstanding asynchronous operations associated with the target object. + * + * @param other The other basic_deadline_timer 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_deadline_timer(const executor_type&) + * constructor. + */ + basic_deadline_timer& operator=(basic_deadline_timer&& other) + { + impl_ = std::move(other.impl_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroys the timer. + /** + * This function destroys the timer, cancelling any outstanding asynchronous + * wait operations associated with the timer as if by calling @c cancel. + */ + ~basic_deadline_timer() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Cancel any asynchronous operations that are waiting on the timer. /** * This function forces the completion of any pending asynchronous wait @@ -212,7 +336,7 @@ std::size_t cancel() { asio::error_code ec; - std::size_t s = this->service.cancel(this->implementation, ec); + std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); return s; } @@ -241,7 +365,7 @@ */ std::size_t cancel(asio::error_code& ec) { - return this->service.cancel(this->implementation, ec); + return impl_.get_service().cancel(impl_.get_implementation(), ec); } /// Cancels one asynchronous operation that is waiting on the timer. @@ -271,7 +395,8 @@ std::size_t cancel_one() { asio::error_code ec; - std::size_t s = this->service.cancel_one(this->implementation, ec); + std::size_t s = impl_.get_service().cancel_one( + impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel_one"); return s; } @@ -302,7 +427,7 @@ */ std::size_t cancel_one(asio::error_code& ec) { - return this->service.cancel_one(this->implementation, ec); + return impl_.get_service().cancel_one(impl_.get_implementation(), ec); } /// Get the timer's expiry time as an absolute time. @@ -312,7 +437,7 @@ */ time_type expires_at() const { - return this->service.expires_at(this->implementation); + return impl_.get_service().expires_at(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. @@ -340,8 +465,8 @@ std::size_t expires_at(const time_type& expiry_time) { asio::error_code ec; - std::size_t s = this->service.expires_at( - this->implementation, expiry_time, ec); + std::size_t s = impl_.get_service().expires_at( + impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_at"); return s; } @@ -371,7 +496,8 @@ std::size_t expires_at(const time_type& expiry_time, asio::error_code& ec) { - return this->service.expires_at(this->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. @@ -381,7 +507,7 @@ */ duration_type expires_from_now() const { - return this->service.expires_from_now(this->implementation); + return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// Set the timer's expiry time relative to now. @@ -409,8 +535,8 @@ std::size_t expires_from_now(const duration_type& expiry_time) { asio::error_code ec; - std::size_t s = this->service.expires_from_now( - this->implementation, expiry_time, ec); + std::size_t s = impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); asio::detail::throw_error(ec, "expires_from_now"); return s; } @@ -440,8 +566,8 @@ std::size_t expires_from_now(const duration_type& expiry_time, asio::error_code& ec) { - return this->service.expires_from_now( - this->implementation, expiry_time, ec); + return impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); } /// Perform a blocking wait on the timer. @@ -454,7 +580,7 @@ void wait() { asio::error_code ec; - this->service.wait(this->implementation, ec); + impl_.get_service().wait(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "wait"); } @@ -467,7 +593,7 @@ */ void wait(asio::error_code& ec) { - this->service.wait(this->implementation, ec); + impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the timer. @@ -490,22 +616,44 @@ * const asio::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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(WaitHandler, void (asio::error_code)) async_wait(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. - ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - return this->service.async_wait(this->implementation, - ASIO_MOVE_CAST(WaitHandler)(handler)); + return async_initiate( + initiate_async_wait(), handler, this); } + +private: + // Disallow copying and assignment. + basic_deadline_timer(const basic_deadline_timer&) ASIO_DELETED; + basic_deadline_timer& operator=( + const basic_deadline_timer&) ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue 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, Executor> impl_; }; } // namespace asio diff -Nru galera-4-26.4.11/asio/asio/basic_io_object.hpp galera-4-26.4.14/asio/asio/basic_io_object.hpp --- galera-4-26.4.11/asio/asio/basic_io_object.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_io_object.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_io_object.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,7 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include "asio/io_service.hpp" +#include "asio/io_context.hpp" #include "asio/detail/push_options.hpp" @@ -67,17 +67,43 @@ /// The underlying implementation type of I/O object. typedef typename service_type::implementation_type implementation_type; - /// Get the io_service associated with the object. +#if !defined(ASIO_NO_DEPRECATED) + /// (Deprecated: Use get_executor().) Get the io_context associated with the + /// object. /** - * This function may be used to obtain the io_service object that the I/O + * 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_service object that the I/O object will use + * @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. */ - asio::io_service& get_io_service() + asio::io_context& get_io_context() { - return service.get_io_service(); + return 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. + */ + asio::io_context& get_io_service() + { + return service_.get_io_context(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + /// The type of the executor associated with the object. + typedef asio::io_context::executor_type executor_type; + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return service_.get_io_context().get_executor(); } protected: @@ -86,10 +112,10 @@ * Performs: * @code get_service().construct(get_implementation()); @endcode */ - explicit basic_io_object(asio::io_service& io_service) - : service(asio::use_service(io_service)) + explicit basic_io_object(asio::io_context& io_context) + : service_(asio::use_service(io_context)) { - service.construct(implementation); + service_.construct(implementation_); } #if defined(GENERATING_DOCUMENTATION) @@ -112,6 +138,11 @@ * @note Available only for services that support movability, */ basic_io_object& operator=(basic_io_object&& other); + + /// Perform a converting move-construction of a basic_io_object. + template + basic_io_object(IoObjectService1& other_service, + typename IoObjectService1::implementation_type& other_implementation); #endif // defined(GENERATING_DOCUMENTATION) /// Protected destructor to prevent deletion through this type. @@ -121,47 +152,42 @@ */ ~basic_io_object() { - service.destroy(implementation); + service_.destroy(implementation_); } /// Get the service associated with the I/O object. service_type& get_service() { - return service; + return service_; } /// Get the service associated with the I/O object. const service_type& get_service() const { - return service; + return service_; } - /// (Deprecated: Use get_service().) The service associated with the I/O - /// object. - /** - * @note Available only for services that do not support movability. - */ - service_type& service; - /// Get the underlying implementation of the I/O object. implementation_type& get_implementation() { - return implementation; + return implementation_; } /// Get the underlying implementation of the I/O object. const implementation_type& get_implementation() const { - return implementation; + return implementation_; } - /// (Deprecated: Use get_implementation().) The underlying implementation of - /// the I/O object. - implementation_type implementation; - private: basic_io_object(const basic_io_object&); basic_io_object& operator=(const basic_io_object&); + + // The service associated with the I/O object. + service_type& service_; + + /// The underlying implementation of the I/O object. + implementation_type implementation_; }; #if defined(ASIO_HAS_MOVE) @@ -173,33 +199,57 @@ typedef IoObjectService service_type; typedef typename service_type::implementation_type implementation_type; - asio::io_service& get_io_service() +#if !defined(ASIO_NO_DEPRECATED) + asio::io_context& get_io_context() + { + return service_->get_io_context(); + } + + asio::io_context& get_io_service() { - return service_->get_io_service(); + return service_->get_io_context(); + } +#endif // !defined(ASIO_NO_DEPRECATED) + + typedef asio::io_context::executor_type executor_type; + + executor_type get_executor() ASIO_NOEXCEPT + { + return service_->get_io_context().get_executor(); } protected: - explicit basic_io_object(asio::io_service& io_service) - : service_(&asio::use_service(io_service)) + explicit basic_io_object(asio::io_context& io_context) + : service_(&asio::use_service(io_context)) { - service_->construct(implementation); + service_->construct(implementation_); } basic_io_object(basic_io_object&& other) : service_(&other.get_service()) { - service_->move_construct(implementation, other.implementation); + service_->move_construct(implementation_, other.implementation_); + } + + template + basic_io_object(IoObjectService1& other_service, + typename IoObjectService1::implementation_type& other_implementation) + : service_(&asio::use_service( + other_service.get_io_context())) + { + service_->converting_move_construct(implementation_, + other_service, other_implementation); } ~basic_io_object() { - service_->destroy(implementation); + service_->destroy(implementation_); } basic_io_object& operator=(basic_io_object&& other) { - service_->move_assign(implementation, - *other.service_, other.implementation); + service_->move_assign(implementation_, + *other.service_, other.implementation_); service_ = other.service_; return *this; } @@ -216,21 +266,20 @@ implementation_type& get_implementation() { - return implementation; + return implementation_; } const implementation_type& get_implementation() const { - return implementation; + return implementation_; } - implementation_type implementation; - private: basic_io_object(const basic_io_object&); void operator=(const basic_io_object&); IoObjectService* service_; + implementation_type implementation_; }; #endif // defined(ASIO_HAS_MOVE) diff -Nru galera-4-26.4.11/asio/asio/basic_raw_socket.hpp galera-4-26.4.14/asio/asio/basic_raw_socket.hpp --- galera-4-26.4.11/asio/asio/basic_raw_socket.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_raw_socket.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_raw_socket.hpp // ~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,15 +19,24 @@ #include #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" -#include "asio/raw_socket_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { +#if !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL) +#define ASIO_BASIC_RAW_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_raw_socket; + +#endif // !defined(ASIO_BASIC_RAW_SOCKET_FWD_DECL) + /// Provides raw-oriented socket functionality. /** * The basic_raw_socket class template provides asynchronous and blocking @@ -37,18 +46,29 @@ * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_raw_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename RawSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_raw_socket other; + }; /// The native representation of a socket. - typedef typename RawSocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -61,12 +81,29 @@ * 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_service The io_service 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(asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_raw_socket(const executor_type& ex) + : basic_socket(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 + explicit basic_raw_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -74,17 +111,36 @@ /** * This constructor creates and opens a raw socket. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_raw_socket(asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) + basic_raw_socket(const executor_type& ex, const protocol_type& protocol) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -95,18 +151,41 @@ * to the specified endpoint on the local machine. The protocol used is the * protocol associated with the given endpoint. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_raw_socket(asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -115,9 +194,8 @@ * This constructor creates a raw socket object to hold an existing * native socket. * - * @param io_service The io_service 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. * @@ -125,10 +203,34 @@ * * @throws asio::system_error Thrown on failure. */ - basic_raw_socket(asio::io_service& io_service, + basic_raw_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_raw_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -141,11 +243,11 @@ * 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_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ basic_raw_socket(basic_raw_socket&& other) - : basic_socket( - ASIO_MOVE_CAST(basic_raw_socket)(other)) + : basic_socket(std::move(other)) { } @@ -157,31 +259,34 @@ * 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_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ basic_raw_socket& operator=(basic_raw_socket&& other) { - basic_socket::operator=( - ASIO_MOVE_CAST(basic_raw_socket)(other)); + basic_socket::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_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ - template - basic_raw_socket(basic_raw_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - ASIO_MOVE_CAST2(basic_raw_socket< - Protocol1, RawSocketService1>)(other)) + template + basic_raw_socket(basic_raw_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -193,20 +298,30 @@ * 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_service&) constructor. + * constructed using the @c basic_raw_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_raw_socket>::type& operator=( - basic_raw_socket&& other) - { - basic_socket::operator=( - ASIO_MOVE_CAST2(basic_raw_socket< - Protocol1, RawSocketService1>)(other)); + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_raw_socket& + >::type operator=(basic_raw_socket&& other) + { + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_raw_socket() + { + } + /// Send some data on a connected socket. /** * This function is used to send data on the raw socket. The function call @@ -232,8 +347,8 @@ std::size_t send(const ConstBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "send"); return s; } @@ -259,8 +374,8 @@ socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "send"); return s; } @@ -285,8 +400,8 @@ std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::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. @@ -307,9 +422,9 @@ * 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 - * asio::io_service::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 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 @@ -330,12 +445,10 @@ async_send(const ConstBufferSequence& buffers, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous send on a connected socket. @@ -358,9 +471,9 @@ * 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 - * asio::io_service::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 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 @@ -373,12 +486,9 @@ socket_base::message_flags flags, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Send raw data to the specified endpoint. @@ -411,8 +521,8 @@ const endpoint_type& destination) { asio::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); asio::detail::throw_error(ec, "send_to"); return s; } @@ -438,8 +548,8 @@ const endpoint_type& destination, socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "send_to"); return s; } @@ -465,7 +575,7 @@ const endpoint_type& destination, socket_base::message_flags flags, asio::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); } @@ -490,9 +600,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -513,12 +623,10 @@ const endpoint_type& destination, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to(this->get_implementation(), - buffers, destination, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, + destination, socket_base::message_flags(0)); } /// Start an asynchronous send. @@ -544,9 +652,9 @@ * 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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(WriteHandler, @@ -555,13 +663,9 @@ const endpoint_type& destination, socket_base::message_flags flags, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send_to(), handler, this, buffers, destination, flags); } /// Receive some data on a connected socket. @@ -592,8 +696,8 @@ std::size_t receive(const MutableBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "receive"); return s; } @@ -621,8 +725,8 @@ socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "receive"); return s; } @@ -649,8 +753,8 @@ std::size_t receive(const MutableBufferSequence& buffers, socket_base::message_flags flags, asio::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. @@ -671,9 +775,9 @@ * 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 - * asio::io_service::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 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 @@ -695,12 +799,10 @@ async_receive(const MutableBufferSequence& buffers, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, + buffers, socket_base::message_flags(0)); } /// Start an asynchronous receive on a connected socket. @@ -723,9 +825,9 @@ * 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 - * asio::io_service::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 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 @@ -738,12 +840,9 @@ socket_base::message_flags flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive(), handler, this, buffers, flags); } /// Receive raw data with the endpoint of the sender. @@ -777,8 +876,8 @@ endpoint_type& sender_endpoint) { asio::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); asio::detail::throw_error(ec, "receive_from"); return s; } @@ -804,8 +903,8 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "receive_from"); return s; } @@ -831,8 +930,8 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, asio::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. @@ -858,9 +957,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -878,13 +977,10 @@ endpoint_type& sender_endpoint, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_from(), handler, this, buffers, + &sender_endpoint, socket_base::message_flags(0)); } /// Start an asynchronous receive. @@ -912,9 +1008,9 @@ * 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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(ReadHandler, @@ -923,14 +1019,85 @@ endpoint_type& sender_endpoint, socket_base::message_flags flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - ASIO_MOVE_CAST(ReadHandler)(handler)); - } + return async_initiate( + initiate_async_receive_from(), handler, + this, buffers, &sender_endpoint, flags); + } + +private: + struct initiate_async_send + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_send( + self->impl_.get_implementation(), buffers, flags, + handler2.value, self->impl_.get_implementation_executor()); + } + }; + + struct initiate_async_send_to + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue 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 -Nru galera-4-26.4.11/asio/asio/basic_seq_packet_socket.hpp galera-4-26.4.14/asio/asio/basic_seq_packet_socket.hpp --- galera-4-26.4.11/asio/asio/basic_seq_packet_socket.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_seq_packet_socket.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_seq_packet_socket.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,12 +21,20 @@ #include "asio/detail/handler_type_requirements.hpp" #include "asio/detail/throw_error.hpp" #include "asio/error.hpp" -#include "asio/seq_packet_socket_service.hpp" #include "asio/detail/push_options.hpp" namespace asio { +#if !defined(ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) +#define ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_seq_packet_socket; + +#endif // !defined(ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) + /// Provides sequenced packet socket functionality. /** * The basic_seq_packet_socket class template provides asynchronous and blocking @@ -36,19 +44,29 @@ * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template > +template class basic_seq_packet_socket - : public basic_socket + : public basic_socket { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename SeqPacketSocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_seq_packet_socket other; + }; /// The native representation of a socket. - typedef typename SeqPacketSocketService::native_handle_type - native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename basic_socket::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -62,12 +80,30 @@ * socket needs to be opened and then connected or accepted before data can * be sent or received on it. * - * @param io_service The io_service 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(asio::io_service& io_service) - : basic_socket(io_service) + explicit basic_seq_packet_socket(const executor_type& ex) + : basic_socket(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. + */ + template + explicit basic_seq_packet_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context) { } @@ -77,17 +113,40 @@ * needs to be connected or accepted before data can be sent or received on * it. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_seq_packet_socket(asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol) - : basic_socket(io_service, protocol) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol) { } @@ -98,18 +157,43 @@ * it bound to the specified endpoint on the local machine. The protocol used * is the protocol associated with the given endpoint. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_seq_packet_socket(asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, endpoint) { } @@ -118,9 +202,8 @@ * This constructor creates a sequenced packet socket object to hold an * existing native socket. * - * @param io_service The io_service 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. * @@ -128,10 +211,34 @@ * * @throws asio::system_error Thrown on failure. */ - basic_seq_packet_socket(asio::io_service& io_service, + basic_seq_packet_socket(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) + : basic_socket(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 asio::system_error Thrown on failure. + */ + template + basic_seq_packet_socket(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : basic_socket(context, protocol, native_socket) { } @@ -145,11 +252,11 @@ * 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_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ basic_seq_packet_socket(basic_seq_packet_socket&& other) - : basic_socket( - ASIO_MOVE_CAST(basic_seq_packet_socket)(other)) + : basic_socket(std::move(other)) { } @@ -162,12 +269,12 @@ * 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_service&) 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::operator=( - ASIO_MOVE_CAST(basic_seq_packet_socket)(other)); + basic_socket::operator=(std::move(other)); return *this; } @@ -181,15 +288,16 @@ * 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_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ - template - basic_seq_packet_socket( - basic_seq_packet_socket&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - ASIO_MOVE_CAST2(basic_seq_packet_socket< - Protocol1, SeqPacketSocketService1>)(other)) + template + basic_seq_packet_socket(basic_seq_packet_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : basic_socket(std::move(other)) { } @@ -203,20 +311,30 @@ * 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_service&) constructor. + * constructed using the @c basic_seq_packet_socket(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_seq_packet_socket>::type& operator=( - basic_seq_packet_socket&& other) - { - basic_socket::operator=( - ASIO_MOVE_CAST2(basic_seq_packet_socket< - Protocol1, SeqPacketSocketService1>)(other)); + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_seq_packet_socket& + >::type operator=(basic_seq_packet_socket&& other) + { + basic_socket::operator=(std::move(other)); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the socket. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ + ~basic_seq_packet_socket() + { + } + /// Send some data on the socket. /** * This function is used to send data on the sequenced packet socket. The @@ -245,8 +363,8 @@ socket_base::message_flags flags) { asio::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); asio::detail::throw_error(ec, "send"); return s; } @@ -273,8 +391,8 @@ std::size_t send(const ConstBufferSequence& buffers, socket_base::message_flags flags, asio::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. @@ -297,9 +415,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To send a single data buffer use the @ref buffer function as follows: @@ -317,12 +435,9 @@ socket_base::message_flags flags, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_send(), handler, this, buffers, flags); } /// Receive some data on the socket. @@ -359,8 +474,8 @@ socket_base::message_flags& out_flags) { asio::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, out_flags, ec); + std::size_t s = this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, 0, out_flags, ec); asio::detail::throw_error(ec, "receive"); return s; } @@ -406,8 +521,8 @@ socket_base::message_flags& out_flags) { asio::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, in_flags, out_flags, ec); + std::size_t s = this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); asio::detail::throw_error(ec, "receive"); return s; } @@ -440,8 +555,8 @@ socket_base::message_flags in_flags, socket_base::message_flags& out_flags, asio::error_code& ec) { - return this->get_service().receive(this->get_implementation(), - buffers, in_flags, out_flags, ec); + return this->impl_.get_service().receive_with_flags( + this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); } /// Start an asynchronous receive. @@ -468,9 +583,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -489,13 +604,10 @@ socket_base::message_flags& out_flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive( - this->get_implementation(), buffers, 0, out_flags, - ASIO_MOVE_CAST(ReadHandler)(handler)); + return async_initiate( + initiate_async_receive_with_flags(), handler, this, + buffers, socket_base::message_flags(0), &out_flags); } /// Start an asynchronous receive. @@ -524,9 +636,9 @@ * 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 - * asio::io_service::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 asio::post(). * * @par Example * To receive into a single data buffer use the @ref buffer function as @@ -548,14 +660,49 @@ socket_base::message_flags& out_flags, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_receive( - this->get_implementation(), buffers, in_flags, out_flags, - ASIO_MOVE_CAST(ReadHandler)(handler)); - } + return async_initiate( + initiate_async_receive_with_flags(), handler, + this, buffers, in_flags, &out_flags); + } + +private: + struct initiate_async_send + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue 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 -Nru galera-4-26.4.11/asio/asio/basic_serial_port.hpp galera-4-26.4.14/asio/asio/basic_serial_port.hpp --- galera-4-26.4.11/asio/asio/basic_serial_port.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_serial_port.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_serial_port.hpp // ~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 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,12 +22,25 @@ || defined(GENERATING_DOCUMENTATION) #include -#include "asio/basic_io_object.hpp" +#include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/io_object_impl.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" #include "asio/serial_port_base.hpp" -#include "asio/serial_port_service.hpp" +#if defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_serial_port_service.hpp" +#else +# include "asio/detail/reactive_serial_port_service.hpp" +#endif + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) #include "asio/detail/push_options.hpp" @@ -35,39 +48,84 @@ /// 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 +template class basic_serial_port - : public basic_io_object, - public serial_port_base + : public serial_port_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// serial port. - typedef typename SerialPortService::native_handle_type native_type; + /// 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(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_serial_port is always the lowest layer. - typedef basic_serial_port lowest_layer_type; + /// A basic_basic_serial_port is always the lowest layer. + typedef basic_serial_port lowest_layer_type; /// Construct a basic_serial_port without opening it. /** * This constructor creates a serial port without opening it. * - * @param io_service The io_service 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. + */ + 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 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. + */ + template + explicit basic_serial_port(ExecutionContext& context, + typename enable_if< + is_convertible::value, + basic_serial_port + >::type* = 0) + : impl_(context) + { + } + + /// 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. */ - explicit basic_serial_port(asio::io_service& io_service) - : basic_io_object(io_service) + basic_serial_port(const executor_type& ex, const char* device) + : impl_(ex) { + asio::error_code ec; + impl_.get_service().open(impl_.get_implementation(), device, ec); + asio::detail::throw_error(ec, "open"); } /// Construct and open a basic_serial_port. @@ -75,18 +133,42 @@ * This constructor creates and opens a serial port for the specified device * name. * - * @param io_service The io_service 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. + */ + template + basic_serial_port(ExecutionContext& context, const char* device, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().open(impl_.get_implementation(), device, ec); + 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. */ - explicit basic_serial_port(asio::io_service& io_service, - const char* device) - : basic_io_object(io_service) + basic_serial_port(const executor_type& ex, const std::string& device) + : impl_(ex) { asio::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } @@ -95,18 +177,22 @@ * This constructor creates and opens a serial port for the specified device * name. * - * @param io_service The io_service 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(asio::io_service& io_service, - const std::string& device) - : basic_io_object(io_service) + template + basic_serial_port(ExecutionContext& context, const std::string& device, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { asio::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } @@ -115,19 +201,47 @@ * This constructor creates a serial port object to hold an existing native * serial port. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_serial_port(asio::io_service& io_service, + basic_serial_port(const executor_type& ex, const native_handle_type& native_serial_port) - : basic_io_object(io_service) + : impl_(ex) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + native_serial_port, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_serial_port(ExecutionContext& context, + const native_handle_type& native_serial_port, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); asio::detail::throw_error(ec, "assign"); } @@ -141,11 +255,11 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_serial_port(io_service&) constructor. + * constructed using the @c basic_serial_port(const executor_type&) + * constructor. */ basic_serial_port(basic_serial_port&& other) - : basic_io_object( - ASIO_MOVE_CAST(basic_serial_port)(other)) + : impl_(std::move(other.impl_)) { } @@ -157,16 +271,32 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_serial_port(io_service&) constructor. + * constructed using the @c basic_serial_port(const executor_type&) + * constructor. */ basic_serial_port& operator=(basic_serial_port&& other) { - basic_io_object::operator=( - ASIO_MOVE_CAST(basic_serial_port)(other)); + impl_ = std::move(other.impl_); return *this; } #endif // defined(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() 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 @@ -206,7 +336,7 @@ void open(const std::string& device) { asio::error_code ec; - this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); asio::detail::throw_error(ec, "open"); } @@ -219,10 +349,11 @@ * * @param ec Set the indicate what error occurred, if any. */ - asio::error_code open(const std::string& device, + ASIO_SYNC_OP_VOID open(const std::string& device, asio::error_code& ec) { - return this->get_service().open(this->get_implementation(), device, ec); + impl_.get_service().open(impl_.get_implementation(), device, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native serial port to the serial port. @@ -236,7 +367,7 @@ void assign(const native_handle_type& native_serial_port) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); asio::detail::throw_error(ec, "assign"); } @@ -249,17 +380,18 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code assign(const native_handle_type& native_serial_port, + ASIO_SYNC_OP_VOID assign(const native_handle_type& native_serial_port, asio::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), native_serial_port, ec); + 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()); + return impl_.get_service().is_open(impl_.get_implementation()); } /// Close the serial port. @@ -273,7 +405,7 @@ void close() { asio::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } @@ -285,21 +417,10 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code close(asio::error_code& ec) - { - return this->get_service().close(this->get_implementation(), ec); - } - - /// (Deprecated: Use native_handle().) 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_type native() + ASIO_SYNC_OP_VOID close(asio::error_code& ec) { - return this->get_service().native_handle(this->get_implementation()); + impl_.get_service().close(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the native serial port representation. @@ -310,7 +431,7 @@ */ 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. @@ -324,7 +445,7 @@ void cancel() { asio::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } @@ -336,9 +457,10 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code cancel(asio::error_code& ec) + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Send a break sequence to the serial port. @@ -351,7 +473,7 @@ void send_break() { asio::error_code ec; - this->get_service().send_break(this->get_implementation(), ec); + impl_.get_service().send_break(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "send_break"); } @@ -362,9 +484,10 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code send_break(asio::error_code& ec) + ASIO_SYNC_OP_VOID send_break(asio::error_code& ec) { - return this->get_service().send_break(this->get_implementation(), ec); + impl_.get_service().send_break(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the serial port. @@ -386,7 +509,7 @@ void set_option(const SettableSerialPortOption& option) { asio::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } @@ -406,11 +529,11 @@ * asio::serial_port_base::character_size */ template - asio::error_code set_option(const SettableSerialPortOption& option, + ASIO_SYNC_OP_VOID set_option(const SettableSerialPortOption& option, asio::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the serial port. @@ -430,10 +553,10 @@ * asio::serial_port_base::character_size */ template - void get_option(GettableSerialPortOption& option) + void get_option(GettableSerialPortOption& option) const { asio::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } @@ -454,11 +577,11 @@ * asio::serial_port_base::character_size */ template - asio::error_code get_option(GettableSerialPortOption& option, - asio::error_code& ec) + ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option, + asio::error_code& ec) const { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Write some data to the serial port. @@ -482,7 +605,7 @@ * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code - * serial_port.write_some(asio::buffer(data, size)); + * basic_serial_port.write_some(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 @@ -492,8 +615,8 @@ std::size_t write_some(const ConstBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "write_some"); return s; } @@ -518,8 +641,8 @@ std::size_t write_some(const ConstBufferSequence& buffers, asio::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. @@ -540,9 +663,9 @@ * 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 - * asio::io_service::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 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 @@ -551,7 +674,8 @@ * @par Example * To write a single data buffer use the @ref buffer function as follows: * @code - * serial_port.async_write_some(asio::buffer(data, size), handler); + * basic_serial_port.async_write_some( + * 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 @@ -563,12 +687,9 @@ async_write_some(const ConstBufferSequence& buffers, 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. - ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_write_some(this->get_implementation(), - buffers, ASIO_MOVE_CAST(WriteHandler)(handler)); + return async_initiate( + initiate_async_write_some(), handler, this, buffers); } /// Read some data from the serial port. @@ -593,7 +714,7 @@ * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code - * serial_port.read_some(asio::buffer(data, size)); + * basic_serial_port.read_some(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 @@ -603,8 +724,8 @@ std::size_t read_some(const MutableBufferSequence& buffers) { asio::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); asio::detail::throw_error(ec, "read_some"); return s; } @@ -630,8 +751,8 @@ std::size_t read_some(const MutableBufferSequence& buffers, asio::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. @@ -652,9 +773,9 @@ * 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 - * asio::io_service::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 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 @@ -664,7 +785,8 @@ * @par Example * To read into a single data buffer use the @ref buffer function as follows: * @code - * serial_port.async_read_some(asio::buffer(data, size), handler); + * basic_serial_port.async_read_some( + * 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 @@ -676,13 +798,55 @@ async_read_some(const MutableBufferSequence& buffers, 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. - ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; - - return this->get_service().async_read_some(this->get_implementation(), - buffers, ASIO_MOVE_CAST(ReadHandler)(handler)); - } + return async_initiate( + initiate_async_read_some(), handler, this, buffers); + } + +private: + // Disallow copying and assignment. + basic_serial_port(const basic_serial_port&) ASIO_DELETED; + basic_serial_port& operator=(const basic_serial_port&) ASIO_DELETED; + + struct initiate_async_write_some + { + template + void operator()(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. + ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_read_some( + self->impl_.get_implementation(), buffers, handler2.value, + self->impl_.get_implementation_executor()); + } + }; + +#if defined(ASIO_HAS_IOCP) + detail::io_object_impl impl_; +#else + detail::io_object_impl impl_; +#endif }; } // namespace asio diff -Nru galera-4-26.4.11/asio/asio/basic_signal_set.hpp galera-4-26.4.14/asio/asio/basic_signal_set.hpp --- galera-4-26.4.11/asio/asio/basic_signal_set.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_signal_set.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_signal_set.hpp // ~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,22 +17,23 @@ #include "asio/detail/config.hpp" -#include "asio/basic_io_object.hpp" +#include "asio/async_result.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/io_object_impl.hpp" +#include "asio/detail/non_const_lvalue.hpp" +#include "asio/detail/signal_set_service.hpp" #include "asio/detail/throw_error.hpp" +#include "asio/detail/type_traits.hpp" #include "asio/error.hpp" -#include "asio/signal_set_service.hpp" - -#include "asio/detail/push_options.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" 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 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 @@ -54,7 +55,7 @@ * ... * * // Construct a signal set registered for process termination. - * asio::signal_set signals(io_service, SIGINT, SIGTERM); + * asio::signal_set signals(my_context, SIGINT, SIGTERM); * * // Start an asynchronous wait for one of the signals to occur. * signals.async_wait(handler); @@ -89,41 +90,88 @@ * that any signals registered using signal_set objects are unblocked in at * least one thread. */ -template +template class basic_signal_set - : public basic_io_object { 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_service The io_service 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. + */ + template + explicit basic_signal_set(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + } + + /// Construct a signal set and add one signal. + /** + * This constructor creates a signal set and registers for one signal. + * + * @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 asio::signal_set signals(ex); + * signals.add(signal_number_1); @endcode */ - explicit basic_signal_set(asio::io_service& io_service) - : basic_io_object(io_service) + basic_signal_set(const executor_type& ex, int signal_number_1) + : impl_(ex) { + asio::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + 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 io_service The io_service 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. * * @param signal_number_1 The signal number to be added. * * @note This constructor is equivalent to performing: - * @code asio::signal_set signals(io_service); + * @code asio::signal_set signals(context); * signals.add(signal_number_1); @endcode */ - basic_signal_set(asio::io_service& io_service, int signal_number_1) - : basic_io_object(io_service) + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { asio::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); } @@ -131,26 +179,59 @@ /** * This constructor creates a signal set and registers for two signals. * - * @param io_service The io_service 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 asio::signal_set signals(io_service); + * @code asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); @endcode */ - basic_signal_set(asio::io_service& io_service, int signal_number_1, + basic_signal_set(const executor_type& ex, int signal_number_1, int signal_number_2) - : basic_io_object(io_service) + : impl_(ex) { asio::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_2, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); + 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 asio::signal_set signals(context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); @endcode + */ + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + int signal_number_2, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); } @@ -158,8 +239,9 @@ /** * This constructor creates a signal set and registers for three signals. * - * @param io_service The io_service 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. * @@ -168,24 +250,77 @@ * @param signal_number_3 The third signal number to be added. * * @note This constructor is equivalent to performing: - * @code asio::signal_set signals(io_service); + * @code asio::signal_set signals(ex); * signals.add(signal_number_1); * signals.add(signal_number_2); * signals.add(signal_number_3); @endcode */ - basic_signal_set(asio::io_service& io_service, 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(io_service) + : impl_(ex) { asio::error_code ec; - this->service.add(this->implementation, signal_number_1, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_2, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); asio::detail::throw_error(ec, "add"); - this->service.add(this->implementation, signal_number_3, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); 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 asio::signal_set signals(context); + * signals.add(signal_number_1); + * signals.add(signal_number_2); + * signals.add(signal_number_3); @endcode + */ + template + basic_signal_set(ExecutionContext& context, int signal_number_1, + int signal_number_2, int signal_number_3, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec); + asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec); + asio::detail::throw_error(ec, "add"); + impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec); + 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() 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 @@ -198,7 +333,7 @@ void add(int signal_number) { asio::error_code ec; - this->service.add(this->implementation, signal_number, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number, ec); asio::detail::throw_error(ec, "add"); } @@ -211,10 +346,11 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code add(int signal_number, + ASIO_SYNC_OP_VOID add(int signal_number, asio::error_code& ec) { - return this->service.add(this->implementation, signal_number, ec); + impl_.get_service().add(impl_.get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove a signal from a signal_set. @@ -232,7 +368,7 @@ void remove(int signal_number) { asio::error_code ec; - this->service.remove(this->implementation, signal_number, ec); + impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); asio::detail::throw_error(ec, "remove"); } @@ -248,10 +384,11 @@ * @note Removes any notifications that have been queued for the specified * signal number. */ - asio::error_code remove(int signal_number, + ASIO_SYNC_OP_VOID remove(int signal_number, asio::error_code& ec) { - return this->service.remove(this->implementation, signal_number, ec); + impl_.get_service().remove(impl_.get_implementation(), signal_number, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Remove all signals from a signal_set. @@ -266,7 +403,7 @@ void clear() { asio::error_code ec; - this->service.clear(this->implementation, ec); + impl_.get_service().clear(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "clear"); } @@ -279,9 +416,10 @@ * * @note Removes all queued notifications. */ - asio::error_code clear(asio::error_code& ec) + ASIO_SYNC_OP_VOID clear(asio::error_code& ec) { - return this->service.clear(this->implementation, ec); + impl_.get_service().clear(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Cancel all operations associated with the signal set. @@ -308,7 +446,7 @@ void cancel() { asio::error_code ec; - this->service.cancel(this->implementation, ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } @@ -333,9 +471,10 @@ * These handlers can no longer be cancelled, and therefore are passed an * error code that indicates the successful completion of the wait operation. */ - asio::error_code cancel(asio::error_code& ec) + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { - return this->service.cancel(this->implementation, ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous operation to wait for a signal to be delivered. @@ -359,26 +498,44 @@ * 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 - * asio::io_service::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 asio::post(). */ template ASIO_INITFN_RESULT_TYPE(SignalHandler, void (asio::error_code, int)) async_wait(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. - ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; - - return this->service.async_wait(this->implementation, - ASIO_MOVE_CAST(SignalHandler)(handler)); + return async_initiate( + initiate_async_wait(), handler, this); } + +private: + // Disallow copying and assignment. + basic_signal_set(const basic_signal_set&) ASIO_DELETED; + basic_signal_set& operator=(const basic_signal_set&) ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(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. + ASIO_SIGNAL_HANDLER_CHECK(SignalHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + detail::io_object_impl impl_; }; } // namespace asio -#include "asio/detail/pop_options.hpp" - #endif // ASIO_BASIC_SIGNAL_SET_HPP diff -Nru galera-4-26.4.11/asio/asio/basic_socket.hpp galera-4-26.4.14/asio/asio/basic_socket.hpp --- galera-4-26.4.11/asio/asio/basic_socket.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_socket.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_socket.hpp // ~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,17 +17,42 @@ #include "asio/detail/config.hpp" #include "asio/async_result.hpp" -#include "asio/basic_io_object.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/io_object_impl.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" +#include "asio/post.hpp" #include "asio/socket_base.hpp" +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + #include "asio/detail/push_options.hpp" namespace asio { +#if !defined(ASIO_BASIC_SOCKET_FWD_DECL) +#define ASIO_BASIC_SOCKET_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_socket; + +#endif // !defined(ASIO_BASIC_SOCKET_FWD_DECL) + /// Provides socket functionality. /** * The basic_socket class template provides functionality that is common to both @@ -37,18 +62,35 @@ * @e Distinct @e objects: Safe.@n * @e Shared @e objects: Unsafe. */ -template +template class basic_socket - : public basic_io_object, - public socket_base + : public socket_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename SocketService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; + + /// Rebinds the socket type to another executor. + template + struct rebind_executor + { + /// The socket type when rebound to the specified executor. + typedef basic_socket other; + }; /// The native representation of a socket. - typedef typename SocketService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#elif defined(ASIO_WINDOWS_RUNTIME) + typedef typename detail::null_socket_service< + Protocol>::native_handle_type native_handle_type; +#elif defined(ASIO_HAS_IOCP) + typedef typename detail::win_iocp_socket_service< + Protocol>::native_handle_type native_handle_type; +#else + typedef typename detail::reactive_socket_service< + Protocol>::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -56,18 +98,37 @@ /// The endpoint type. typedef typename Protocol::endpoint endpoint_type; +#if !defined(ASIO_NO_EXTENSIONS) /// A basic_socket is always the lowest layer. - typedef basic_socket lowest_layer_type; + typedef basic_socket lowest_layer_type; +#endif // !defined(ASIO_NO_EXTENSIONS) /// Construct a basic_socket without opening it. /** * This constructor creates a socket without opening it. * - * @param io_service The io_service 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(asio::io_service& io_service) - : basic_io_object(io_service) + 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 + explicit basic_socket(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -75,19 +136,42 @@ /** * This constructor creates and opens a socket. * - * @param io_service The io_service 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 asio::system_error Thrown on failure. */ - basic_socket(asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const protocol_type& protocol) + : impl_(ex) + { + asio::error_code ec; + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { asio::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } @@ -98,7 +182,7 @@ * specified endpoint on the local machine. The protocol used is the protocol * associated with the given endpoint. * - * @param io_service The io_service 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 @@ -106,15 +190,45 @@ * * @throws asio::system_error Thrown on failure. */ - basic_socket(asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const endpoint_type& endpoint) + : impl_(ex) { asio::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); asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const endpoint_type& endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + const protocol_type protocol = endpoint.protocol(); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + asio::detail::throw_error(ec, "open"); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } @@ -122,7 +236,7 @@ /** * This constructor creates a socket object to hold an existing native socket. * - * @param io_service The io_service 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. @@ -131,12 +245,40 @@ * * @throws asio::system_error Thrown on failure. */ - basic_socket(asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_service) + basic_socket(const executor_type& ex, const protocol_type& protocol, + const native_handle_type& native_socket) + : impl_(ex) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + protocol, native_socket, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_socket(ExecutionContext& context, const protocol_type& protocol, + const native_handle_type& native_socket, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); asio::detail::throw_error(ec, "assign"); } @@ -150,11 +292,10 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket(basic_socket&& other) - : basic_io_object( - ASIO_MOVE_CAST(basic_socket)(other)) + : impl_(std::move(other.impl_)) { } @@ -166,17 +307,16 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ basic_socket& operator=(basic_socket&& other) { - basic_io_object::operator=( - ASIO_MOVE_CAST(basic_socket)(other)); + impl_ = std::move(other.impl_); return *this; } // All sockets have access to each other's implementations. - template + template friend class basic_socket; /// Move-construct a basic_socket from a socket of another protocol type. @@ -187,15 +327,16 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ - template - basic_socket(basic_socket&& other, - typename enable_if::value>::type* = 0) - : basic_io_object(other.get_io_service()) + template + basic_socket(basic_socket&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : impl_(std::move(other.impl_)) { - this->get_service().template converting_move_construct( - this->get_implementation(), other.get_implementation()); } /// Move-assign a basic_socket from a socket of another protocol type. @@ -206,21 +347,28 @@ * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket(const executor_type&) constructor. */ - template - typename enable_if::value, - basic_socket>::type& operator=( - basic_socket&& other) - { - basic_socket tmp(ASIO_MOVE_CAST2(basic_socket< - Protocol1, SocketService1>)(other)); - basic_io_object::operator=( - ASIO_MOVE_CAST(basic_socket)(tmp)); + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_socket& + >::type operator=(basic_socket && other) + { + basic_socket tmp(std::move(other)); + impl_ = std::move(tmp.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + +#if !defined(ASIO_NO_EXTENSIONS) /// Get a reference to the lowest layer. /** * This function returns a reference to the lowest layer in a stack of @@ -248,6 +396,7 @@ { return *this; } +#endif // !defined(ASIO_NO_EXTENSIONS) /// Open the socket using the specified protocol. /** @@ -259,14 +408,14 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { asio::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } @@ -280,7 +429,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::error_code ec; * socket.open(asio::ip::tcp::v4(), ec); * if (ec) @@ -289,10 +438,11 @@ * } * @endcode */ - asio::error_code open(const protocol_type& protocol, + ASIO_SYNC_OP_VOID open(const protocol_type& protocol, asio::error_code& ec) { - return this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assign an existing native socket to the socket. @@ -309,7 +459,7 @@ const native_handle_type& native_socket) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); asio::detail::throw_error(ec, "assign"); } @@ -324,17 +474,18 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code assign(const protocol_type& protocol, + ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_socket, asio::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_socket, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// 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. @@ -352,7 +503,7 @@ void close() { asio::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } @@ -367,7 +518,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * socket.close(ec); @@ -380,20 +531,62 @@ * @note For portable behaviour with respect to graceful closure of a * connected socket, call shutdown() before closing the socket. */ - asio::error_code close(asio::error_code& ec) + ASIO_SYNC_OP_VOID close(asio::error_code& ec) { - return this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } - /// (Deprecated: Use native_handle().) Get the native socket representation. + /// Release ownership of the underlying native socket. /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. Ownership + * of the native socket is then transferred to the caller. + * + * @throws asio::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release() + { + asio::error_code ec; + native_handle_type s = impl_.get_service().release( + impl_.get_implementation(), ec); + asio::detail::throw_error(ec, "release"); + return s; + } + + /// Release ownership of the underlying native socket. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the asio::error::operation_aborted error. Ownership + * of the native socket is then transferred to the caller. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. */ - native_type native() +#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release(asio::error_code& ec) { - return this->get_service().native_handle(this->get_implementation()); + return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native socket representation. @@ -404,7 +597,7 @@ */ 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. @@ -451,7 +644,7 @@ void cancel() { asio::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } @@ -496,9 +689,10 @@ "operation_not_supported when used on Windows XP, Windows Server 2003, " "or earlier. Consult documentation for details.")) #endif - asio::error_code cancel(asio::error_code& ec) + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Determine whether the socket is at the out-of-band data mark. @@ -514,7 +708,7 @@ bool at_mark() const { asio::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); asio::detail::throw_error(ec, "at_mark"); return b; } @@ -531,7 +725,7 @@ */ bool at_mark(asio::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. @@ -547,8 +741,8 @@ std::size_t available() const { asio::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); asio::detail::throw_error(ec, "available"); return s; } @@ -565,7 +759,7 @@ */ std::size_t available(asio::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. @@ -580,7 +774,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * socket.bind(asio::ip::tcp::endpoint( * asio::ip::tcp::v4(), 12345)); @@ -589,7 +783,7 @@ void bind(const endpoint_type& endpoint) { asio::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } @@ -605,7 +799,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * socket.open(asio::ip::tcp::v4()); * asio::error_code ec; * socket.bind(asio::ip::tcp::endpoint( @@ -616,10 +810,11 @@ * } * @endcode */ - asio::error_code bind(const endpoint_type& endpoint, + ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, asio::error_code& ec) { - return this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Connect the socket to the specified endpoint. @@ -639,7 +834,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.connect(endpoint); @@ -650,11 +845,11 @@ asio::error_code ec; if (!is_open()) { - this->get_service().open(this->get_implementation(), + impl_.get_service().open(impl_.get_implementation(), peer_endpoint.protocol(), ec); 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); asio::detail::throw_error(ec, "connect"); } @@ -675,7 +870,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * asio::error_code ec; @@ -686,20 +881,21 @@ * } * @endcode */ - asio::error_code connect(const endpoint_type& peer_endpoint, + ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, asio::error_code& ec) { if (!is_open()) { - if (this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec)) + impl_.get_service().open(impl_.get_implementation(), + peer_endpoint.protocol(), ec); + if (ec) { - return ec; + ASIO_SYNC_OP_VOID_RETURN(ec); } } - return this->get_service().connect( - this->get_implementation(), peer_endpoint, ec); + impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous connect. @@ -721,9 +917,9 @@ * const asio::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 - * asio::io_service::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 asio::post(). * * @par Example * @code @@ -737,7 +933,7 @@ * * ... * - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint( * asio::ip::address::from_string("1.2.3.4"), 12345); * socket.async_connect(endpoint, connect_handler); @@ -749,32 +945,15 @@ async_connect(const endpoint_type& peer_endpoint, 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. - ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - + asio::error_code open_ec; if (!is_open()) { - asio::error_code ec; const protocol_type protocol = peer_endpoint.protocol(); - if (this->get_service().open(this->get_implementation(), protocol, ec)) - { - detail::async_result_init< - ConnectHandler, void (asio::error_code)> init( - ASIO_MOVE_CAST(ConnectHandler)(handler)); - - this->get_io_service().post( - asio::detail::bind_handler( - ASIO_MOVE_CAST(ASIO_HANDLER_TYPE( - ConnectHandler, void (asio::error_code)))( - init.handler), ec)); - - return init.result.get(); - } + impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); } - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, ASIO_MOVE_CAST(ConnectHandler)(handler)); + return async_initiate( + initiate_async_connect(), handler, this, peer_endpoint, open_ec); } /// Set an option on the socket. @@ -805,7 +984,7 @@ * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option(true); * socket.set_option(option); @@ -815,7 +994,7 @@ void set_option(const SettableSocketOption& option) { asio::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } @@ -847,7 +1026,7 @@ * @par Example * Setting the IPPROTO_TCP/TCP_NODELAY option: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::no_delay option(true); * asio::error_code ec; @@ -859,11 +1038,11 @@ * @endcode */ template - asio::error_code set_option(const SettableSocketOption& option, + ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, asio::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the socket. @@ -894,7 +1073,7 @@ * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::keep_alive option; * socket.get_option(option); @@ -905,7 +1084,7 @@ void get_option(GettableSocketOption& option) const { asio::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } @@ -937,7 +1116,7 @@ * @par Example * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::keep_alive option; * asio::error_code ec; @@ -950,11 +1129,11 @@ * @endcode */ template - asio::error_code get_option(GettableSocketOption& option, + ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, asio::error_code& ec) const { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the socket. @@ -972,7 +1151,7 @@ * @par Example * Getting the number of bytes ready to read: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::bytes_readable command; * socket.io_control(command); @@ -983,7 +1162,7 @@ void io_control(IoControlCommand& command) { asio::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); asio::detail::throw_error(ec, "io_control"); } @@ -1002,7 +1181,7 @@ * @par Example * Getting the number of bytes ready to read: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::socket::bytes_readable command; * asio::error_code ec; @@ -1015,11 +1194,11 @@ * @endcode */ template - asio::error_code io_control(IoControlCommand& command, + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, asio::error_code& ec) { - return this->get_service().io_control( - this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the socket. @@ -1035,7 +1214,7 @@ */ 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. @@ -1054,7 +1233,7 @@ void non_blocking(bool mode) { asio::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "non_blocking"); } @@ -1071,11 +1250,11 @@ * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ - asio::error_code non_blocking( + ASIO_SYNC_OP_VOID non_blocking( bool mode, asio::error_code& ec) { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native socket implementation. @@ -1135,7 +1314,7 @@ * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1159,12 +1338,12 @@ * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ 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. @@ -1225,7 +1404,7 @@ * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1249,14 +1428,14 @@ * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ void native_non_blocking(bool mode) { asio::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); asio::detail::throw_error(ec, "native_non_blocking"); } @@ -1318,7 +1497,7 @@ * || ec == asio::error::try_again) * { * // We have to wait for the socket to become ready again. - * sock_.async_write_some(asio::null_buffers(), *this); + * sock_.async_wait(tcp::socket::wait_write, *this); * return; * } * @@ -1342,14 +1521,15 @@ * void async_sendfile(tcp::socket& sock, int fd, Handler h) * { * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_write_some(asio::null_buffers(), op); + * sock.async_wait(tcp::socket::wait_write, op); * } @endcode */ - asio::error_code native_non_blocking( + ASIO_SYNC_OP_VOID native_non_blocking( bool mode, asio::error_code& ec) { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the socket. @@ -1362,7 +1542,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); * @endcode @@ -1370,8 +1550,8 @@ endpoint_type local_endpoint() const { asio::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); asio::detail::throw_error(ec, "local_endpoint"); return ep; } @@ -1387,7 +1567,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); @@ -1399,7 +1579,7 @@ */ endpoint_type local_endpoint(asio::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. @@ -1412,7 +1592,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); * @endcode @@ -1420,8 +1600,8 @@ endpoint_type remote_endpoint() const { asio::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); asio::detail::throw_error(ec, "remote_endpoint"); return ep; } @@ -1437,7 +1617,7 @@ * * @par Example * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); @@ -1449,7 +1629,7 @@ */ endpoint_type remote_endpoint(asio::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. @@ -1464,7 +1644,7 @@ * @par Example * Shutting down the send side of the socket: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * socket.shutdown(asio::ip::tcp::socket::shutdown_send); * @endcode @@ -1472,7 +1652,7 @@ void shutdown(shutdown_type what) { asio::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); + impl_.get_service().shutdown(impl_.get_implementation(), what, ec); asio::detail::throw_error(ec, "shutdown"); } @@ -1488,7 +1668,7 @@ * @par Example * Shutting down the send side of the socket: * @code - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * ... * asio::error_code ec; * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); @@ -1498,17 +1678,175 @@ * } * @endcode */ - asio::error_code shutdown(shutdown_type what, + ASIO_SYNC_OP_VOID shutdown(shutdown_type what, asio::error_code& ec) { - return this->get_service().shutdown(this->get_implementation(), what, ec); + impl_.get_service().shutdown(impl_.get_implementation(), what, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); + } + + /// Wait for the socket 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 socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket state. + * + * @par Example + * Waiting for a socket to become readable. + * @code + * asio::ip::tcp::socket socket(my_context); + * ... + * socket.wait(asio::ip::tcp::socket::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + impl_.get_service().wait(impl_.get_implementation(), w, ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the socket 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 socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for a socket to become readable. + * @code + * asio::ip::tcp::socket socket(my_context); + * ... + * asio::error_code ec; + * socket.wait(asio::ip::tcp::socket::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + impl_.get_service().wait(impl_.get_implementation(), w, ec); + 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. + /** + * This function is used to perform an asynchronous wait for a socket to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired socket 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 asio::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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::socket socket(my_context); + * ... + * socket.async_wait(asio::ip::tcp::socket::wait_read, wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler) + { + return async_initiate( + initiate_async_wait(), handler, this, w); } protected: /// Protected destructor to prevent deletion through this type. + /** + * This function destroys the socket, cancelling any outstanding asynchronous + * operations associated with the socket as if by calling @c cancel. + */ ~basic_socket() { } + +#if defined(ASIO_WINDOWS_RUNTIME) + detail::io_object_impl< + detail::null_socket_service, Executor> impl_; +#elif defined(ASIO_HAS_IOCP) + detail::io_object_impl< + detail::win_iocp_socket_service, Executor> impl_; +#else + detail::io_object_impl< + detail::reactive_socket_service, Executor> impl_; +#endif + +private: + // Disallow copying and assignment. + basic_socket(const basic_socket&) ASIO_DELETED; + basic_socket& operator=(const basic_socket&) ASIO_DELETED; + + struct initiate_async_connect + { + template + void operator()(ASIO_MOVE_ARG(ConnectHandler) handler, + basic_socket* self, const endpoint_type& peer_endpoint, + const asio::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. + ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; + + if (open_ec) + { + asio::post(self->impl_.get_executor(), + asio::detail::bind_handler( + ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); + } + else + { + detail::non_const_lvalue 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 + void operator()(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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), w, handler2.value, + self->impl_.get_implementation_executor()); + } + }; }; } // namespace asio diff -Nru galera-4-26.4.11/asio/asio/basic_socket_acceptor.hpp galera-4-26.4.14/asio/asio/basic_socket_acceptor.hpp --- galera-4-26.4.11/asio/asio/basic_socket_acceptor.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_socket_acceptor.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_socket_acceptor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,42 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" -#include "asio/basic_io_object.hpp" #include "asio/basic_socket.hpp" #include "asio/detail/handler_type_requirements.hpp" +#include "asio/detail/io_object_impl.hpp" +#include "asio/detail/non_const_lvalue.hpp" #include "asio/detail/throw_error.hpp" #include "asio/detail/type_traits.hpp" #include "asio/error.hpp" -#include "asio/socket_acceptor_service.hpp" +#include "asio/execution_context.hpp" +#include "asio/executor.hpp" #include "asio/socket_base.hpp" +#if defined(ASIO_WINDOWS_RUNTIME) +# include "asio/detail/null_socket_service.hpp" +#elif defined(ASIO_HAS_IOCP) +# include "asio/detail/win_iocp_socket_service.hpp" +#else +# include "asio/detail/reactive_socket_service.hpp" +#endif + +#if defined(ASIO_HAS_MOVE) +# include +#endif // defined(ASIO_HAS_MOVE) + #include "asio/detail/push_options.hpp" namespace asio { +#if !defined(ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL) +#define ASIO_BASIC_SOCKET_ACCEPTOR_FWD_DECL + +// Forward declaration with defaulted arguments. +template +class basic_socket_acceptor; + +#endif // !defined(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 @@ -41,7 +64,7 @@ * @par Example * Opening a socket acceptor with the SO_REUSEADDR option enabled: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port); * acceptor.open(endpoint.protocol()); * acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(true)); @@ -49,19 +72,27 @@ * acceptor.listen(); * @endcode */ -template > +template class basic_socket_acceptor - : public basic_io_object, - public socket_base + : public socket_base { public: - /// (Deprecated: Use native_handle_type.) The native representation of an - /// acceptor. - typedef typename SocketAcceptorService::native_handle_type native_type; + /// The type of the executor associated with the object. + typedef Executor executor_type; /// The native representation of an acceptor. - typedef typename SocketAcceptorService::native_handle_type native_handle_type; +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#elif defined(ASIO_WINDOWS_RUNTIME) + typedef typename detail::null_socket_service< + Protocol>::native_handle_type native_handle_type; +#elif defined(ASIO_HAS_IOCP) + typedef typename detail::win_iocp_socket_service< + Protocol>::native_handle_type native_handle_type; +#else + typedef typename detail::reactive_socket_service< + Protocol>::native_handle_type native_handle_type; +#endif /// The protocol type. typedef Protocol protocol_type; @@ -75,12 +106,31 @@ * connections. The open() function must be called before the acceptor can * accept new socket connections. * - * @param io_service The io_service 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(asio::io_service& io_service) - : basic_io_object(io_service) + 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 + explicit basic_socket_acceptor(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { } @@ -88,7 +138,7 @@ /** * This constructor creates an acceptor and automatically opens it. * - * @param io_service The io_service 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. * @@ -96,12 +146,36 @@ * * @throws asio::system_error Thrown on failure. */ - basic_socket_acceptor(asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol) + : impl_(ex) + { + asio::error_code ec; + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_socket_acceptor(ExecutionContext& context, + const protocol_type& protocol, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { asio::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } @@ -110,7 +184,7 @@ * This constructor creates an acceptor and automatically opens it to listen * for new connections on the specified endpoint. * - * @param io_service The io_service 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. * @@ -124,32 +198,84 @@ * * @note This constructor is equivalent to the following code: * @code - * basic_socket_acceptor acceptor(io_service); + * basic_socket_acceptor 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(asio::io_service& io_service, + basic_socket_acceptor(const executor_type& ex, const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_service) + : impl_(ex) + { + asio::error_code ec; + const protocol_type protocol = endpoint.protocol(); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + asio::detail::throw_error(ec, "open"); + if (reuse_addr) + { + impl_.get_service().set_option(impl_.get_implementation(), + socket_base::reuse_address(true), ec); + asio::detail::throw_error(ec, "set_option"); + } + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + asio::detail::throw_error(ec, "bind"); + impl_.get_service().listen(impl_.get_implementation(), + socket_base::max_listen_connections, ec); + 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 asio::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor 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 + basic_socket_acceptor(ExecutionContext& context, + const endpoint_type& endpoint, bool reuse_addr = true, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) { asio::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); 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); 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); asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_connections, ec); + impl_.get_service().listen(impl_.get_implementation(), + socket_base::max_listen_connections, ec); asio::detail::throw_error(ec, "listen"); } @@ -158,7 +284,7 @@ * This constructor creates an acceptor object to hold an existing native * acceptor. * - * @param io_service The io_service 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. * @@ -168,12 +294,41 @@ * * @throws asio::system_error Thrown on failure. */ - basic_socket_acceptor(asio::io_service& io_service, + basic_socket_acceptor(const executor_type& ex, const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_service) + : impl_(ex) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), + protocol, native_acceptor, ec); + 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 asio::system_error Thrown on failure. + */ + template + basic_socket_acceptor(ExecutionContext& context, + const protocol_type& protocol, const native_handle_type& native_acceptor, + typename enable_if< + is_convertible::value + >::type* = 0) + : impl_(context) + { + asio::error_code ec; + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); asio::detail::throw_error(ec, "assign"); } @@ -187,11 +342,11 @@ * 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_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ basic_socket_acceptor(basic_socket_acceptor&& other) - : basic_io_object( - ASIO_MOVE_CAST(basic_socket_acceptor)(other)) + : impl_(std::move(other.impl_)) { } @@ -203,17 +358,17 @@ * 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_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ basic_socket_acceptor& operator=(basic_socket_acceptor&& other) { - basic_io_object::operator=( - ASIO_MOVE_CAST(basic_socket_acceptor)(other)); + impl_ = std::move(other.impl_); return *this; } // All socket acceptors have access to each other's implementations. - template + template friend class basic_socket_acceptor; /// Move-construct a basic_socket_acceptor from an acceptor of another @@ -225,16 +380,17 @@ * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ - template - basic_socket_acceptor( - basic_socket_acceptor&& other, - typename enable_if::value>::type* = 0) - : basic_io_object(other.get_io_service()) + template + basic_socket_acceptor(basic_socket_acceptor&& other, + typename enable_if< + is_convertible::value + && is_convertible::value + >::type* = 0) + : impl_(std::move(other.impl_)) { - this->get_service().template converting_move_construct( - this->get_implementation(), other.get_implementation()); } /// Move-assign a basic_socket_acceptor from an acceptor of another protocol @@ -246,21 +402,38 @@ * will occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. + * constructed using the @c basic_socket_acceptor(const executor_type&) + * constructor. */ - template - typename enable_if::value, - basic_socket_acceptor>::type& operator=( - basic_socket_acceptor&& other) - { - basic_socket_acceptor tmp(ASIO_MOVE_CAST2(basic_socket_acceptor< - Protocol1, SocketAcceptorService1>)(other)); - basic_io_object::operator=( - ASIO_MOVE_CAST(basic_socket_acceptor)(tmp)); + template + typename enable_if< + is_convertible::value + && is_convertible::value, + basic_socket_acceptor& + >::type operator=(basic_socket_acceptor&& other) + { + basic_socket_acceptor tmp(std::move(other)); + impl_ = std::move(tmp.impl_); return *this; } #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Destroys the acceptor. + /** + * This function destroys the acceptor, cancelling any outstanding + * asynchronous operations associated with the acceptor as if by calling + * @c cancel. + */ + ~basic_socket_acceptor() + { + } + + /// Get the executor associated with the object. + executor_type get_executor() ASIO_NOEXCEPT + { + return impl_.get_executor(); + } + /// Open the acceptor using the specified protocol. /** * This function opens the socket acceptor so that it will use the specified @@ -272,14 +445,14 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * acceptor.open(asio::ip::tcp::v4()); * @endcode */ void open(const protocol_type& protocol = protocol_type()) { asio::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); asio::detail::throw_error(ec, "open"); } @@ -294,7 +467,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * asio::error_code ec; * acceptor.open(asio::ip::tcp::v4(), ec); * if (ec) @@ -303,10 +476,11 @@ * } * @endcode */ - asio::error_code open(const protocol_type& protocol, + ASIO_SYNC_OP_VOID open(const protocol_type& protocol, asio::error_code& ec) { - return this->get_service().open(this->get_implementation(), protocol, ec); + impl_.get_service().open(impl_.get_implementation(), protocol, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Assigns an existing native acceptor to the acceptor. @@ -323,7 +497,7 @@ const native_handle_type& native_acceptor) { asio::error_code ec; - this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); asio::detail::throw_error(ec, "assign"); } @@ -338,17 +512,18 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code assign(const protocol_type& protocol, + ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, const native_handle_type& native_acceptor, asio::error_code& ec) { - return this->get_service().assign(this->get_implementation(), + impl_.get_service().assign(impl_.get_implementation(), protocol, native_acceptor, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// 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. @@ -363,7 +538,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * acceptor.bind(endpoint); @@ -372,7 +547,7 @@ void bind(const endpoint_type& endpoint) { asio::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); asio::detail::throw_error(ec, "bind"); } @@ -388,7 +563,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), 12345); * acceptor.open(endpoint.protocol()); * asio::error_code ec; @@ -399,10 +574,11 @@ * } * @endcode */ - asio::error_code bind(const endpoint_type& endpoint, + ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, asio::error_code& ec) { - return this->get_service().bind(this->get_implementation(), endpoint, ec); + impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Place the acceptor into the state where it will listen for new @@ -415,10 +591,10 @@ * * @throws asio::system_error Thrown on failure. */ - void listen(int backlog = socket_base::max_connections) + void listen(int backlog = socket_base::max_listen_connections) { asio::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); + impl_.get_service().listen(impl_.get_implementation(), backlog, ec); asio::detail::throw_error(ec, "listen"); } @@ -434,19 +610,20 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; - * acceptor.listen(asio::socket_base::max_connections, ec); + * acceptor.listen(asio::socket_base::max_listen_connections, ec); * if (ec) * { * // An error occurred. * } * @endcode */ - asio::error_code listen(int backlog, asio::error_code& ec) + ASIO_SYNC_OP_VOID listen(int backlog, asio::error_code& ec) { - return this->get_service().listen(this->get_implementation(), backlog, ec); + impl_.get_service().listen(impl_.get_implementation(), backlog, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Close the acceptor. @@ -462,7 +639,7 @@ void close() { asio::error_code ec; - this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "close"); } @@ -478,7 +655,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * acceptor.close(ec); @@ -488,20 +665,62 @@ * } * @endcode */ - asio::error_code close(asio::error_code& ec) + ASIO_SYNC_OP_VOID close(asio::error_code& ec) { - return this->get_service().close(this->get_implementation(), ec); + impl_.get_service().close(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } - /// (Deprecated: Use native_handle().) Get the native acceptor representation. + /// Release ownership of the underlying native acceptor. /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_type native() + * This function causes all outstanding asynchronous accept operations to + * finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. Ownership of the + * native acceptor is then transferred to the caller. + * + * @throws asio::system_error Thrown on failure. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release() + { + asio::error_code ec; + native_handle_type s = impl_.get_service().release( + impl_.get_implementation(), ec); + asio::detail::throw_error(ec, "release"); + return s; + } + + /// Release ownership of the underlying native acceptor. + /** + * This function causes all outstanding asynchronous accept operations to + * finish immediately, and the handlers for cancelled operations will be + * passed the asio::error::operation_aborted error. Ownership of the + * native acceptor is then transferred to the caller. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note This function is unsupported on Windows versions prior to Windows + * 8.1, and will fail with asio::error::operation_not_supported on + * these platforms. + */ +#if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \ + && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) + __declspec(deprecated("This function always fails with " + "operation_not_supported when used on Windows versions " + "prior to Windows 8.1.")) +#endif + native_handle_type release(asio::error_code& ec) { - return this->get_service().native_handle(this->get_implementation()); + return impl_.get_service().release(impl_.get_implementation(), ec); } /// Get the native acceptor representation. @@ -512,7 +731,7 @@ */ 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. @@ -526,7 +745,7 @@ void cancel() { asio::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); asio::detail::throw_error(ec, "cancel"); } @@ -538,9 +757,10 @@ * * @param ec Set to indicate what error occurred, if any. */ - asio::error_code cancel(asio::error_code& ec) + ASIO_SYNC_OP_VOID cancel(asio::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + impl_.get_service().cancel(impl_.get_implementation(), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Set an option on the acceptor. @@ -558,7 +778,7 @@ * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option(true); * acceptor.set_option(option); @@ -568,7 +788,7 @@ void set_option(const SettableSocketOption& option) { asio::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "set_option"); } @@ -587,7 +807,7 @@ * @par Example * Setting the SOL_SOCKET/SO_REUSEADDR option: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option(true); * asio::error_code ec; @@ -599,11 +819,11 @@ * @endcode */ template - asio::error_code set_option(const SettableSocketOption& option, + ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, asio::error_code& ec) { - return this->get_service().set_option( - this->get_implementation(), option, ec); + impl_.get_service().set_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get an option from the acceptor. @@ -621,7 +841,7 @@ * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option; * acceptor.get_option(option); @@ -629,10 +849,10 @@ * @endcode */ template - void get_option(GettableSocketOption& option) + void get_option(GettableSocketOption& option) const { asio::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); asio::detail::throw_error(ec, "get_option"); } @@ -651,7 +871,7 @@ * @par Example * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::reuse_address option; * asio::error_code ec; @@ -664,11 +884,11 @@ * @endcode */ template - asio::error_code get_option(GettableSocketOption& option, - asio::error_code& ec) + ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, + asio::error_code& ec) const { - return this->get_service().get_option( - this->get_implementation(), option, ec); + impl_.get_service().get_option(impl_.get_implementation(), option, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Perform an IO control command on the acceptor. @@ -685,7 +905,7 @@ * @par Example * Getting the number of bytes ready to read: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::non_blocking_io command(true); * socket.io_control(command); @@ -695,7 +915,7 @@ void io_control(IoControlCommand& command) { asio::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); asio::detail::throw_error(ec, "io_control"); } @@ -713,7 +933,7 @@ * @par Example * Getting the number of bytes ready to read: * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::acceptor::non_blocking_io command(true); * asio::error_code ec; @@ -725,11 +945,11 @@ * @endcode */ template - asio::error_code io_control(IoControlCommand& command, + ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, asio::error_code& ec) { - return this->get_service().io_control( - this->get_implementation(), command, ec); + impl_.get_service().io_control(impl_.get_implementation(), command, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the acceptor. @@ -745,7 +965,7 @@ */ 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. @@ -764,7 +984,7 @@ void non_blocking(bool mode) { asio::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); asio::detail::throw_error(ec, "non_blocking"); } @@ -781,11 +1001,11 @@ * operations. Asynchronous operations will never fail with the error * asio::error::would_block. */ - asio::error_code non_blocking( + ASIO_SYNC_OP_VOID non_blocking( bool mode, asio::error_code& ec) { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Gets the non-blocking mode of the native acceptor implementation. @@ -804,7 +1024,7 @@ */ 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. @@ -825,8 +1045,8 @@ void native_non_blocking(bool mode) { asio::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); asio::detail::throw_error(ec, "native_non_blocking"); } @@ -845,11 +1065,12 @@ * function fails with asio::error::invalid_argument, as the * combination does not make sense. */ - asio::error_code native_non_blocking( + ASIO_SYNC_OP_VOID native_non_blocking( bool mode, asio::error_code& ec) { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); + impl_.get_service().native_non_blocking( + impl_.get_implementation(), mode, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Get the local endpoint of the acceptor. @@ -862,7 +1083,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); * @endcode @@ -870,8 +1091,8 @@ endpoint_type local_endpoint() const { asio::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); asio::detail::throw_error(ec, "local_endpoint"); return ep; } @@ -888,7 +1109,7 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... * asio::error_code ec; * asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); @@ -900,9 +1121,105 @@ */ endpoint_type local_endpoint(asio::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 + /// pending error conditions. + /** + * This function is used to perform a blocking wait for an acceptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor state. + * + * @par Example + * Waiting for an acceptor to become readable. + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.wait(asio::ip::tcp::acceptor::wait_read); + * @endcode + */ + void wait(wait_type w) + { + asio::error_code ec; + impl_.get_service().wait(impl_.get_implementation(), w, ec); + asio::detail::throw_error(ec, "wait"); + } + + /// Wait for the acceptor to become ready to read, ready to write, or to have + /// pending error conditions. + /** + * This function is used to perform a blocking wait for an acceptor to enter + * a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor state. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * Waiting for an acceptor to become readable. + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::error_code ec; + * acceptor.wait(asio::ip::tcp::acceptor::wait_read, ec); + * @endcode + */ + ASIO_SYNC_OP_VOID wait(wait_type w, asio::error_code& ec) + { + impl_.get_service().wait(impl_.get_implementation(), w, ec); + 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. + /** + * This function is used to perform an asynchronous wait for an acceptor to + * enter a ready to read, write or error condition state. + * + * @param w Specifies the desired acceptor 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 asio::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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void wait_handler(const asio::error_code& error) + * { + * if (!error) + * { + * // Wait succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_wait( + * asio::ip::tcp::acceptor::wait_read, + * wait_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(WaitHandler, + void (asio::error_code)) + async_wait(wait_type w, ASIO_MOVE_ARG(WaitHandler) handler) + { + return async_initiate( + initiate_async_wait(), handler, this, w); } +#if !defined(ASIO_NO_EXTENSIONS) /// Accept a new connection. /** * This function is used to accept a new connection from a peer into the @@ -915,18 +1232,20 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * acceptor.accept(socket); * @endcode */ - template - void accept(basic_socket& peer, - typename enable_if::value>::type* = 0) + template + void accept(basic_socket& peer, + typename enable_if< + is_convertible::value + >::type* = 0) { asio::error_code ec; - this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); asio::detail::throw_error(ec, "accept"); } @@ -943,9 +1262,9 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... - * asio::ip::tcp::soocket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::error_code ec; * acceptor.accept(socket, ec); * if (ec) @@ -954,14 +1273,16 @@ * } * @endcode */ - template - asio::error_code accept( - basic_socket& peer, - asio::error_code& ec, - typename enable_if::value>::type* = 0) + template + ASIO_SYNC_OP_VOID accept( + basic_socket& peer, asio::error_code& ec, + typename enable_if< + is_convertible::value + >::type* = 0) { - return this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, static_cast(0), ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. @@ -980,9 +1301,9 @@ * const asio::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 - * asio::io_service::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 asio::post(). * * @par Example * @code @@ -996,26 +1317,24 @@ * * ... * - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * acceptor.async_accept(socket, accept_handler); * @endcode */ - template + template ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (asio::error_code)) - async_accept(basic_socket& peer, + async_accept(basic_socket& peer, ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::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. - ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - ASIO_MOVE_CAST(AcceptHandler)(handler)); + typename enable_if< + is_convertible::value + >::type* = 0) + { + return async_initiate( + initiate_async_accept(), handler, this, + &peer, static_cast(0)); } /// Accept a new connection and obtain the endpoint of the peer @@ -1034,19 +1353,19 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint; * acceptor.accept(socket, endpoint); * @endcode */ - template - void accept(basic_socket& peer, + template + void accept(basic_socket& peer, endpoint_type& peer_endpoint) { asio::error_code ec; - this->get_service().accept(this->get_implementation(), + impl_.get_service().accept(impl_.get_implementation(), peer, &peer_endpoint, ec); asio::detail::throw_error(ec, "accept"); } @@ -1067,9 +1386,9 @@ * * @par Example * @code - * asio::ip::tcp::acceptor acceptor(io_service); + * asio::ip::tcp::acceptor acceptor(my_context); * ... - * asio::ip::tcp::socket socket(io_service); + * asio::ip::tcp::socket socket(my_context); * asio::ip::tcp::endpoint endpoint; * asio::error_code ec; * acceptor.accept(socket, endpoint, ec); @@ -1079,13 +1398,13 @@ * } * @endcode */ - template - asio::error_code accept( - basic_socket& peer, + template + ASIO_SYNC_OP_VOID accept(basic_socket& peer, endpoint_type& peer_endpoint, asio::error_code& ec) { - return this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); + impl_.get_service().accept( + impl_.get_implementation(), peer, &peer_endpoint, ec); + ASIO_SYNC_OP_VOID_RETURN(ec); } /// Start an asynchronous accept. @@ -1110,23 +1429,946 @@ * const asio::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 - * asio::io_service::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 asio::post(). */ - template + template ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (asio::error_code)) - async_accept(basic_socket& peer, + async_accept(basic_socket& peer, endpoint_type& peer_endpoint, ASIO_MOVE_ARG(AcceptHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + return async_initiate( + initiate_async_accept(), handler, this, &peer, &peer_endpoint); + } +#endif // !defined(ASIO_NO_EXTENSIONS) + +#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// 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. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + typename Protocol::socket accept() + { + asio::error_code ec; + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + 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 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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept(ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept(asio::error_code& ec) + { + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + return peer; + } - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, ASIO_MOVE_CAST(AcceptHandler)(handler)); + /// 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 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 asio::error_code& error, // Result of operation. + * 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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(ASIO_MOVE_ARG(MoveAcceptHandler) handler) + { + return async_initiate( + initiate_async_move_accept(), handler, this, + impl_.get_executor(), static_cast(0), + static_cast(0)); } + + /// 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, + typename enable_if< + is_executor::value + >::type* = 0) + { + asio::error_code ec; + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + 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 context The I/O execution context object to be used for the newly + * accepted socket. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept()); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, + typename enable_if< + is_convertible::value + >::type* = 0) + { + asio::error_code ec; + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other peer(context); + impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); + 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 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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, asio::error_code& ec, + typename enable_if< + is_executor::value + >::type* = 0) + { + typename Protocol::socket::template + rebind_executor::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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, asio::error_code& ec, + typename enable_if< + is_convertible::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. + /** + * 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 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 + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const asio::error_code& error, // Result of operation. + * 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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(my_context2, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, + typename Protocol::socket::template rebind_executor< + Executor1>::other)) + async_accept(const Executor1& ex, + ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_executor::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + Executor1>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + ex, static_cast(0), + static_cast(0)); + } + + /// 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 asio::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 asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * acceptor.async_accept(my_context2, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other)) + async_accept(ExecutionContext& context, + ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + context.get_executor(), static_cast(0), + static_cast(0)); + } + + /// 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 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket(acceptor.accept(endpoint)); + * @endcode + */ + typename Protocol::socket accept(endpoint_type& peer_endpoint) + { + asio::error_code ec; + typename Protocol::socket peer(impl_.get_executor()); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + 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 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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + typename Protocol::socket accept( + endpoint_type& peer_endpoint, asio::error_code& 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. + /** + * 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 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 asio::error_code& error, // Result of operation. + * 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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(endpoint, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, typename Protocol::socket)) + async_accept(endpoint_type& peer_endpoint, + ASIO_MOVE_ARG(MoveAcceptHandler) handler) + { + return async_initiate( + initiate_async_move_accept(), handler, this, + impl_.get_executor(), &peer_endpoint, + static_cast(0)); + } + + /// 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 + * remote peer will be written. + * + * @returns A socket object representing the newly accepted connection. + * + * @throws asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint)); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const Executor1& ex, endpoint_type& peer_endpoint, + typename enable_if< + is_executor::value + >::type* = 0) + { + asio::error_code ec; + typename Protocol::socket::template + rebind_executor::other peer(ex); + impl_.get_service().accept(impl_.get_implementation(), + peer, &peer_endpoint, ec); + 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 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 asio::system_error Thrown on failure. + * + * @par Example + * @code + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint)); + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, endpoint_type& peer_endpoint, + typename enable_if< + is_convertible::value + >::type* = 0) + { + asio::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); + 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 + * 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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor::other + accept(const executor_type& ex, + endpoint_type& peer_endpoint, asio::error_code& ec, + typename enable_if< + is_executor::value + >::type* = 0) + { + typename Protocol::socket::template + rebind_executor::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 + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * asio::ip::tcp::socket socket( + * acceptor.accept(my_context2, endpoint, ec)); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other + accept(ExecutionContext& context, + endpoint_type& peer_endpoint, asio::error_code& ec, + typename enable_if< + is_convertible::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. + /** + * 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 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 + * 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 asio::error_code& error, // Result of operation. + * 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. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(my_context2, endpoint, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, + typename Protocol::socket::template rebind_executor< + Executor1>::other)) + async_accept(const Executor1& ex, endpoint_type& peer_endpoint, + ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_executor::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + Executor1>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + ex, &peer_endpoint, + static_cast(0)); + } + + /// 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 asio::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 asio::post(). + * + * @par Example + * @code + * void accept_handler(const asio::error_code& error, + * asio::ip::tcp::socket peer) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * asio::ip::tcp::acceptor acceptor(my_context); + * ... + * asio::ip::tcp::endpoint endpoint; + * acceptor.async_accept(my_context2, endpoint, accept_handler); + * @endcode + */ + template + ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, + void (asio::error_code, + typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other)) + async_accept(ExecutionContext& context, + endpoint_type& peer_endpoint, + ASIO_MOVE_ARG(MoveAcceptHandler) handler, + typename enable_if< + is_convertible::value + >::type* = 0) + { + typedef typename Protocol::socket::template rebind_executor< + typename ExecutionContext::executor_type>::other other_socket_type; + + return async_initiate( + initiate_async_move_accept(), handler, this, + context.get_executor(), &peer_endpoint, + static_cast(0)); + } +#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + +private: + // Disallow copying and assignment. + basic_socket_acceptor(const basic_socket_acceptor&) ASIO_DELETED; + basic_socket_acceptor& operator=( + const basic_socket_acceptor&) ASIO_DELETED; + + struct initiate_async_wait + { + template + void operator()(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. + ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(ASIO_MOVE_ARG(AcceptHandler) handler, + basic_socket_acceptor* self, basic_socket* 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. + ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + + detail::non_const_lvalue 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 + void operator()(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. + ASIO_MOVE_ACCEPT_HANDLER_CHECK( + MoveAcceptHandler, handler, Socket) type_check; + + detail::non_const_lvalue 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(ASIO_WINDOWS_RUNTIME) + detail::io_object_impl< + detail::null_socket_service, Executor> impl_; +#elif defined(ASIO_HAS_IOCP) + detail::io_object_impl< + detail::win_iocp_socket_service, Executor> impl_; +#else + detail::io_object_impl< + detail::reactive_socket_service, Executor> impl_; +#endif }; } // namespace asio diff -Nru galera-4-26.4.11/asio/asio/basic_socket_iostream.hpp galera-4-26.4.14/asio/asio/basic_socket_iostream.hpp --- galera-4-26.4.11/asio/asio/basic_socket_iostream.hpp 2022-02-09 11:02:02.000000000 +0000 +++ galera-4-26.4.14/asio/asio/basic_socket_iostream.hpp 2023-02-24 08:38:48.000000000 +0000 @@ -2,7 +2,7 @@ // basic_socket_iostream.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the 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,6 @@ #include #include #include "asio/basic_socket_streambuf.hpp" -#include "asio/stream_socket_service.hpp" #if !defined(ASIO_HAS_VARIADIC_TEMPLATES) @@ -33,8 +32,7 @@ // explicit basic_socket_iostream(T1 x1, ..., Tn xn) // : std::basic_iostream( // &this->detail::socket_iostream_base< -// Protocol, StreamSocketService, Time, -// TimeTraits, TimerService>::streambuf_) +// Protocol, Clock, WaitTraits>::streambuf_) // { // if (rdbuf()->connect(x1, ..., xn) == 0) // this->setstate(std::ios_base::failbit); @@ -43,14 +41,13 @@ # define ASIO_PRIVATE_CTR_DEF(n) \ template \ - explicit basic_socket_iostream(ASIO_VARIADIC_PARAMS(n)) \ + explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ : std::basic_iostream( \ &this->detail::socket_iostream_base< \ - Protocol, StreamSocketService, Time, \ - TimeTraits, TimerService>::streambuf_) \ + Protocol, Clock, WaitTraits>::streambuf_) \ { \ this->setf(std::ios_base::unitbuf); \ - if (rdbuf()->connect(ASIO_VARIADIC_ARGS(n)) == 0) \ + if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ @@ -66,9 +63,9 @@ # define ASIO_PRIVATE_CONNECT_DEF(n) \ template \ - void connect(ASIO_VARIADIC_PARAMS(n)) \ + void connect(ASIO_VARIADIC_BYVAL_PARAMS(n)) \ { \ - if (rdbuf()->connect(ASIO_VARIADIC_ARGS(n)) == 0) \ + if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \ this->setstate(std::ios_base::failbit); \ } \ /**/ @@ -82,69 +79,156 @@ // 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 +template class socket_iostream_base { protected: - basic_socket_streambuf streambuf_; + socket_iostream_base() + { + } + +#if defined(ASIO_HAS_MOVE) + socket_iostream_base(socket_iostream_base&& other) + : streambuf_(std::move(other.streambuf_)) + { + } + + socket_iostream_base(basic_stream_socket s) + : streambuf_(std::move(s)) + { + } + + socket_iostream_base& operator=(socket_iostream_base&& other) + { + streambuf_ = std::move(other.streambuf_); + return *this; + } +#endif // defined(ASIO_HAS_MOVE) + + basic_socket_streambuf streambuf_; }; -} +} // namespace detail -/// Iostream interface for a socket. +#if !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL) +#define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL + +// Forward declaration with defaulted arguments. template , #if defined(ASIO_HAS_BOOST_DATE_TIME) \ - || defined(GENERATING_DOCUMENTATION) - typename Time = boost::posix_time::ptime, - typename TimeTraits = asio::time_traits