49 Commits
0.1.0 ... 0.3.0

Author SHA1 Message Date
Sergey Abramchuk
79eca6ca5f Merge branch 'release/0.3.0' 2019-06-29 10:39:56 +03:00
Sergey Abramchuk
37dc5e024e Update readme file 2019-06-29 10:39:09 +03:00
Sergey Abramchuk
1f03a43003 Update podspec 2019-06-29 10:38:03 +03:00
Sergey Abramchuk
0b94df103a Update version number 2019-06-29 10:34:49 +03:00
Sergey Abramchuk
d950779014 Merge branch 'feature/update-dependencies' into develop 2019-06-17 10:49:45 +03:00
Sergey Abramchuk
7d2bd2a1cf Apply asio patch 2019-06-17 10:17:40 +03:00
Sergey Abramchuk
a76165a23e Merge commit '9ec9e579e9efef1fa749d215ed103eab824b5901' into feature/update-dependencies
# Conflicts:
#	Sources/OpenVPNAdapter/Libraries/Vendors/asio/asio/include/asio/basic_socket.hpp
2019-06-17 09:52:27 +03:00
Sergey Abramchuk
9ec9e579e9 Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/asio/' changes from b3d2ab7255..90f32660cd
90f32660cd asio version 1.13.0 released
eb99518b32 Remove ASIO_ENABLE_OLD_SERVICES from documentation.
a8d0c39c92 Revision history.
efac12f649 Change default _WIN32_WINNT value to 0x0601 (Windows 7).
5bb3cf5c61 Bump minimum MSVC version for ASIO_HAS_DECLTYPE.
233254304b Add more missing entries to quick reference.
b439f14af8 Default to standalone build unless boost is explicitly specified.
0b5f03b4b7 Suppress various unused variable warnings.
ab174ab000 Don't overwrite a failure error code from the SSL engine when doing sync I/O.
45abc54125 Fix up dispatch() documentation. Clarify distinction between post() and defer().
c7d4557434 Add new cpp14 examples to doc.
b53662939f Fix template argument list bracketing.
c47c05ad31 Regenerate documentation.
265e75cdbb Define ASIO_STANDALONE automatically if C++11 or later is detected.
189a5b1453 Update composed operations examples to use async_initiate and a new helper function async_compose.
296216a122 Fix handler tracking arguments in io_context implementation.
b823ee0954 Only enable <atomic> for the most recent Xcode clang version.
54c93f73e7 Fix cross references.
32c9da2551 Fix typo in basic_stream_socket documentation.
66095aa1f2 Add new DynamicBuffer_v2 which is CopyConstructible.
d1a23c75b7 Use <atomic> when targeting apple/clang/libc++, even for C++03.
c585bdf3c9 Reduce number of copies of I/O executor.
5d9d01729d Move rather than copy buffers when moving a composed operation implementation.
2c7d26454b Completion conditions now require move rather than copy.
93337cba7b Add a fallback error code for when we get SSL_ERROR_SYSCALL without an associated error.
760e12ae22 Exclude implementation details from documentation.
0557b6ddf0 Fix parameter documentation in basic_object_handle constructor.
dc477ae51a Add ip::resolver_base to quick reference and cross reference it from ip::basic_resolver.
0a6bcd89bb Suppress eof on shutdown as it actually indicates success.
57b2ef19b0 Ensure SSL handshake errors are propagated to the peer.
93104538f6 Add noexcept to buffer_sequence_begin/end.
7c7a2555b0 Prevent implicit conversion with buffer_sequence_begin/end.
fff63d15a7 Add a make_strand function.
52eef463ef Remove experimental directory from documentation processing.
2b18f00f48 Fix long line.
536df5fd74 Deduce EndpointSequence iterator type.
bc7e0f38cf Fix calculation of absolute timeout when using pthread_cond_timedwait.
30e38527a4 Capture port by value to prevent dangling reference.
2ee7a65253 Add network_v[46].hpp headers to top-level convenience header.
1c9a4ac338 Allow visibility pragmas to be disabled by defining ASIO_DISABLE_VISIBILITY.
38d3fc09ab Add -lnetwork to LDFLAGS when building for Haiku OS.
0616f498bf Include unistd.h when targeting Haiku OS.
a10d3595eb Also set SO_REUSEPORT on QNX to correctly enable multicast.
555ed6c993 Return correct number of bytes transferred when datagram truncation occurs.
3b0daafa0b Make the executor_work_guard move constructor noexcept.
1a7b0c7220 Don't allow thread_pool locking to be set by ASIO_CONCURRENCY_HINT_ macros.
51274de46a Update list of unit tests in MSVC makefile.
4e49b8c3e5 Disambiguate enable_if and native_handle_type.
ea67e69e3a Repeat typedefs in derived class templates to fix gcc compile error on Windows.
490743a662 Promote coroutines TS support classes to asio namespace.
171a02ed0d Added constructor for local::basic_endpoint from string_view
6f40eb3155 Add noexcept qualifier to ip::basic_endpoint class.
3b4bf13bd1 Add noexcept qualifier to ip::address_v6 class.
b5b9717ed6 Add noexcept qualifier to ip::address_v4 class.
39993b3ec2 Add noexcept qualifier to ip::address class.
e7b397142a Update windows::overlapped_ptr to support custom I/O executors.
84e9a48ae6 Fix completion signatures used for ssl::stream's async_handshake and async_shutdown.
24e92ea209 Change archetype completion token's handler to require exact signature.
498dab4662 Fix compile error in serialization example.
62c4488abc New async_result form with initiate() static member function.
fc05ce407c Remove deprecated handler_type and single-argument async_result.
f9e4489b57 Update copyright notices.
cbe1c5e13d Add custom I/O executor support to I/O objects.
2c689adc90 Remove deprecated get_io_context and get_io_service functions.
9801132ea0 Remove deprecated services support.
531475f46c Use separate recycled memory slot for polymorphic executor.
22afb86087 asio version 1.12.2 released
7a566ad1e5 Ensure socks4 example header file is included in release tarball.
9d54ba058e Revision history.
b3a3961047 Fix example links.
765f197ed6 Add examples showing how to write composed operations.
11fe8b7c7e Add documentation for change in concurrency_hint type.
fd5a89b004 Regenerate documentation.
d6209b6c73 Add C++11 version of SOCKS4 example.
e7dbfcecb8 Fix long lines.
a452dfd43b Add C++11 version of SSL example.
dd006b867e Add C++11 version of timers example.
caa9450231 Add C++11 versions of timeouts examples.
019449fb0f Use new form of async_accept where socket is moved into the completion handler.
a432abc27e Execution contexts must be publicly derived from asio::execution_context.
4d7d624970 Make distinction between overloads clearer.
8c5004b100 Indicate replacements for deprecated overloads.
f03803ea8b Fix brief description of buffer() overload for non-const std::string.
eed287d46c Fix detection of std::future with libstdc++.
e0daf291bc Fix compile error in regex overload of read_until.
ff28c6f777 Clear the heap index for removed timers.
68df16d560 Fix detection of std::experimental::string_view and std::string_view with newer clang/libc++.
c7d2467be2 Add compile-time test for TLSv1 presence.
2c6b6db640 Fix macro used to test for TLS v1.2 support.
14c0108b2c Fix typo in ssl::stream::async_write_some documentation.
ed775a2ef1 Fix incorrect reference to 'io_context' in thread_pool documentation.
f5440aa76e Fix MSVC version number for availability of std::invoke_result.
b397659ded Test language version using _MSVC_LANG rather than _HAS_CXX17.
2e30e9d327 Update buffer sequence traits to test new requirements, if decltype is available.
a591f818f2 Define buffer sequence traits after buffer_sequence_begin/end has been defined.
6d2b56aafa Fix MSVC issue when building with exceptions disabled.
42a94f7cb4 Add options for TLS v1.3.
91b2dcf43d Fix typo in 'Streams, Short Reads and Short Writes' documentation section.
5cb855d024 Prevent global objects from being created once per thread on Windows.
414cdf4f83 Use heading elements to keep asynchronous requirements on one page.
a3f713e393 Fix crash when using size(), max_size() or empty() on default-constructed resolver results.
912d0d67f9 Move the return value in basic_resolver_results::begin() to avoid copying.
83e24fa04f Don't use BOOST_VERSION macro in standalone mode.
98e0bf115a ASIO_HAS_DECL_TYPE should be ASIO_HAS_DECLTYPE in is_buffer_sequence.hpp.
6554073823 Fix bug in deregister_handler in actor example.
547f06a1e4 Enable move support for the Intel Compiler.
0f9b727e9f Do not double define has_string_view with clang-cl
39a9be7786 Fix handler tracking operation name for io_context::executor_type::dispatch.
eed73f024d Fix buffer overflow when parsing an address string with a 64-bit scope id.
b73dc1d2c0 asio version 1.12.1 released
3d3bbae1b6 Add cpp17 examples to distribution.
157bdf2a87 Revision history.
5736e51cf5 Add Coroutines TS overview and examples to documentation.
b0926b61b0 Regenerate documentation.
5318eaafd6 Check for gthreads before enabling std::future with g++.
bf69d3f390 Need namespace cstd for sprintf.
a2992ace2c Remove accidentally added file.
5ddede1e25 Fix storage of decayed function and handler in spawn()-ed coroutine.
173871f855 Fixed compilation on Android NDK15+
450e65093b Fix basic_yield_context support for completion signatures with reference parameters.
bf70ad6062 Explicitly ignore result of iterator dereference.
479a0c51f4 Distinguish legacy completion handlers (which must be CopyConstructible).
d47931da7b Decay the DynamicBuffer type used in enable_if tests.
3c7bbe42ea Use std::string_view for C++17 or later, and std::experimental::string_view for C++14.
b4245aac24 Use std::invoke_result with recent MSVC.
1156fad4f0 Make add_certificate_authority process multiple certificates in a bundle
9a7ccb9bf3 Don't call SSL_COMP_free_compression_methods if SSL_OP_NO_COMPRESSION is defined.
129c654e3c Fix typo in detail::consuming_buffers specialisation.
37e32598cb Fix basic_resolver_results::value_type typedef.
5fdb48bd34 Add missing move in ssl asynchronous operation.
d31062f3fc Fix includes in some cpp11 and cpp14 examples
21e86ec26d Fix async_result when used with handler_type
68180a19ff Correct prepare_memfn_helper test
08c1955017 Detect C++11 and C++14 and automatically enable corresponding examples.
bca41a6b19 Regenerate list of installed header files.
6711b85da8 Update examples to use chrono rather than Boost.Date_Time.
d8387c93b3 Change socket iostreams to use chrono by default.
a918966260 Fix unit tests to compile when ASIO_NO_DEPRECATED is defined.
b9855c9fdb Update timeout examples to use latest features.
501dfc424a Ignore operations posted to a strand during shutdown.
7a39d8a7d9 Fix redirect_error to work with non-const error_codes.
25b8ff168a Add missing include of <sys/timerfd.h>.
2acd085dc4 Clean up some experimental::co_spawn examples.
8f39bf249f Ensure all coroutine layers are correctly attached to the 'stack'.
83c28c582f Add some more experimental::co_spawn examples.
af776b1522 Fix spurious resumption.
9a0585b63d Restrict the types that may be awaited.
daf25a7f4f Fix MSVC compile error.
5680bbb24b Fix namespace qualification issues.
d4848c3cc4 Allow the awaitable to be stored and co_await applied to it later.
4cdff8b803 Use memory recycling for awaitees.
ad1751063a Regenerate documentation.
1728c8fa42 Add experimental features to documentation.
51dcdb7d93 Fix up make_work_guard ambiguity.
80c6f596c8 Add experimental::co_spawn examples.
4e58a1b8ad Add new experimental directory to boostify script.
32cd6fdfa7 Add convenience header for experimental features.
ea40e78451 Add new experimental::co_spawn function.
be369c9789 Add new experimental::redirect_error completion token type.
15ae0bb7a6 Add new experimental::detached_t completion token type.
7b2d186ced Add missing const qualification to acceptor's get_option members.
66a1943c55 Work around a mysterious parsing error that occurs with some versions of gcc.
4ebd33ce55 Update copyright notices.

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/asio
git-subtree-split: 90f32660cd503494b3707840cfbd5434d8e9dabe
2019-06-17 09:46:13 +03:00
Sergey Abramchuk
1c8f34560f Merge commit '5edb23a7abbffb2ec7874d0352b993e1b4193374' into feature/update-dependencies 2019-06-17 09:44:01 +03:00
Sergey Abramchuk
5edb23a7ab Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from daf575ff50..275cf80efb
275cf80efb mac/tuncli: Don't take address of temporary error.
1406187bfc tun/win/tunutil: Don't auto& a temporary iterator.
fe7f984c5d ip/ping6: Use _WIN32, not _MSC_VER (to fix MinGW).
03a906771e win: add OpenSSL as solution configuration
89cc11b300 win: enable building Windows client with OpenSSL
febb24e7d9 openssl/compat.hpp: remove functions already defined in OpenSSL
0833eb1f76 linux/tunsetup: Fix missing asio/errinfo declaration
d54b742910 linux: Improve cpu_time() using glibc/kernel methods
a55fe2b554 tests: Added unit test for linux/cputime.hpp
e33a00e6de [OVPN3-431] agent: Wintun support for agent
42592eb1b1 appveyor: initial commit
3e3f2078e6 win: rename env var in project file
a2496a3616 Wintun: experimental support
58a7866b45 build script: added OPENSSL_DIST parameter to specify a custom OpenSSL build
288ea0277e OpenSSLContext: SSL_CTX_set_ecdh_auto() becomes a no-op in OpenSSL 1.1, so #ifdef out to avoid compiler warnings
3ef5059fa6 TLSSessionTicketBase: removed the ERROR symbol from a local enum in case it conflicts with a global preprocessor symbol
3364ed76b8 TLSSessionTicketBase: removed trailing comma from Status enum
025c7bad88 mbedtls/sslctx: Fix missing override in virtual methods
6cb3243681 mbedTLS: ssl() method accepting hostname should check if it is null
ca31da7d28 bio_memq_stream.hpp: fixed multi-thread race (introduced with OpenSSL 1.1 support) using init_static() approach
2deb402223 OpenSSLContext::tls_ticket_key_callback: get self with SSL_get_ex_data instead of ssl->ctx->app_verify_arg
eec139a100 MSF::find: renamed template type names to avoid conflict with preprocessor symbol (ITER) in test/ssl/proto.cpp
1024d37f33 str_neq: fixed bug where neq was not initialized
c00b6f6302 Listen::List: refactored and extended expand_ports()
448c549a0b cpu_time(): added bool thread parameter to return CPU time of current thread (instead of process)
868801d7d9 Linux library: added cpu_time() method to return the CPU time of the current process
964d2cd428 SSL layer: added did_full_handshake() method and implemented for OpenSSL
dd18d6c806 crypto::str_neq: use atomic_thread_fence(std::memory_order_acq_rel) instead of OPENVPN_COMPILER_FENCE
6a30af9528 OpenSSLSessionCache: use map instead of unordered_map
3ecbcbc81b OptionList: fixed compile errors that occur when get_num<T>() is used with a const type
72e9f858e4 SSL: added SSLConst::PEER_CERT_OPTIONAL flag and implemented for OpenSSL
33f15c8840 OpenSSL: use OPENSSL_VERSION_NUMBER instead of SSLEAY_VERSION_NUMBER
cadb712ea9 ProfileMerge: added "static-key" to is_fileref_directive()
85befa316a TLS session tickets: work around an issue in OpenSSL session ticket keying callback
f43c4c1440 TLSSessionTicketBase: misc fixes/enhancements
c5f4d59d39 OpenSSLContext: added missing X509_free() to rebuild_authcert()
658fcc50eb OptionList: added get_num methods with min/max but no default
162eeaa485 SSL layer: added RFC 5077 TLS session resumption ticket support
e0a821ddd6 OpenSSLContext: use C++11 member initializers
1ea5acce3c OpenSSLContext: minor changes to handshake_details()
74c0a4f995 string: added copy_fill() method
3e5921c06d AuthCert: added is_uninitialized() method
3d6b6b2319 library: added convenience method MSF::find() for maps/sets
18f5f4d1b5 SSLConfigAPI: remove set_enable_renegotiation()
18dcfd616c Added crypto::str_neq() function for securely comparing variable-length strings
4fc5725b9e RunContext: added get_servers() method
ae22f155fd server: determine when server-side session ID should be preserved on soon-to-be-closed connections
5e34759d50 client: HALT/RESTART message was not properly purging the Session ID when required
e1647eb407 Fix builds with GCC 4.8 compilers
b55f78dd1d test_sitnl.cpp: account for old iptools output
236d39258b Allow overriding DEP_DIR by environment variable
d56e049ea4 Refactor dependencies to be in a cmake script
e9dc75ec90 sitnl: add unit tests
faad8454be sitnl: pick the best gw by longest prefix and lowest metric
dfcc4bc437 [OVPN3-354] cli.cpp: support for round-robin DNS and redirect gw
8a502f3b61 [OVPN3-354] tun linux: support for round-robin DNS and redirect gw
c9315c7dc1 gwnetlink.hpp: specify destination when looking for gateway
89f091daf0 sitnl: implement interface filtering when looking for gateway
220de072a2 sitnl: support for multipart messages
5771dfc0ee transport: remove ip_hole_punch API
d448b4a7db tun/builder/client.hpp: use "override" method specifier
d85e92621d Make reproducible builds possible
7150f72e09 tun: remove code duplications in Linux tun implementations
8112f0cd7c [OVPN3-378] cli: support for TunBuilder API
6f0e9f6388 Fix Asio 0003 patch.
964662bacb Add /bigobj to build.py
74e40a8907 Upgrade ASIO to 0.13.0
a2713ce1f6 PureTLS: enable SNI by default when configuring client
19a44dbdda Merge branch 'qa'
a5fdf43726 InitProcess: comment clarification that crypto_init declaration causes SSL library init when instantiated
dec3bc140e OpenSSL: Revert a commit that breaks OpenSSL initialization
16a4e3d4a7 [OVPN3-405] asio: A quick fix for incorrect error message encoding
aa785c30c1 Fix Base64::UCharWrap compiler warnings
51a1469e6b Merge various fixes
218cfa39cb Explicitly disable TAP support when parsing configurations
3a0e768ecd Explicitly disable any potential TAP support
aba98471fc Fix base64 unit test with mbedtls and windows
9f84174f0b Add unit tests for Base64
017bc545ce Add base64 decode for void* data
452a353b2d Fix lzo build script to use it as dependency for the unit tests
dfdd528dc1 Convert unit test to Googletest
bd9ee482e6 Add copyright header to test_comp
059f20f2b2 Move compression unit test from common to core repository
5a024cde5c Added Snappy corpus for testing compression/decompression.
ec4d400933 Add compatibility functions for OpenSSL 1.1.0
9768562a01 OpenSSL 1.1: Add argument to external sign to specify algorithm
1bbd2cc78c OpenSSL 1.1: Replace RSA_F_RSA_EAY_PRIVATE_ENCRYPT with Openssl variant
c959a3cff0 OpenSSL 1.1: Replace remaining direct access to members
4307f024ca OpenSSL 1.1: And missing remaining compat implementations
3385c45151 OpenSSL 1.1: Use opaque pointer for HMAC_CTX
f29453f4ca OpenSSL 1.1: Add compat includes for HMAC
c107a1f6ab OpenSSL 1.1: Remove support for OpenSSL older than 1.0.0
024a10adc2 OpenSSL 1.1: Use EVP_MD_ctx as opaque pointer
35d82906c4 OpenSSL 1.1: Change EVP_CIPHER ctx field to pointer
ebf4b7e87d OpenSSL 1.1: Use X509_digest to get certificate digest
7d3e5d02f2 OpenSSL 1.1: Use SSL_get_ex_data instead of direct access
8717f822ca OpenSSL 1.1: Replace ctx->current with X509_STORE_CTX_get_current_cert
67fbe1ab3f OpenSSL 1.1: Use X509_check_purpose to check certificate types
7b5a92d58e OpenSSL 1.1: Change OpenSSL TLS version logic to match mbed TLS
c28b7d1893 OpenSSL 1.1: Adjust default OpenSSL cipher suites
f108044a09 OpenSSL 1.1: Add defines for TLS 1.3 in tlsver.hpp
ee1308b505 OpenSSL 1.1: Replace initialisation of RSA_meth with access method
905d681af1 OpenSSL 1.1: Use standard tls methods
cf28e4600c OpenSSL 1.1: Change BIO wrappers around to use access methods
5e6571163d OpenSSL 1.1: Implement compat methods for new BIO methods in 1.0.2
8837539a73 Use std::nothrow as argument for new
e6ec025932 Merge branch 'qa'
752a38c067 [OVPN3-397] size.hpp: wrap typedef in guards
d4e50f8c54 Merge branch 'qa'
d8d14e1991 [UCONNECT-1027] implement ResolveThread and ensure it is properly detachable
525a9a88a6 Merge branch qa
30ea53cb92 Replace custom memcpy implementation
de7c672ee7 Workaround for compiler bug in memneq
84fcecd5e7 Fix missing override annotation in udp/tcp/httpcli
1a3a69a496 [UCONNECT-1027] use one AsioWork object for the whole pre-resolve opertation
c4cbf93f9b Revert "[UCONNECT-1027] remotelist: create standalone object for resolve thread"
6ef089164e Allow unit tests to be also compiled with mbed TLS and on Windows
7c67bf7f50 Add unit tests for route emulation and establish common test suite
64a7b2f124 Add build file for core unit tests
0a0d080a49 Implement allowing local LAN access
2105b4b7c0 Fix Android route exclusion emulation

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn
git-subtree-split: 275cf80efb7a08adc920f7ca49075c776e596b08
2019-06-17 09:44:01 +03:00
Sergey Abramchuk
61c9e8f6dc Merge branch 'feature/fat-libraries' into develop 2019-06-17 09:26:47 +03:00
Sergey Abramchuk
206ce5eeb9 Update library search paths 2019-04-25 10:11:00 +03:00
Sergey Abramchuk
e77c8a7994 Create fat iOS library for mbedtls 2019-04-25 10:07:31 +03:00
Sergey Abramchuk
838184dcae Create fat iOS library for lz4 2019-04-25 10:01:22 +03:00
Sergey Abramchuk
36de2fc09c Merge branch 'release/0.2.0' 2019-04-10 12:21:10 +03:00
Sergey Abramchuk
90fbbbea65 Merge tag '0.2.0' into develop
no message
2019-04-10 12:21:10 +03:00
Sergey Abramchuk
45723d7ee1 Delete outdated revisions 2019-04-10 12:18:05 +03:00
Sergey Abramchuk
f3caddf509 Update Acknowledgments section 2019-04-10 12:16:40 +03:00
Sergey Abramchuk
f0844e998f Update Usage section 2019-04-10 12:14:04 +03:00
Sergey Abramchuk
208d87f258 Fix typos 2019-04-10 12:02:56 +03:00
Sergey Abramchuk
b38a8050e0 Update version in Cocoapods section 2019-04-10 12:02:42 +03:00
Sergey Abramchuk
7b2320fbe3 Update podspec 2019-04-10 11:59:05 +03:00
Sergey Abramchuk
9eac433665 Bump version number 2019-04-10 11:53:08 +03:00
Sergey Abramchuk
b00951ceae Update project settings 2019-04-10 11:50:13 +03:00
Sergey Abramchuk
bd98a18fb3 Merge branch 'feature/reset-tunnel' into develop 2019-03-18 13:16:17 +03:00
Sergey Abramchuk
4e2bb966c2 Merge branch 'develop' into feature/reset-tunnel
* develop:
  Fix incorrect architecture of libraries
2019-03-18 11:21:31 +03:00
Sergey Abramchuk
6766fb52f9 Fix incorrect architecture of libraries 2019-03-18 11:21:23 +03:00
Sergey Abramchuk
74f56bf680 Merge branch 'develop' into feature/reset-tunnel
* develop:
  Explicitly set the define to use <string_view>
  Apply asio patches
  Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from 934f4e741f..daf575ff50
2019-03-15 12:54:45 +03:00
Sergey Abramchuk
aa67ea253f Merge branch 'feature/update-dependencies' into develop 2019-03-15 12:53:18 +03:00
Sergey Abramchuk
9686d3295a Explicitly set the define to use <string_view> 2019-03-15 12:23:15 +03:00
Sergey Abramchuk
a58d48b88b Apply asio patches 2019-03-15 12:20:19 +03:00
Sergey Abramchuk
e9b9b66317 Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from 934f4e741f..daf575ff50
daf575ff50 Merge remote-tracking branch 'origin/qa'
e3a2425be4 [UCONNECT-1027] remotelist: create standalone object for resolve thread
e487b75860 async-resolve: use native GCD implementation on iOS
346ed043fa Merge remote-tracking branch 'origin/qa'
3f55dcd266 remotelist: add missing includes
073b3993f4 Fix commit 8b22a7b2 (mbed TLS compatibility)
8b22a7b209 Fix compatibility with mbed TLS < 2.7.0

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn
git-subtree-split: daf575ff5099eebb10109e52be94253507fd253b
2019-03-15 11:55:16 +03:00
Sergey Abramchuk
9243263fcd Merge commit 'e9b9b66317298258a27ad20c5a4ed7cac300acaa' into feature/update-dependencies 2019-03-15 11:55:16 +03:00
Sergey Abramchuk
9b51c260a1 Clear out tunPersist mentions 2019-02-24 16:10:45 +03:00
Sergey Abramchuk
4889f3b8cd Delete tunPersist property because tun builder doesn't use this option 2019-02-24 16:08:24 +03:00
Sergey Abramchuk
399ce8435d Reset tunnel on disconnect 2019-02-24 16:06:24 +03:00
Sergey Abramchuk
ed98f2568b Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from 6608878d5..934f4e741
934f4e741 Merge remote-tracking branch 'origin/qa'
8c87c7696 [UCONNECT-1027] use proper io_context when initializing AsyncResolve class
c3026c65a Merge remote-tracking branch 'origin/qa'
f33fe7665 [UCONNECT-1027] perform async DNS resolution in a detached thread
0c0af6781 [OVPN3-342] Generate ICMP "packet too big" reply
c93af60a7 Move files from ovpn3-common to openvpn3 repo
d5eeb78ed ClientAPI: print core version when starting
04de9c425 Merge branch 'qa'
2c0dbc6c3 buildep.py: add asio patching
600c68012 Allow updating auth-token during session
7391096b9 [OC-85] tunprop: exclude routes for additional remotes also on macOS
3587628d7 [OC-84] tunprop: exclude routes for additional remotes also on Windows
25471635d Revert "[UCONNECT-868] When no network is present pause instead of stopping"
5713ff34a Fixed some breakage caused by recent endian/ffs commits
a9ce44a22 endian.hpp: break out endian compile-time tests to endian_platform.hpp
72181f9e7 [UCONNECT-868] When no network is present pause instead of stopping
10d636cfe version: switch to 3.2

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn
git-subtree-split: 934f4e741f760160dc65a6f4b29af57bb5be8f93
2019-02-24 15:02:57 +03:00
Sergey Abramchuk
e7084c56c6 Merge commit 'ed98f2568b15d5548ef8f373b45a3f7078ce7a7e' into feature/update-dependencies 2019-02-24 15:02:57 +03:00
Sergey Abramchuk
72bf0c306d Update lz4 library to version 1.8.3 2019-02-24 15:01:59 +03:00
Sergey Abramchuk
16c2801168 Add retryOnAuthFailed property 2019-01-13 14:30:52 +03:00
Sergey Abramchuk
fa25b668e0 Add port property and test get/set its value 2019-01-13 14:24:25 +03:00
Sergey Abramchuk
b578e282f5 Update client methods and prepare it for remote overriding 2019-01-13 13:56:51 +03:00
Sergey Abramchuk
c514bf7312 Add new events: AUTH_PENDING, WARN, UNSUPPORTED_FEATURE 2019-01-13 13:36:25 +03:00
Sergey Abramchuk
ece80f63a9 Add TLS_CRYPT_META_FAIL error 2019-01-13 13:29:07 +03:00
Sergey Abramchuk
9c09e6f507 Merge commit 'f5fda0fa735dc13c5bd18362133467818921bb1b' into feature/update-dependencies 2019-01-13 13:08:43 +03:00
Sergey Abramchuk
f5fda0fa73 Squashed 'Sources/OpenVPNAdapter/Libraries/Vendors/openvpn/' changes from cc90cde57..6608878d5
6608878d5 [OVPN3-341] implement mssfix support
1bf3fc0e4 win: update project files
f8d209435 travis: update to default osx image: xcode9.4
31eb246a8 travis.yml: align deps version to lib-version
996f86635 RunContext: fixed rebase issue that added two "default: signal_rearm();" clauses
aebea6456 build script: minor changes to Cityhash inclusion
1d754072c modstat: make update_file_mod_time_nanoseconds() a no-op on non-Linux
7974c9867 Fixed some breakage caused by recent endian/ffs commits
a0dd7fe8b endian.hpp: break out endian compile-time tests to endian_platform.hpp
c8bdf5a34 ffs.hpp: support additional numeric types
dcb0c9452 BufferType: append() argument can now be a flexible buffer type
2009a8a25 Added AsioTimerSafe
39e71b7dd event_loop_wait_barrier: use a longer default timeout when running under valgrind
8b7e08e9b string::contains_non_space_ctrl: consider ASCII char 127 (DEL) to be a control char
e43024d7c RunContext: rearm non-terminating signals
6ab379323 write_binary_atomic: remove temporary file on move failure
55dc653cd path: added is_contained()
02bf235c6 Reverted previous commit: "ReplyParser: added undefined status"
84dbc5b9b Allow test/cli.cpp to be used with NetCfg Tunbuilder client
80fed2c55 Allow updating auth-token during session
ad7da751e don't print time in debug message and use OPENVPN_LOG_PROTO_VERBOSE
981407994 tls-crypt-v2: implement abstract metadata parser
be38bbeb8 tls-crypt-v2: test/ssl/proto.cpp - extend protocol test
60fcf374f tls-crypt-v2: implement WKc appending/unwrapping logic
51f4a3a29 tls-crypt-v2: introduce CONTROL_HARD_RESET_V3 packet type
156a6e58b tls-crypt-v2: implement client key parser and renderer
54a97b381 ssl: add support for encoding/decoding PEM format
f090fcda4 tls-crypt: make HMAC API more generic
d87f5bbc0 OpenSSL: init library
2ea88a93b Add Remote endpoint information to protect_socket call
0a081ee17 [OVPN3-315] cli/go: add option to compile SITNL component
5bbfb57c0 [OVPN3-315] TunLinux::Client: allow user to select netlink at compile time
e8458a68e [OVPN3-315] GW: add netlink support
4e77edb9e [OVPN3-315] TunLinux: add Netlink implementation for Tun setup methods
68508fe56 bigmutex: include missing extern.hpp header
a7b923e1e Fix logic inversion from commit 2de9aebc
923e10d13 runcontext: arrange members to allow inheritance
2de9aebc7 Replace deprecated mbedtls_sha1 with mbedtls_sha1_ret
e9c0bd00b Remove unused private field
ee17c33c2 Add virtual deconstructor to TransportClientParent
fab64ba0f Fix clang warning about unused attributes and missing overrides
2624d9ddf Also parse dhcp-option DNS6 as DNS server for compatibility with OpenVPN 2
6d12c9cc2 Refuse external pki with non RSA keys
4a25059f5 test/ovpncli: Don't override PROF env variable
f241c4c5f scripts: Add tool to update copyright years
27beeb03d Update lz4 version to 1.8.3
17e356858 Define DASIO_HAS_STD_STRING_VIEW on Android build
b107fd994 Remove unsupported platforms from Android build
6a200f72e Ensure all Android components are always installed
fbcd374a4 [OVPN3-327] OpenSSL: ensure >TLS1.0 is negotiated by default
d9b1f78b6 JSON: #define OPENVPN_JSON_INTERNAL when internal JSON library is used
39290f19d Fix build issues with #if macro on big-endian hardware
d4f62d9ed Fix instantiating a new URL instead of parsing the URL

git-subtree-dir: Sources/OpenVPNAdapter/Libraries/Vendors/openvpn
git-subtree-split: 6608878d57eec1c64c16c5a13ee65b2cf0418ca1
2019-01-13 13:08:42 +03:00
Sergey Abramchuk
008678734f Use full git path and tag in instruction 2018-10-27 14:06:11 +03:00
Sergey Abramchuk
1e010202f7 Delete comments 2018-10-27 13:14:49 +03:00
Sergey Abramchuk
4d36dbddd1 Merge tag '0.1.0' into develop
no message
2018-10-27 13:12:25 +03:00
1200 changed files with 96623 additions and 31976 deletions

View File

@@ -8,9 +8,9 @@ CLANG_CXX_LANGUAGE_STANDARD = gnu++14
CLANG_CXX_LIBRARY = libc++
VENDORS_DIR = $(PROJECT_DIR)/Sources/OpenVPNAdapter/Libraries/Vendors
HEADER_SEARCH_PATHS = "$(VENDORS_DIR)/asio/asio/include" "$(VENDORS_DIR)/lz4/include" "$(VENDORS_DIR)/mbedtls/include" "$(VENDORS_DIR)/openvpn"
LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(VENDORS_DIR)/lz4/lib/sim" "$(VENDORS_DIR)/mbedtls/lib/sim"
LIBRARY_SEARCH_PATHS[sdk=iphonesimulator*] = "$(VENDORS_DIR)/lz4/lib/ios" "$(VENDORS_DIR)/mbedtls/lib/ios"
LIBRARY_SEARCH_PATHS[sdk=iphoneos*] = "$(VENDORS_DIR)/lz4/lib/ios" "$(VENDORS_DIR)/mbedtls/lib/ios"
LIBRARY_SEARCH_PATHS[sdk=macosx*] = "$(VENDORS_DIR)/lz4/lib/macos" "$(VENDORS_DIR)/mbedtls/lib/macos"
OTHER_LDFLAGS = -lmbedtls -lmbedx509 -lmbedcrypto -llz4
OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER
OTHER_CPLUSPLUSFLAGS = $(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DASIO_HAS_STD_STRING_VIEW -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER
GCC_WARN_64_TO_32_BIT_CONVERSION = NO

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.0</string>
<string>0.3.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

4
NOTICE
View File

@@ -4,7 +4,6 @@ Third party libraries used by the OpenVPNAdapter project:
--------------------------------------------------------------------
Dependency: https://github.com/OpenVPN/openvpn3
Revision: 3e002c83ce2e9f9f40ddcee750d3cfa664238abe
License type: GNU Affero General Public License - Version 3.0
--------------------------------------------------------------------
OpenVPN Library
@@ -675,7 +674,6 @@ For more information on this, and how to apply and follow the GNU AGPL, see
--------------------------------------------------------------------
Dependency: https://github.com/ARMmbed/mbedtls
Revision: 72ea31b026e1fc61b01662474aa5125817b968bc
License type: Apache License - Version 2.0
--------------------------------------------------------------------
mbedTLS Library
@@ -886,7 +884,6 @@ limitations under the License.
--------------------------------------------------------------------
Dependency: https://github.com/chriskohlhoff/asio
Revision: 72ea31b026e1fc61b01662474aa5125817b968bc
License type: Boost Software License - Version 1.0
--------------------------------------------------------------------
ASIO Library
@@ -920,7 +917,6 @@ DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------
Dependency: https://github.com/lz4/lz4
Revision: c10863b98e1503af90616ae99725ecd120265dfb
License type: BSD 2-Clause License
--------------------------------------------------------------------
LZ4 Library

View File

@@ -3,7 +3,7 @@ Pod::Spec.new do |s|
# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
s.name = "OpenVPNAdapter"
s.version = "0.1.0"
s.version = "0.3.0"
s.summary = "Objective-C wrapper for OpenVPN library. Compatible with iOS and macOS."
s.description = <<-DESC
OpenVPNAdapter is an Objective-C framework that allows to easily configure and establish VPN connection using OpenVPN protocol.
@@ -143,7 +143,7 @@ Pod::Spec.new do |s|
openvpn.xcconfig = {
"HEADER_SEARCH_PATHS" => "${PODS_TARGET_SRCROOT}/#{openvpn_path}/**",
"OTHER_CPLUSPLUSFLAGS" => "$(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER"
"OTHER_CPLUSPLUSFLAGS" => "$(OTHER_CFLAGS) -DUSE_ASIO -DUSE_ASIO_THREADLOCAL -DASIO_STANDALONE -DASIO_NO_DEPRECATED -DASIO_HAS_STD_STRING_VIEW -DHAVE_LZ4 -DUSE_MBEDTLS -DOPENVPN_FORCE_TUN_NULL -DUSE_TUN_BUILDER"
}
end

View File

@@ -775,7 +775,7 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0820;
LastUpgradeCheck = 0930;
LastUpgradeCheck = 1020;
TargetAttributes = {
C9BB475B1E71663A00F3F98C = {
CreatedOnToolsVersion = 8.2.1;
@@ -785,7 +785,7 @@
C9BB478D1E71821A00F3F98C = {
CreatedOnToolsVersion = 8.2.1;
DevelopmentTeam = 2TWXCGG7R3;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
ProvisioningStyle = Manual;
};
C9D2ABD81EA20F99007EDF9D = {
@@ -793,13 +793,13 @@
};
C9D2ABF21EA212A3007EDF9D = {
DevelopmentTeam = 2TWXCGG7R3;
LastSwiftMigration = 0900;
LastSwiftMigration = 1020;
};
};
};
buildConfigurationList = C91030FB1E471D760004DFFE /* Build configuration list for PBXProject "OpenVPNAdapter" */;
compatibilityVersion = "Xcode 8.0";
developmentRegion = English;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
@@ -1240,7 +1240,7 @@
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -1285,7 +1285,7 @@
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
};
name = Release;
@@ -1437,7 +1437,7 @@
SUPPORTED_PLATFORMS = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
@@ -1483,7 +1483,7 @@
SDKROOT = macosx;
SUPPORTED_PLATFORMS = macosx;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_VERSION = 4.0;
SWIFT_VERSION = 5.0;
VALIDATE_PRODUCT = YES;
};
name = Release;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@@ -32,11 +32,8 @@ To install OpenVPNAdapter with Cocoapods, add the following lines to your `Podfi
```ruby
target 'Your Target Name' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for iOSOpenVPNTunnel
pod 'OpenVPNAdapter', '~> 0.1'
pod 'OpenVPNAdapter', :git => 'https://github.com/ss-abramchuk/OpenVPNAdapter.git', :tag => '0.3.0'
end
```
@@ -56,7 +53,7 @@ Then we need to create or load a VPN profile. [`NETunnelProviderManager`](https:
```swift
NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
guard error == nil else {
// Handle an occured error
// Handle an occurred error
return
}
@@ -68,7 +65,7 @@ The next step is to provide VPN settings to the instance of [`NETunnelProviderMa
```swift
self.providerManager?.loadFromPreferences(completionHandler: { (error) in
guard error == nil else {
// Handle an occured error
// Handle an occurred error
return
}
@@ -110,7 +107,7 @@ self.providerManager?.loadFromPreferences(completionHandler: { (error) in
// Save configuration in the Network Extension preferences
self.providerManager?.saveToPreferences(completionHandler: { (error) in
if let error = error {
// Handle an occured error
// Handle an occurred error
}
})
}
@@ -121,14 +118,14 @@ Start VPN by calling the following code.
```swift
self.providerManager?.loadFromPreferences(completionHandler: { (error) in
guard error == nil else {
// Handle an occured error
// Handle an occurred error
return
}
do {
try self.providerManager?.connection.startVPNTunnel()
} catch {
// Handle an occured error
// Handle an occurred error
}
}
```
@@ -250,7 +247,12 @@ extension PacketTunnelProvider: OpenVPNAdapterDelegate {
// `OpenVPNAdapterPacketFlow` method signatures are similar to `NEPacketTunnelFlow` so
// you can just extend that class to adopt `OpenVPNAdapterPacketFlow` protocol and
// send `self.packetFlow` to `completionHandler` callback.
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings, completionHandler: @escaping (OpenVPNAdapterPacketFlow?) -> Void) {
func openVPNAdapter(_ openVPNAdapter: OpenVPNAdapter, configureTunnelWithNetworkSettings networkSettings: NEPacketTunnelNetworkSettings?, completionHandler: @escaping (OpenVPNAdapterPacketFlow?) -> Void) {
// In order to direct all DNS queries first to the VPN DNS servers before the primary DNS servers
// send empty string to NEDNSSettings.matchDomains
networkSettings?.dnsSettings?.matchDomains = [""]
// Specify the network settings for the current tunneling session.
setTunnelNetworkSettings(settings) { (error) in
completionHandler(error == nil ? self.packetFlow : nil)
}
@@ -323,7 +325,7 @@ extension NEPacketTunnelFlow: OpenVPNAdapterPacketFlow {}
Any contributions and suggestions are welcome! But before creating a PR or an issue please read the [Contribution Guide](CONTRIBUTING.md).
## Acknowledgments
Special thanks goes to @JonathanDowning for great help in development of this project and bug fixing.
Special thanks goes to [@JonathanDowning](https://github.com/JonathanDowning) for great help in development of this project and bug fixing.
## License
OpenVPNAdapter is available under the AGPLv3 license. See the [LICENSE](LICENSE) file for more info. Also this project has a few dependencies:

View File

@@ -1,4 +1,4 @@
Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,4 +1,4 @@
asio version 1.12.0
Released Sunday, 04 March 2018.
asio version 1.13.0
Released Tuesday, 12 March 2019.
See doc/index.html for API documentation and a tutorial.

View File

@@ -281,7 +281,7 @@ sub copy_source_file
$line =~ s/asio::/boost::asio::/g if !$is_xsl;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /} \/\/ namespace std/)
elsif ($line =~ /^} \/\/ namespace std/)
{
print_line($output, "} // namespace system", $from, $lineno);
print_line($output, "} // namespace boost", $from, $lineno);
@@ -365,6 +365,8 @@ sub copy_include_files
"include/asio",
"include/asio/detail",
"include/asio/detail/impl",
"include/asio/experimental",
"include/asio/experimental/impl",
"include/asio/generic",
"include/asio/generic/detail",
"include/asio/generic/detail/impl",
@@ -528,8 +530,15 @@ sub copy_examples
"src/examples/cpp11/local",
"src/examples/cpp11/multicast",
"src/examples/cpp11/nonblocking",
"src/examples/cpp11/operations",
"src/examples/cpp11/socks4",
"src/examples/cpp11/spawn",
"src/examples/cpp14/executors");
"src/examples/cpp11/ssl",
"src/examples/cpp11/timeouts",
"src/examples/cpp11/timers",
"src/examples/cpp14/executors",
"src/examples/cpp14/operations",
"src/examples/cpp17/coroutines_ts");
our $boost_dir;
foreach my $dir (@dirs)

View File

@@ -1,4 +1,4 @@
AC_INIT(asio, [1.12.0])
AC_INIT(asio, [1.13.0])
AC_CONFIG_SRCDIR(include/asio.hpp)
AM_MAINTAINER_MODE
AM_INIT_AUTOMAKE([tar-ustar])
@@ -17,20 +17,12 @@ AC_ARG_WITH(boost,
if test "${withval}" = no; then
STANDALONE="yes"
else
CPPFLAGS="$CPPFLAGS -I${withval} -DBOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING"
CPPFLAGS="$CPPFLAGS -I${withval} -DASIO_ENABLE_BOOST -DBOOST_CHRONO_HEADER_ONLY -DBOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING"
LIBS="$LIBS -L${withval}/stage/lib"
fi
],
[
BOOSTDIR=`ls -1d ../boost_*_*_*/ 2>/dev/null | sort -t "_" -k 2nr -k 3nr -k 4nr | head -n 1 | sed -e 's/\/$//'`
if test "${BOOSTDIR}" != ""; then
BOOSTDIR="`pwd`/${BOOSTDIR}"
if test -d "${BOOSTDIR}"; then
echo "using automatically detected boost from ${BOOSTDIR}"
CPPFLAGS="$CPPFLAGS -I${BOOSTDIR} -DBOOST_CHRONO_DONT_PROVIDE_HYBRID_ERROR_HANDLING"
LIBS="$LIBS -L${BOOSTDIR}/stage/lib"
fi
fi
STANDALONE="yes"
])
AC_ARG_ENABLE(separate-compilation,
@@ -50,6 +42,7 @@ if test "$STANDALONE" != yes; then
[
echo "Can't find boost headers. Please check the location of the boost"
echo "distribution and rerun configure using the --with-boost=DIR option."
echo "Alternatively, run with --without-boost to enable standalone build."
exit 1
],[])
fi
@@ -101,7 +94,7 @@ case $host in
WINDOWS=yes
;;
*-pc-cygwin*)
CXXFLAGS="$CXXFLAGS -D__USE_W32_SOCKETS -D_WIN32_WINNT=0x0501"
CXXFLAGS="$CXXFLAGS -D__USE_W32_SOCKETS -D_WIN32_WINNT=0x0601"
LIBS="$LIBS -lws2_32 -lmswsock"
WINDOWS=yes
;;
@@ -117,13 +110,14 @@ case $host in
CXXFLAGS="$CXXFLAGS -pthread"
LDFLAGS="$LDFLAGS -pthread"
;;
*-*-haiku*)
CXXFLAGS="$CXXFLAGS -lnetwork"
LDFLAGS="$LDFLAGS -lnetwork"
esac
if test "$GXX" = yes; then
CXXFLAGS="$CXXFLAGS -ftemplate-depth-256"
if test "$STANDALONE" = yes; then
CPPFLAGS="-std=c++0x $CPPFLAGS"
fi
fi
if test "$STANDALONE" = yes; then
@@ -134,6 +128,37 @@ if test "$SEPARATE_COMPILATION" = yes; then
CPPFLAGS="$CPPFLAGS -DASIO_SEPARATE_COMPILATION"
fi
AC_MSG_CHECKING([whether C++11 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if __cplusplus < 201103L]]
[[#error C++11 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX11=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX11=no;])
AC_MSG_CHECKING([whether C++14 is enabled])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#if __cplusplus < 201402L]]
[[#error C++14 not available]]
[[#endif]])],
[AC_MSG_RESULT([yes])
HAVE_CXX14=yes;],
[AC_MSG_RESULT([no])
HAVE_CXX14=no;])
if test "$GXX" = yes; then
if test "$STANDALONE" = yes; then
if test "$HAVE_CXX11" = no; then
HAVE_CXX11=yes
CPPFLAGS="-std=c++0x $CPPFLAGS"
fi
fi
fi
AM_CONDITIONAL(STANDALONE,test x$STANDALONE = xyes)
AM_CONDITIONAL(SEPARATE_COMPILATION,test x$SEPARATE_COMPILATION = xyes)
@@ -142,6 +167,10 @@ AM_CONDITIONAL(HAVE_BOOST_COROUTINE,test x$HAVE_BOOST_COROUTINE = xyes)
AM_CONDITIONAL(WINDOWS_TARGET,test x$WINDOWS != xno)
AM_CONDITIONAL(HAVE_CXX11,test x$HAVE_CXX11 = xyes)
AM_CONDITIONAL(HAVE_CXX14,test x$HAVE_CXX14 = xyes)
AC_OUTPUT([
Makefile
include/Makefile
@@ -149,4 +178,5 @@ AC_OUTPUT([
src/tests/Makefile
src/examples/cpp03/Makefile
src/examples/cpp11/Makefile
src/examples/cpp14/Makefile])
src/examples/cpp14/Makefile
src/examples/cpp17/Makefile])

View File

@@ -3,6 +3,7 @@ nobase_include_HEADERS = \
asio/associated_allocator.hpp \
asio/associated_executor.hpp \
asio/async_result.hpp \
asio/awaitable.hpp \
asio/basic_datagram_socket.hpp \
asio/basic_deadline_timer.hpp \
asio/basic_io_object.hpp \
@@ -27,13 +28,14 @@ nobase_include_HEADERS = \
asio/buffered_write_stream.hpp \
asio/buffer.hpp \
asio/buffers_iterator.hpp \
asio/co_spawn.hpp \
asio/completion_condition.hpp \
asio/compose.hpp \
asio/connect.hpp \
asio/coroutine.hpp \
asio/datagram_socket_service.hpp \
asio/deadline_timer.hpp \
asio/deadline_timer_service.hpp \
asio/defer.hpp \
asio/detached.hpp \
asio/detail/array_fwd.hpp \
asio/detail/array.hpp \
asio/detail/assert.hpp \
@@ -64,10 +66,12 @@ nobase_include_HEADERS = \
asio/detail/epoll_reactor.hpp \
asio/detail/eventfd_select_interrupter.hpp \
asio/detail/event.hpp \
asio/detail/executor_function.hpp \
asio/detail/executor_op.hpp \
asio/detail/fd_set_adapter.hpp \
asio/detail/fenced_block.hpp \
asio/detail/functional.hpp \
asio/detail/future.hpp \
asio/detail/gcc_arm_fenced_block.hpp \
asio/detail/gcc_hppa_fenced_block.hpp \
asio/detail/gcc_sync_fenced_block.hpp \
@@ -131,6 +135,8 @@ nobase_include_HEADERS = \
asio/detail/impl/win_thread.ipp \
asio/detail/impl/win_tss_ptr.ipp \
asio/detail/io_control.hpp \
asio/detail/io_object_executor.hpp \
asio/detail/io_object_impl.hpp \
asio/detail/is_buffer_sequence.hpp \
asio/detail/is_executor.hpp \
asio/detail/keyword_tss_ptr.hpp \
@@ -140,6 +146,7 @@ nobase_include_HEADERS = \
asio/detail/macos_fenced_block.hpp \
asio/detail/memory.hpp \
asio/detail/mutex.hpp \
asio/detail/non_const_lvalue.hpp \
asio/detail/noncopyable.hpp \
asio/detail/null_event.hpp \
asio/detail/null_fenced_block.hpp \
@@ -284,8 +291,8 @@ nobase_include_HEADERS = \
asio/error_code.hpp \
asio/error.hpp \
asio/execution_context.hpp \
asio/executor_work_guard.hpp \
asio/executor.hpp \
asio/executor_work_guard.hpp \
asio/generic/basic_endpoint.hpp \
asio/generic/datagram_protocol.hpp \
asio/generic/detail/endpoint.hpp \
@@ -296,13 +303,16 @@ nobase_include_HEADERS = \
asio/handler_alloc_hook.hpp \
asio/handler_continuation_hook.hpp \
asio/handler_invoke_hook.hpp \
asio/handler_type.hpp \
asio/high_resolution_timer.hpp \
asio.hpp \
asio/impl/awaitable.hpp \
asio/impl/buffered_read_stream.hpp \
asio/impl/buffered_write_stream.hpp \
asio/impl/co_spawn.hpp \
asio/impl/compose.hpp \
asio/impl/connect.hpp \
asio/impl/defer.hpp \
asio/impl/detached.hpp \
asio/impl/dispatch.hpp \
asio/impl/error_code.ipp \
asio/impl/error.ipp \
@@ -317,6 +327,7 @@ nobase_include_HEADERS = \
asio/impl/read_at.hpp \
asio/impl/read.hpp \
asio/impl/read_until.hpp \
asio/impl/redirect_error.hpp \
asio/impl/serial_port_base.hpp \
asio/impl/serial_port_base.ipp \
asio/impl/spawn.hpp \
@@ -327,13 +338,14 @@ nobase_include_HEADERS = \
asio/impl/system_executor.hpp \
asio/impl/thread_pool.hpp \
asio/impl/thread_pool.ipp \
asio/impl/use_awaitable.hpp \
asio/impl/use_future.hpp \
asio/impl/write_at.hpp \
asio/impl/write.hpp \
asio/io_context_strand.hpp \
asio/io_context.hpp \
asio/io_service_strand.hpp \
asio/io_context_strand.hpp \
asio/io_service.hpp \
asio/io_service_strand.hpp \
asio/ip/address.hpp \
asio/ip/address_v4.hpp \
asio/ip/address_v4_iterator.hpp \
@@ -370,7 +382,6 @@ nobase_include_HEADERS = \
asio/ip/network_v6.hpp \
asio/ip/resolver_base.hpp \
asio/ip/resolver_query_base.hpp \
asio/ip/resolver_service.hpp \
asio/ip/tcp.hpp \
asio/ip/udp.hpp \
asio/ip/unicast.hpp \
@@ -388,22 +399,17 @@ nobase_include_HEADERS = \
asio/placeholders.hpp \
asio/posix/basic_descriptor.hpp \
asio/posix/basic_stream_descriptor.hpp \
asio/posix/descriptor.hpp \
asio/posix/descriptor_base.hpp \
asio/posix/descriptor.hpp \
asio/posix/stream_descriptor.hpp \
asio/posix/stream_descriptor_service.hpp \
asio/post.hpp \
asio/raw_socket_service.hpp \
asio/read_at.hpp \
asio/read.hpp \
asio/read_until.hpp \
asio/seq_packet_socket_service.hpp \
asio/redirect_error.hpp \
asio/serial_port_base.hpp \
asio/serial_port.hpp \
asio/serial_port_service.hpp \
asio/signal_set.hpp \
asio/signal_set_service.hpp \
asio/socket_acceptor_service.hpp \
asio/socket_base.hpp \
asio/spawn.hpp \
asio/ssl/context_base.hpp \
@@ -437,11 +443,11 @@ nobase_include_HEADERS = \
asio/steady_timer.hpp \
asio/strand.hpp \
asio/streambuf.hpp \
asio/stream_socket_service.hpp \
asio/system_context.hpp \
asio/system_error.hpp \
asio/system_executor.hpp \
asio/system_timer.hpp \
asio/this_coro.hpp \
asio/thread.hpp \
asio/thread_pool.hpp \
asio/time_traits.hpp \
@@ -454,23 +460,20 @@ nobase_include_HEADERS = \
asio/ts/socket.hpp \
asio/ts/timer.hpp \
asio/unyield.hpp \
asio/use_awaitable.hpp \
asio/use_future.hpp \
asio/uses_executor.hpp \
asio/version.hpp \
asio/waitable_timer_service.hpp \
asio/wait_traits.hpp \
asio/windows/basic_handle.hpp \
asio/windows/basic_object_handle.hpp \
asio/windows/basic_overlapped_handle.hpp \
asio/windows/basic_random_access_handle.hpp \
asio/windows/basic_stream_handle.hpp \
asio/windows/object_handle.hpp \
asio/windows/object_handle_service.hpp \
asio/windows/overlapped_handle.hpp \
asio/windows/overlapped_ptr.hpp \
asio/windows/random_access_handle.hpp \
asio/windows/random_access_handle_service.hpp \
asio/windows/stream_handle.hpp \
asio/windows/stream_handle_service.hpp \
asio/write_at.hpp \
asio/write.hpp \
asio/yield.hpp

View File

@@ -2,7 +2,7 @@
// asio.hpp
// ~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -18,6 +18,7 @@
#include "asio/associated_allocator.hpp"
#include "asio/associated_executor.hpp"
#include "asio/async_result.hpp"
#include "asio/awaitable.hpp"
#include "asio/basic_datagram_socket.hpp"
#include "asio/basic_deadline_timer.hpp"
#include "asio/basic_io_object.hpp"
@@ -25,6 +26,7 @@
#include "asio/basic_seq_packet_socket.hpp"
#include "asio/basic_serial_port.hpp"
#include "asio/basic_signal_set.hpp"
#include "asio/basic_socket.hpp"
#include "asio/basic_socket_acceptor.hpp"
#include "asio/basic_socket_iostream.hpp"
#include "asio/basic_socket_streambuf.hpp"
@@ -40,13 +42,14 @@
#include "asio/buffered_write_stream_fwd.hpp"
#include "asio/buffered_write_stream.hpp"
#include "asio/buffers_iterator.hpp"
#include "asio/co_spawn.hpp"
#include "asio/completion_condition.hpp"
#include "asio/compose.hpp"
#include "asio/connect.hpp"
#include "asio/coroutine.hpp"
#include "asio/datagram_socket_service.hpp"
#include "asio/deadline_timer_service.hpp"
#include "asio/deadline_timer.hpp"
#include "asio/defer.hpp"
#include "asio/detached.hpp"
#include "asio/dispatch.hpp"
#include "asio/error.hpp"
#include "asio/error_code.hpp"
@@ -61,7 +64,6 @@
#include "asio/handler_alloc_hook.hpp"
#include "asio/handler_continuation_hook.hpp"
#include "asio/handler_invoke_hook.hpp"
#include "asio/handler_type.hpp"
#include "asio/high_resolution_timer.hpp"
#include "asio/io_context.hpp"
#include "asio/io_context_strand.hpp"
@@ -74,6 +76,8 @@
#include "asio/ip/address_v6.hpp"
#include "asio/ip/address_v6_iterator.hpp"
#include "asio/ip/address_v6_range.hpp"
#include "asio/ip/network_v4.hpp"
#include "asio/ip/network_v6.hpp"
#include "asio/ip/bad_address_cast.hpp"
#include "asio/ip/basic_endpoint.hpp"
#include "asio/ip/basic_resolver.hpp"
@@ -85,7 +89,6 @@
#include "asio/ip/multicast.hpp"
#include "asio/ip/resolver_base.hpp"
#include "asio/ip/resolver_query_base.hpp"
#include "asio/ip/resolver_service.hpp"
#include "asio/ip/tcp.hpp"
#include "asio/ip/udp.hpp"
#include "asio/ip/unicast.hpp"
@@ -104,48 +107,40 @@
#include "asio/posix/descriptor.hpp"
#include "asio/posix/descriptor_base.hpp"
#include "asio/posix/stream_descriptor.hpp"
#include "asio/posix/stream_descriptor_service.hpp"
#include "asio/post.hpp"
#include "asio/raw_socket_service.hpp"
#include "asio/read.hpp"
#include "asio/read_at.hpp"
#include "asio/read_until.hpp"
#include "asio/seq_packet_socket_service.hpp"
#include "asio/redirect_error.hpp"
#include "asio/serial_port.hpp"
#include "asio/serial_port_base.hpp"
#include "asio/serial_port_service.hpp"
#include "asio/signal_set.hpp"
#include "asio/signal_set_service.hpp"
#include "asio/socket_acceptor_service.hpp"
#include "asio/socket_base.hpp"
#include "asio/steady_timer.hpp"
#include "asio/strand.hpp"
#include "asio/stream_socket_service.hpp"
#include "asio/streambuf.hpp"
#include "asio/system_context.hpp"
#include "asio/system_error.hpp"
#include "asio/system_executor.hpp"
#include "asio/system_timer.hpp"
#include "asio/this_coro.hpp"
#include "asio/thread.hpp"
#include "asio/thread_pool.hpp"
#include "asio/time_traits.hpp"
#include "asio/use_awaitable.hpp"
#include "asio/use_future.hpp"
#include "asio/uses_executor.hpp"
#include "asio/version.hpp"
#include "asio/wait_traits.hpp"
#include "asio/waitable_timer_service.hpp"
#include "asio/windows/basic_handle.hpp"
#include "asio/windows/basic_object_handle.hpp"
#include "asio/windows/basic_overlapped_handle.hpp"
#include "asio/windows/basic_random_access_handle.hpp"
#include "asio/windows/basic_stream_handle.hpp"
#include "asio/windows/object_handle.hpp"
#include "asio/windows/object_handle_service.hpp"
#include "asio/windows/overlapped_handle.hpp"
#include "asio/windows/overlapped_ptr.hpp"
#include "asio/windows/random_access_handle.hpp"
#include "asio/windows/random_access_handle_service.hpp"
#include "asio/windows/stream_handle.hpp"
#include "asio/windows/stream_handle_service.hpp"
#include "asio/write.hpp"
#include "asio/write_at.hpp"

View File

@@ -2,7 +2,7 @@
// associated_allocator.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// associated_executor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// async_result.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,7 +17,7 @@
#include "asio/detail/config.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/handler_type.hpp"
#include "asio/detail/variadic_templates.hpp"
#include "asio/detail/push_options.hpp"
@@ -41,30 +41,15 @@ namespace asio {
* The primary template assumes that the CompletionToken is the completion
* handler.
*/
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature>
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature = void>
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
class async_result
{
public:
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// The concrete completion handler type for the specific signature.
typedef CompletionToken completion_handler_type;
/// The return type of the initiating function.
typedef void return_type;
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// For backward compatibility, determine the concrete completion handler type
// by using the legacy handler_type trait.
typedef typename handler_type<CompletionToken, Signature>::type
completion_handler_type;
// For backward compatibility, determine the initiating function return type
// using the legacy single-parameter version of async_result.
typedef typename async_result<completion_handler_type>::type return_type;
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
/// Construct an async result from a given handler.
/**
@@ -73,11 +58,6 @@ public:
* then returned from the initiating function.
*/
explicit async_result(completion_handler_type& h)
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members to initialise.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
: legacy_result_(h)
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
(void)h;
}
@@ -85,56 +65,60 @@ public:
/// Obtain the value to be returned from the initiating function.
return_type get()
{
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// Nothing to do.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
return legacy_result_.get();
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
}
#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 <typename Initiation, typename RawCompletionToken, typename... Args>
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)
template <typename Initiation, typename RawCompletionToken>
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 <typename Initiation, typename RawCompletionToken, \
ASIO_VARIADIC_TPARAMS(n)> \
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;
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
// No data members.
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
async_result<completion_handler_type> legacy_result_;
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
};
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use two-parameter version of async_result.) An interface for
/// customising the behaviour of an initiating function.
/**
* This template may be specialised for user-defined handler types.
*/
template <typename Handler>
class async_result<Handler>
{
public:
/// The return type of the initiating function.
typedef void type;
/// Construct an async result from a given handler.
/**
* When using a specalised async_result, the constructor has an opportunity
* to initialise some state associated with the handler, which is then
* returned from the initiating function.
*/
explicit async_result(Handler&)
{
}
/// Obtain the value to be returned from the initiating function.
type get()
{
}
};
#endif // !defined(ASIO_NO_DEPRECATED)
/// 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.
@@ -194,10 +178,40 @@ struct async_result_helper
{
};
} // namespace detail
} // namespace asio
struct async_result_memfns_base
{
void initiate();
};
#include "asio/detail/pop_options.hpp"
template <typename T>
struct async_result_memfns_derived
: T, async_result_memfns_base
{
};
template <typename T, T>
struct async_result_memfns_check
{
};
template <typename>
char (&async_result_initiate_memfn_helper(...))[2];
template <typename T>
char async_result_initiate_memfn_helper(
async_result_memfns_check<
void (async_result_memfns_base::*)(),
&async_result_memfns_derived<T>::initiate>*);
template <typename CompletionToken, typename Signature>
struct async_result_has_initiate_memfn
: integral_constant<bool, sizeof(async_result_initiate_memfn_helper<
async_result<typename decay<CompletionToken>::type, Signature>
>(0)) != 1>
{
};
} // namespace detail
#if defined(GENERATING_DOCUMENTATION)
# define ASIO_INITFN_RESULT_TYPE(ct, sig) \
@@ -218,4 +232,125 @@ struct async_result_helper
typename ::asio::decay<ct>::type, sig>::completion_handler_type
#endif
#if defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
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 <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
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_MOVE_ARG(Args)... args)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
ASIO_MOVE_CAST(CompletionToken)(token),
ASIO_MOVE_CAST(Args)(args)...);
}
template <typename CompletionToken, typename Signature,
typename Initiation, typename... Args>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
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<CompletionToken, Signature> 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 <typename CompletionToken, typename Signature, typename Initiation>
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)
{
return async_result<typename decay<CompletionToken>::type,
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation),
ASIO_MOVE_CAST(CompletionToken)(token));
}
template <typename CompletionToken, typename Signature, typename Initiation>
inline typename enable_if<
!detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value,
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)>::type
async_initiate(ASIO_MOVE_ARG(Initiation) initiation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token)
{
async_completion<CompletionToken, Signature> 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 <typename CompletionToken, typename Signature, \
typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
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<typename decay<CompletionToken>::type, \
Signature>::initiate(ASIO_MOVE_CAST(Initiation)(initiation), \
ASIO_MOVE_CAST(CompletionToken)(token), \
ASIO_VARIADIC_MOVE_ARGS(n)); \
} \
\
template <typename CompletionToken, typename Signature, \
typename Initiation, ASIO_VARIADIC_TPARAMS(n)> \
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<CompletionToken, Signature> 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

View File

@@ -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 <experimental/coroutine>
#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 <typename> class awaitable_thread;
template <typename, typename> class awaitable_frame;
} // namespace detail
/// The return type of a coroutine or asynchronous operation.
template <typename T, typename Executor = executor>
class awaitable
{
public:
/// The type of the awaited value.
typedef T value_type;
/// The executor type that will be used for the coroutine.
typedef Executor executor_type;
/// Default constructor.
constexpr awaitable() noexcept
: frame_(nullptr)
{
}
/// Move constructor.
awaitable(awaitable&& other) noexcept
: frame_(std::exchange(other.frame_, nullptr))
{
}
/// Destructor
~awaitable()
{
if (frame_)
frame_->destroy();
}
/// Checks if the awaitable refers to a future result.
bool valid() const noexcept
{
return !!frame_;
}
#if !defined(GENERATING_DOCUMENTATION)
// Support for co_await keyword.
bool await_ready() const noexcept
{
return false;
}
// Support for co_await keyword.
template <class U>
void await_suspend(
detail::coroutine_handle<detail::awaitable_frame<U, Executor>> h)
{
frame_->push_frame(&h.promise());
}
// Support for co_await keyword.
T await_resume()
{
return frame_->get();
}
#endif // !defined(GENERATING_DOCUMENTATION)
private:
template <typename> friend class detail::awaitable_thread;
template <typename, typename> friend class detail::awaitable_frame;
// Not copy constructible or copy assignable.
awaitable(const awaitable&) = delete;
awaitable& operator=(const awaitable&) = delete;
// Construct the awaitable from a coroutine's frame object.
explicit awaitable(detail::awaitable_frame<T, Executor>* a)
: frame_(a)
{
}
detail::awaitable_frame<T, Executor>* frame_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/impl/awaitable.hpp"
#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#endif // ASIO_AWAITABLE_HPP

View File

@@ -2,7 +2,7 @@
// basic_datagram_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the 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,18 +19,24 @@
#include <cstddef>
#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"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/datagram_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
#if !defined(ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL)
#define ASIO_BASIC_DATAGRAM_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
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
@@ -40,18 +46,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= datagram_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_datagram_socket
: public basic_socket<Protocol ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_datagram_socket<Protocol, Executor1> other;
};
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -65,12 +81,29 @@ public:
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_datagram_socket(asio::io_context& io_context)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context)
explicit basic_datagram_socket(const executor_type& ex)
: basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_datagram_socket without opening it.
/**
* This constructor creates a datagram socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_datagram_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{
}
@@ -78,17 +111,37 @@ public:
/**
* This constructor creates and opens a datagram socket.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
basic_datagram_socket(asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, protocol)
basic_datagram_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, protocol)
{
}
/// Construct and open a basic_datagram_socket.
/**
* This constructor creates and opens a datagram socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -99,18 +152,42 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
basic_datagram_socket(asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, endpoint)
basic_datagram_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, endpoint)
{
}
/// Construct a basic_datagram_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a datagram socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the datagram
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -119,9 +196,8 @@ public:
* This constructor creates a datagram socket object to hold an existing
* native socket.
*
* @param io_context The io_context object that the datagram socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -129,10 +205,34 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
basic_datagram_socket(asio::io_context& io_context,
basic_datagram_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
{
}
/// Construct a basic_datagram_socket on an existing native socket.
/**
* This constructor creates a datagram socket object to hold an existing
* native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_datagram_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -145,10 +245,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
basic_datagram_socket(basic_datagram_socket&& other)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -161,11 +262,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
basic_datagram_socket& operator=(basic_datagram_socket&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -178,13 +280,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_datagram_socket(
basic_datagram_socket<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_datagram_socket(basic_datagram_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -198,14 +303,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_datagram_socket(io_context&) constructor.
* constructed using the @c basic_datagram_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_datagram_socket>::type& operator=(
basic_datagram_socket<Protocol1 ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value,
basic_datagram_socket&
>::type operator=(basic_datagram_socket<Protocol1, Executor1>&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -245,8 +353,8 @@ public:
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;
}
@@ -273,8 +381,8 @@ public:
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;
}
@@ -300,8 +408,8 @@ public:
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.
@@ -322,9 +430,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -345,22 +453,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@@ -383,9 +479,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -398,22 +494,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send a datagram to the specified endpoint.
@@ -446,8 +529,8 @@ public:
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;
}
@@ -473,8 +556,8 @@ public:
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;
}
@@ -500,7 +583,7 @@ public:
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);
}
@@ -525,9 +608,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -548,24 +631,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, 0,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -591,9 +660,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -602,24 +671,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@@ -650,8 +704,8 @@ public:
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;
}
@@ -679,8 +733,8 @@ public:
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;
}
@@ -707,8 +761,8 @@ public:
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.
@@ -729,9 +783,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -753,22 +807,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@@ -791,9 +833,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -806,22 +848,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive a datagram with the endpoint of the sender.
@@ -855,8 +884,8 @@ public:
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;
}
@@ -882,8 +911,8 @@ public:
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;
}
@@ -909,8 +938,8 @@ public:
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.
@@ -936,9 +965,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -956,24 +985,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -1001,9 +1016,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -1012,25 +1027,85 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(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<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
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<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@@ -2,7 +2,7 @@
// basic_deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -21,19 +21,16 @@
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include "asio/basic_io_object.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"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/deadline_timer_service.hpp"
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/deadline_timer_service.hpp"
# define ASIO_SVC_T detail::deadline_timer_service<TimeTraits>
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
@@ -57,7 +54,7 @@ namespace asio {
* Performing a blocking wait:
* @code
* // Construct a timer without setting an expiry time.
* asio::deadline_timer timer(io_context);
* asio::deadline_timer timer(my_context);
*
* // Set an expiry time relative to now.
* timer.expires_from_now(boost::posix_time::seconds(5));
@@ -80,7 +77,7 @@ namespace asio {
* ...
*
* // Construct a timer with an absolute expiry time.
* asio::deadline_timer timer(io_context,
* asio::deadline_timer timer(my_context,
* boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
*
* // Start an asynchronous wait.
@@ -127,14 +124,13 @@ namespace asio {
* it contains the value asio::error::operation_aborted.
*/
template <typename Time,
typename TimeTraits = asio::time_traits<Time>
ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)>
typename TimeTraits = asio::time_traits<Time>,
typename Executor = executor>
class basic_deadline_timer
: ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
typedef io_context::executor_type executor_type;
typedef Executor executor_type;
/// The time traits type.
typedef TimeTraits traits_type;
@@ -151,11 +147,30 @@ public:
* expires_at() or expires_from_now() functions must be called to set an
* expiry time before the timer can be waited on.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*/
explicit basic_deadline_timer(asio::io_context& io_context)
: basic_io_object<ASIO_SVC_T>(io_context)
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 <typename ExecutionContext>
explicit basic_deadline_timer(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
}
@@ -163,18 +178,40 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
basic_deadline_timer(asio::io_context& io_context,
const time_type& expiry_time)
: basic_io_object<ASIO_SVC_T>(io_context)
basic_deadline_timer(const executor_type& ex, const time_type& expiry_time)
: impl_(ex)
{
asio::error_code ec;
this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
template <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
}
@@ -182,19 +219,44 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
basic_deadline_timer(asio::io_context& io_context,
basic_deadline_timer(const executor_type& ex,
const duration_type& expiry_time)
: basic_io_object<ASIO_SVC_T>(io_context)
: impl_(ex)
{
asio::error_code ec;
this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_from_now");
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
template <typename ExecutionContext>
basic_deadline_timer(ExecutionContext& context,
const duration_type& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_from_now");
}
@@ -207,10 +269,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor.
* constructed using the @c basic_deadline_timer(const executor_type&)
* constructor.
*/
basic_deadline_timer(basic_deadline_timer&& other)
: basic_io_object<ASIO_SVC_T>(std::move(other))
: impl_(std::move(other.impl_))
{
}
@@ -223,11 +286,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_deadline_timer(io_context&) constructor.
* constructed using the @c basic_deadline_timer(const executor_type&)
* constructor.
*/
basic_deadline_timer& operator=(basic_deadline_timer&& other)
{
basic_io_object<ASIO_SVC_T>::operator=(std::move(other));
impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -241,45 +305,11 @@ public:
{
}
#if defined(ASIO_ENABLE_OLD_SERVICES)
// These functions are provided by basic_io_object<>.
#else // defined(ASIO_ENABLE_OLD_SERVICES)
#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_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_context()
{
return basic_io_object<ASIO_SVC_T>::get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_context& get_io_service()
{
return basic_io_object<ASIO_SVC_T>::get_io_service();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Get the executor associated with the object.
executor_type get_executor() ASIO_NOEXCEPT
{
return basic_io_object<ASIO_SVC_T>::get_executor();
return impl_.get_executor();
}
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer.
/**
@@ -306,7 +336,7 @@ public:
std::size_t cancel()
{
asio::error_code ec;
std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "cancel");
return s;
}
@@ -335,7 +365,7 @@ public:
*/
std::size_t cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
return impl_.get_service().cancel(impl_.get_implementation(), ec);
}
/// Cancels one asynchronous operation that is waiting on the timer.
@@ -365,8 +395,8 @@ public:
std::size_t cancel_one()
{
asio::error_code ec;
std::size_t s = this->get_service().cancel_one(
this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel_one(
impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "cancel_one");
return s;
}
@@ -397,7 +427,7 @@ public:
*/
std::size_t cancel_one(asio::error_code& ec)
{
return this->get_service().cancel_one(this->get_implementation(), ec);
return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
}
/// Get the timer's expiry time as an absolute time.
@@ -407,7 +437,7 @@ public:
*/
time_type expires_at() const
{
return this->get_service().expires_at(this->get_implementation());
return impl_.get_service().expires_at(impl_.get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -435,8 +465,8 @@ public:
std::size_t expires_at(const time_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
return s;
}
@@ -466,8 +496,8 @@ public:
std::size_t expires_at(const time_type& expiry_time,
asio::error_code& ec)
{
return this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
}
/// Get the timer's expiry time relative to now.
@@ -477,7 +507,7 @@ public:
*/
duration_type expires_from_now() const
{
return this->get_service().expires_from_now(this->get_implementation());
return impl_.get_service().expires_from_now(impl_.get_implementation());
}
/// Set the timer's expiry time relative to now.
@@ -505,8 +535,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time)
{
asio::error_code ec;
std::size_t s = this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@@ -536,8 +566,8 @@ public:
std::size_t expires_from_now(const duration_type& expiry_time,
asio::error_code& ec)
{
return this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
}
/// Perform a blocking wait on the timer.
@@ -550,7 +580,7 @@ public:
void wait()
{
asio::error_code ec;
this->get_service().wait(this->get_implementation(), ec);
impl_.get_service().wait(impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "wait");
}
@@ -563,7 +593,7 @@ public:
*/
void wait(asio::error_code& ec)
{
this->get_service().wait(this->get_implementation(), ec);
impl_.get_service().wait(impl_.get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -586,42 +616,50 @@ public:
* 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_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename WaitHandler>
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_wait(this->get_implementation(),
ASIO_MOVE_CAST(WaitHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WaitHandler, void (asio::error_code)>(
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 <typename WaitHandler>
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<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<TimeTraits>, Executor> impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# undef ASIO_SVC_T
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)

View File

@@ -2,7 +2,7 @@
// basic_io_object.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// basic_raw_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the 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,18 +19,24 @@
#include <cstddef>
#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"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/raw_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#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 <typename Protocol, typename Executor = executor>
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
@@ -40,18 +46,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= raw_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_raw_socket
: public basic_socket<Protocol ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_raw_socket<Protocol, Executor1> other;
};
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -65,12 +81,29 @@ public:
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_raw_socket(asio::io_context& io_context)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context)
explicit basic_raw_socket(const executor_type& ex)
: basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_raw_socket without opening it.
/**
* This constructor creates a raw socket without opening it. The open()
* function must be called before data can be sent or received on the socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_raw_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{
}
@@ -78,17 +111,36 @@ public:
/**
* This constructor creates and opens a raw socket.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
basic_raw_socket(asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, protocol)
basic_raw_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, protocol)
{
}
/// Construct and open a basic_raw_socket.
/**
* This constructor creates and opens a raw socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context, const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -99,18 +151,41 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the raw
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
basic_raw_socket(asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, endpoint)
basic_raw_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, endpoint)
{
}
/// Construct a basic_raw_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a raw socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the raw
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context, const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -119,9 +194,8 @@ public:
* This constructor creates a raw socket object to hold an existing
* native socket.
*
* @param io_context The io_context object that the raw socket will use
* to dispatch handlers for any asynchronous operations performed on the
* socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -129,10 +203,34 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
basic_raw_socket(asio::io_context& io_context,
basic_raw_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
{
}
/// Construct a basic_raw_socket on an existing native socket.
/**
* This constructor creates a raw socket object to hold an existing
* native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_raw_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -145,10 +243,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
basic_raw_socket(basic_raw_socket&& other)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -160,28 +259,34 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
basic_raw_socket& operator=(basic_raw_socket&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
/// Move-construct a basic_raw_socket from a socket of another protocol type.
/// Move-construct a basic_raw_socket from a socket of another protocol
/// type.
/**
* This constructor moves a raw socket from one object to another.
*
* @param other The other basic_raw_socket object from which the move will
* occur.
* @param other The other basic_raw_socket object from which the move
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_raw_socket(basic_raw_socket<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_raw_socket(basic_raw_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -193,14 +298,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_raw_socket(io_context&) constructor.
* constructed using the @c basic_raw_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_raw_socket>::type& operator=(
basic_raw_socket<Protocol1 ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value,
basic_raw_socket&
>::type operator=(basic_raw_socket<Protocol1, Executor1>&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -239,8 +347,8 @@ public:
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 +374,8 @@ public:
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;
}
@@ -292,8 +400,8 @@ public:
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.
@@ -314,9 +422,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -337,22 +445,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send on a connected socket.
@@ -375,9 +471,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -390,22 +486,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Send raw data to the specified endpoint.
@@ -438,8 +521,8 @@ public:
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;
}
@@ -465,8 +548,8 @@ public:
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;
}
@@ -492,7 +575,7 @@ public:
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);
}
@@ -517,9 +600,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -540,22 +623,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(this->get_implementation(),
buffers, destination, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers,
destination, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -581,9 +652,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename ConstBufferSequence, typename WriteHandler>
ASIO_INITFN_RESULT_TYPE(WriteHandler,
@@ -592,24 +663,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send_to(
this->get_implementation(), buffers, destination, flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send_to(), handler, this, buffers, destination, flags);
}
/// Receive some data on a connected socket.
@@ -640,8 +696,8 @@ public:
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;
}
@@ -669,8 +725,8 @@ public:
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;
}
@@ -697,8 +753,8 @@ public:
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.
@@ -719,9 +775,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -743,22 +799,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive on a connected socket.
@@ -781,9 +825,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -796,22 +840,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Receive raw data with the endpoint of the sender.
@@ -845,8 +876,8 @@ public:
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;
}
@@ -872,8 +903,8 @@ public:
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;
}
@@ -899,8 +930,8 @@ public:
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.
@@ -926,9 +957,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -946,24 +977,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, 0,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler, this, buffers,
&sender_endpoint, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -991,9 +1008,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename MutableBufferSequence, typename ReadHandler>
ASIO_INITFN_RESULT_TYPE(ReadHandler,
@@ -1002,25 +1019,85 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_from(
this->get_implementation(), buffers, sender_endpoint, flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_from(), handler,
this, buffers, &sender_endpoint, flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(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<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_send_to
{
template <typename WriteHandler, typename ConstBufferSequence>
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<WriteHandler> handler2(handler);
self->impl_.get_service().async_send_to(
self->impl_.get_implementation(), buffers, destination, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_from
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_from(
self->impl_.get_implementation(), buffers, *sender_endpoint, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@@ -2,7 +2,7 @@
// basic_seq_packet_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the 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,14 +22,19 @@
#include "asio/detail/throw_error.hpp"
#include "asio/error.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/seq_packet_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#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 <typename Protocol, typename Executor = executor>
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
@@ -39,18 +44,28 @@ namespace asio {
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_seq_packet_socket
: public basic_socket<Protocol ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_seq_packet_socket<Protocol, Executor1> other;
};
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -65,12 +80,30 @@ public:
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_seq_packet_socket(asio::io_context& io_context)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context)
explicit basic_seq_packet_socket(const executor_type& ex)
: basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_seq_packet_socket without opening it.
/**
* This constructor creates a sequenced packet socket without opening it. The
* socket needs to be opened and then connected or accepted before data can
* be sent or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_seq_packet_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{
}
@@ -80,17 +113,40 @@ public:
* needs to be connected or accepted before data can be sent or received on
* it.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
basic_seq_packet_socket(asio::io_context& io_context,
basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, protocol)
: basic_socket<Protocol, Executor>(ex, protocol)
{
}
/// Construct and open a basic_seq_packet_socket.
/**
* This constructor creates and opens a sequenced_packet socket. The socket
* needs to be connected or accepted before data can be sent or received on
* it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -101,18 +157,43 @@ public:
* it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the sequenced
* packet socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
basic_seq_packet_socket(asio::io_context& io_context,
basic_seq_packet_socket(const executor_type& ex,
const endpoint_type& endpoint)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, endpoint)
: basic_socket<Protocol, Executor>(ex, endpoint)
{
}
/// Construct a basic_seq_packet_socket, opening it and binding it to the
/// given local endpoint.
/**
* This constructor creates a sequenced packet socket and automatically opens
* it bound to the specified endpoint on the local machine. The protocol used
* is the protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the sequenced
* packet socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -121,9 +202,8 @@ public:
* This constructor creates a sequenced packet socket object to hold an
* existing native socket.
*
* @param io_context The io_context object that the sequenced packet socket
* will use to dispatch handlers for any asynchronous operations performed on
* the socket.
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
@@ -131,10 +211,34 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
basic_seq_packet_socket(asio::io_context& io_context,
basic_seq_packet_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
{
}
/// Construct a basic_seq_packet_socket on an existing native socket.
/**
* This constructor creates a sequenced packet socket object to hold an
* existing native socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_seq_packet_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -148,10 +252,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
basic_seq_packet_socket(basic_seq_packet_socket&& other)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -164,11 +269,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -182,13 +288,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_seq_packet_socket(
basic_seq_packet_socket<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -202,14 +311,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_seq_packet_socket(io_context&) constructor.
* constructed using the @c basic_seq_packet_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_seq_packet_socket>::type& operator=(
basic_seq_packet_socket<Protocol1 ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value,
basic_seq_packet_socket&
>::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -251,8 +363,8 @@ public:
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;
}
@@ -279,8 +391,8 @@ public:
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.
@@ -303,9 +415,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To send a single data buffer use the @ref buffer function as follows:
@@ -323,22 +435,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@@ -375,13 +474,8 @@ public:
socket_base::message_flags& out_flags)
{
asio::error_code ec;
#if defined(ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, 0, out_flags, ec);
#else // defined(ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, 0, out_flags, ec);
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
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;
}
@@ -427,13 +521,8 @@ public:
socket_base::message_flags& out_flags)
{
asio::error_code ec;
#if defined(ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive(
this->get_implementation(), buffers, in_flags, out_flags, ec);
#else // defined(ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->get_service().receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags, ec);
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
std::size_t s = this->impl_.get_service().receive_with_flags(
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
asio::detail::throw_error(ec, "receive");
return s;
}
@@ -466,13 +555,8 @@ public:
socket_base::message_flags in_flags,
socket_base::message_flags& out_flags, asio::error_code& ec)
{
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive(this->get_implementation(),
buffers, in_flags, out_flags, ec);
#else // defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().receive_with_flags(this->get_implementation(),
buffers, in_flags, out_flags, ec);
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return this->impl_.get_service().receive_with_flags(
this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
}
/// Start an asynchronous receive.
@@ -499,9 +583,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -520,24 +604,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, 0, out_flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, 0, out_flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler, this,
buffers, socket_base::message_flags(0), &out_flags);
}
/// Start an asynchronous receive.
@@ -566,9 +636,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* To receive into a single data buffer use the @ref buffer function as
@@ -590,25 +660,49 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(
this->get_implementation(), buffers, in_flags, out_flags,
ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive_with_flags(
this->get_implementation(), buffers, in_flags, out_flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive_with_flags(), handler,
this, buffers, in_flags, &out_flags);
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(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<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive_with_flags
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive_with_flags(
self->impl_.get_implementation(), buffers, in_flags, *out_flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@@ -2,7 +2,7 @@
// basic_serial_port.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Rep Invariant Systems, Inc. (info@repinvariant.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -18,18 +18,29 @@
#include "asio/detail/config.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_HAS_SERIAL_PORT) \
|| defined(GENERATING_DOCUMENTATION)
#include <string>
#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 <utility>
#endif // defined(ASIO_HAS_MOVE)
#include "asio/detail/push_options.hpp"
@@ -37,34 +48,63 @@ namespace asio {
/// Provides serial port functionality.
/**
* The basic_serial_port class template provides functionality that is common
* to all serial ports.
* The basic_serial_port class provides a wrapper over serial port
* functionality.
*
* @par Thread Safety
* @e Distinct @e objects: Safe.@n
* @e Shared @e objects: Unsafe.
*/
template <typename SerialPortService = serial_port_service>
template <typename Executor = executor>
class basic_serial_port
: public basic_io_object<SerialPortService>,
public serial_port_base
: public serial_port_base
{
public:
/// The native representation of a serial port.
typedef typename SerialPortService::native_handle_type native_handle_type;
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// A basic_serial_port is always the lowest layer.
typedef basic_serial_port<SerialPortService> lowest_layer_type;
/// The native representation of a serial port.
#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_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_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* serial port.
*/
explicit basic_serial_port(asio::io_context& io_context)
: basic_io_object<SerialPortService>(io_context)
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 <typename ExecutionContext>
explicit basic_serial_port(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value,
basic_serial_port
>::type* = 0)
: impl_(context)
{
}
@@ -73,18 +113,18 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
explicit basic_serial_port(asio::io_context& io_context,
const char* device)
: basic_io_object<SerialPortService>(io_context)
basic_serial_port(const executor_type& ex, const char* device)
: impl_(ex)
{
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");
}
@@ -93,18 +133,66 @@ public:
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param context An execution context which provides the I/O executor that
* the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
explicit basic_serial_port(asio::io_context& io_context,
const std::string& device)
: basic_io_object<SerialPortService>(io_context)
template <typename ExecutionContext>
basic_serial_port(ExecutionContext& context, const char* device,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
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");
}
/// Construct and open a basic_serial_port.
/**
* This constructor creates and opens a serial port for the specified device
* name.
*
* @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
basic_serial_port(const executor_type& ex, const std::string& device)
: impl_(ex)
{
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 context An execution context which provides the I/O executor that
* the serial port will use, by default, to dispatch handlers for any
* asynchronous operations performed on the serial port.
*
* @param device The platform-specific device name for this serial
* port.
*/
template <typename ExecutionContext>
basic_serial_port(ExecutionContext& context, const std::string& device,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().open(impl_.get_implementation(), device, ec);
asio::detail::throw_error(ec, "open");
}
@@ -113,19 +201,47 @@ public:
* This constructor creates a serial port object to hold an existing native
* serial port.
*
* @param io_context The io_context object that the serial port will use to
* dispatch handlers for any asynchronous operations performed on the port.
* @param ex The I/O executor that the serial port will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* serial port.
*
* @param native_serial_port A native serial port.
*
* @throws asio::system_error Thrown on failure.
*/
basic_serial_port(asio::io_context& io_context,
basic_serial_port(const executor_type& ex,
const native_handle_type& native_serial_port)
: basic_io_object<SerialPortService>(io_context)
: impl_(ex)
{
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 <typename ExecutionContext>
basic_serial_port(ExecutionContext& context,
const native_handle_type& native_serial_port,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().assign(impl_.get_implementation(),
native_serial_port, ec);
asio::detail::throw_error(ec, "assign");
}
@@ -139,11 +255,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor.
* constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/
basic_serial_port(basic_serial_port&& other)
: basic_io_object<SerialPortService>(
ASIO_MOVE_CAST(basic_serial_port)(other))
: impl_(std::move(other.impl_))
{
}
@@ -155,16 +271,32 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_serial_port(io_context&) constructor.
* constructed using the @c basic_serial_port(const executor_type&)
* constructor.
*/
basic_serial_port& operator=(basic_serial_port&& other)
{
basic_io_object<SerialPortService>::operator=(
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
@@ -204,7 +336,7 @@ public:
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");
}
@@ -220,7 +352,7 @@ public:
ASIO_SYNC_OP_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_SYNC_OP_VOID_RETURN(ec);
}
@@ -235,7 +367,7 @@ public:
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");
}
@@ -251,7 +383,7 @@ public:
ASIO_SYNC_OP_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_SYNC_OP_VOID_RETURN(ec);
}
@@ -259,7 +391,7 @@ public:
/// Determine whether the serial port is open.
bool is_open() const
{
return this->get_service().is_open(this->get_implementation());
return impl_.get_service().is_open(impl_.get_implementation());
}
/// Close the serial port.
@@ -273,7 +405,7 @@ public:
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");
}
@@ -287,7 +419,7 @@ public:
*/
ASIO_SYNC_OP_VOID close(asio::error_code& ec)
{
this->get_service().close(this->get_implementation(), ec);
impl_.get_service().close(impl_.get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -299,7 +431,7 @@ public:
*/
native_handle_type native_handle()
{
return this->get_service().native_handle(this->get_implementation());
return impl_.get_service().native_handle(impl_.get_implementation());
}
/// Cancel all asynchronous operations associated with the serial port.
@@ -313,7 +445,7 @@ public:
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");
}
@@ -327,7 +459,7 @@ public:
*/
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
this->get_service().cancel(this->get_implementation(), ec);
impl_.get_service().cancel(impl_.get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -341,7 +473,7 @@ public:
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");
}
@@ -354,7 +486,7 @@ public:
*/
ASIO_SYNC_OP_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_SYNC_OP_VOID_RETURN(ec);
}
@@ -377,7 +509,7 @@ public:
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");
}
@@ -400,7 +532,7 @@ public:
ASIO_SYNC_OP_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_SYNC_OP_VOID_RETURN(ec);
}
@@ -424,7 +556,7 @@ public:
void get_option(GettableSerialPortOption& option)
{
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");
}
@@ -448,7 +580,7 @@ public:
ASIO_SYNC_OP_VOID get_option(GettableSerialPortOption& option,
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_SYNC_OP_VOID_RETURN(ec);
}
@@ -473,7 +605,7 @@ public:
* @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
@@ -483,8 +615,8 @@ public:
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;
}
@@ -509,8 +641,8 @@ public:
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.
@@ -531,9 +663,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -542,7 +674,8 @@ public:
* @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
@@ -554,12 +687,9 @@ public:
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<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_write_some(), handler, this, buffers);
}
/// Read some data from the serial port.
@@ -584,7 +714,7 @@ public:
* @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
@@ -594,8 +724,8 @@ public:
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;
}
@@ -621,8 +751,8 @@ public:
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.
@@ -643,9 +773,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -655,7 +785,8 @@ public:
* @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
@@ -667,13 +798,55 @@ public:
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<ReadHandler,
void (asio::error_code, std::size_t)>(
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 <typename WriteHandler, typename ConstBufferSequence>
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<WriteHandler> handler2(handler);
self->impl_.get_service().async_write_some(
self->impl_.get_implementation(), buffers, handler2.value,
self->impl_.get_implementation_executor());
}
};
struct initiate_async_read_some
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(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<ReadHandler> 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<detail::win_iocp_serial_port_service, Executor> impl_;
#else
detail::io_object_impl<detail::reactive_serial_port_service, Executor> impl_;
#endif
};
} // namespace asio
@@ -683,6 +856,4 @@ public:
#endif // defined(ASIO_HAS_SERIAL_PORT)
// || defined(GENERATING_DOCUMENTATION)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#endif // ASIO_BASIC_SERIAL_PORT_HPP

View File

@@ -2,7 +2,7 @@
// basic_signal_set.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the 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,24 +17,23 @@
#include "asio/detail/config.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
#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
@@ -56,7 +55,7 @@ namespace asio {
* ...
*
* // Construct a signal set registered for process termination.
* asio::signal_set signals(io_context, 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);
@@ -91,20 +90,40 @@ namespace asio {
* that any signals registered using signal_set objects are unblocked in at
* least one thread.
*/
template <typename SignalSetService = signal_set_service>
template <typename Executor = executor>
class basic_signal_set
: public basic_io_object<SignalSetService>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Construct a signal set without adding any signals.
/**
* This constructor creates a signal set without registering for any signals.
*
* @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* signal set.
*/
explicit basic_signal_set(asio::io_context& io_context)
: basic_io_object<SignalSetService>(io_context)
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 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 <typename ExecutionContext>
explicit basic_signal_set(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
}
@@ -112,20 +131,47 @@ public:
/**
* This constructor creates a signal set and registers for one signal.
*
* @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* signal set.
*
* @param signal_number_1 The signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code asio::signal_set signals(io_context);
* @code asio::signal_set signals(ex);
* signals.add(signal_number_1); @endcode
*/
basic_signal_set(asio::io_context& io_context, int signal_number_1)
: basic_io_object<SignalSetService>(io_context)
basic_signal_set(const executor_type& ex, int signal_number_1)
: impl_(ex)
{
asio::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
asio::detail::throw_error(ec, "add");
}
/// Construct a signal set and add one signal.
/**
* This constructor creates a signal set and registers for one signal.
*
* @param context An execution context which provides the I/O executor that
* the signal set will use, by default, to dispatch handlers for any
* asynchronous operations performed on the signal set.
*
* @param signal_number_1 The signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code asio::signal_set signals(context);
* signals.add(signal_number_1); @endcode
*/
template <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
asio::detail::throw_error(ec, "add");
}
@@ -133,26 +179,59 @@ public:
/**
* This constructor creates a signal set and registers for two signals.
*
* @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* signal set.
*
* @param signal_number_1 The first signal number to be added.
*
* @param signal_number_2 The second signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code asio::signal_set signals(io_context);
* @code asio::signal_set signals(ex);
* signals.add(signal_number_1);
* signals.add(signal_number_2); @endcode
*/
basic_signal_set(asio::io_context& io_context, int signal_number_1,
basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2)
: basic_io_object<SignalSetService>(io_context)
: impl_(ex)
{
asio::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_2, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
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 <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
int signal_number_2,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
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");
}
@@ -160,8 +239,9 @@ public:
/**
* This constructor creates a signal set and registers for three signals.
*
* @param io_context The io_context object that the signal set will use to
* dispatch handlers for any asynchronous operations performed on the set.
* @param ex The I/O executor that the signal set will use, by default, to
* dispatch handlers for any asynchronous operations performed on the
* signal set.
*
* @param signal_number_1 The first signal number to be added.
*
@@ -170,24 +250,77 @@ public:
* @param signal_number_3 The third signal number to be added.
*
* @note This constructor is equivalent to performing:
* @code asio::signal_set signals(io_context);
* @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_context& io_context, int signal_number_1,
basic_signal_set(const executor_type& ex, int signal_number_1,
int signal_number_2, int signal_number_3)
: basic_io_object<SignalSetService>(io_context)
: impl_(ex)
{
asio::error_code ec;
this->get_service().add(this->get_implementation(), signal_number_1, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_1, ec);
asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_2, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_2, ec);
asio::detail::throw_error(ec, "add");
this->get_service().add(this->get_implementation(), signal_number_3, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number_3, ec);
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 <typename ExecutionContext>
basic_signal_set(ExecutionContext& context, int signal_number_1,
int signal_number_2, int signal_number_3,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
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
@@ -200,7 +333,7 @@ public:
void add(int signal_number)
{
asio::error_code ec;
this->get_service().add(this->get_implementation(), signal_number, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
asio::detail::throw_error(ec, "add");
}
@@ -213,9 +346,10 @@ public:
*
* @param ec Set to indicate what error occurred, if any.
*/
ASIO_SYNC_OP_VOID add(int signal_number, asio::error_code& ec)
ASIO_SYNC_OP_VOID add(int signal_number,
asio::error_code& ec)
{
this->get_service().add(this->get_implementation(), signal_number, ec);
impl_.get_service().add(impl_.get_implementation(), signal_number, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -234,7 +368,7 @@ public:
void remove(int signal_number)
{
asio::error_code ec;
this->get_service().remove(this->get_implementation(), signal_number, ec);
impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
asio::detail::throw_error(ec, "remove");
}
@@ -253,7 +387,7 @@ public:
ASIO_SYNC_OP_VOID remove(int signal_number,
asio::error_code& ec)
{
this->get_service().remove(this->get_implementation(), signal_number, ec);
impl_.get_service().remove(impl_.get_implementation(), signal_number, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -269,7 +403,7 @@ public:
void clear()
{
asio::error_code ec;
this->get_service().clear(this->get_implementation(), ec);
impl_.get_service().clear(impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "clear");
}
@@ -284,7 +418,7 @@ public:
*/
ASIO_SYNC_OP_VOID clear(asio::error_code& ec)
{
this->get_service().clear(this->get_implementation(), ec);
impl_.get_service().clear(impl_.get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -312,7 +446,7 @@ public:
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");
}
@@ -339,7 +473,7 @@ public:
*/
ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
{
this->get_service().cancel(this->get_implementation(), ec);
impl_.get_service().cancel(impl_.get_implementation(), ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
@@ -364,28 +498,44 @@ public:
* int signal_number // Indicates which signal occurred.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename SignalHandler>
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->get_service().async_wait(this->get_implementation(),
ASIO_MOVE_CAST(SignalHandler)(handler));
return async_initiate<SignalHandler, void (asio::error_code, int)>(
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 <typename SignalHandler>
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<SignalHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<detail::signal_set_service, Executor> impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#endif // ASIO_BASIC_SIGNAL_SET_HPP

View File

@@ -2,7 +2,7 @@
// basic_socket_iostream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -23,10 +23,6 @@
#include <ostream>
#include "asio/basic_socket_streambuf.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# include "asio/detail/variadic_templates.hpp"
@@ -36,8 +32,7 @@
// explicit basic_socket_iostream(T1 x1, ..., Tn xn)
// : std::basic_iostream<char>(
// &this->detail::socket_iostream_base<
// Protocol ASIO_SVC_TARG, Clock,
// WaitTraits ASIO_SVC_TARG1>::streambuf_)
// Protocol, Clock, WaitTraits>::streambuf_)
// {
// if (rdbuf()->connect(x1, ..., xn) == 0)
// this->setstate(std::ios_base::failbit);
@@ -49,8 +44,7 @@
explicit basic_socket_iostream(ASIO_VARIADIC_BYVAL_PARAMS(n)) \
: std::basic_iostream<char>( \
&this->detail::socket_iostream_base< \
Protocol ASIO_SVC_TARG, Clock, \
WaitTraits ASIO_SVC_TARG1>::streambuf_) \
Protocol, Clock, WaitTraits>::streambuf_) \
{ \
this->setf(std::ios_base::unitbuf); \
if (rdbuf()->connect(ASIO_VARIADIC_BYVAL_ARGS(n)) == 0) \
@@ -85,8 +79,7 @@ namespace detail {
// A separate base class is used to ensure that the streambuf is initialised
// prior to the basic_socket_iostream's basic_iostream base class.
template <typename Protocol ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
class socket_iostream_base
{
protected:
@@ -112,8 +105,7 @@ protected:
}
#endif // defined(ASIO_HAS_MOVE)
basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Clock, WaitTraits ASIO_SVC_TARG1> streambuf_;
basic_socket_streambuf<Protocol, Clock, WaitTraits> streambuf_;
};
} // namespace detail
@@ -122,17 +114,17 @@ protected:
#define ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(ASIO_HAS_BOOST_DATE_TIME)
template <typename Protocol,
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
typename WaitTraits = time_traits<Clock> >
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
typename WaitTraits = wait_traits<Clock> >
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_iostream;
#endif // !defined(ASIO_BASIC_SOCKET_IOSTREAM_FWD_DECL)
@@ -143,22 +135,23 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_iostream
: private detail::socket_iostream_base<Protocol
ASIO_SVC_TARG, Clock, WaitTraits ASIO_SVC_TARG1>,
: private detail::socket_iostream_base<Protocol, Clock, WaitTraits>,
public std::basic_iostream<char>
{
private:
// These typedefs are intended keep this class's implementation independent
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(ASIO_HAS_BOOST_DATE_TIME)
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typedef WaitTraits traits_helper;
#else
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
public:
/// The protocol type.
@@ -195,8 +188,7 @@ public:
basic_socket_iostream()
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@@ -205,12 +197,10 @@ public:
/// Construct a basic_socket_iostream from the supplied socket.
explicit basic_socket_iostream(basic_stream_socket<protocol_type> s)
: detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>(std::move(s)),
Protocol, Clock, WaitTraits>(std::move(s)),
std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
}
@@ -220,13 +210,11 @@ public:
/// Move-construct a basic_socket_iostream from another.
basic_socket_iostream(basic_socket_iostream&& other)
: detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>(std::move(other)),
Protocol, Clock, WaitTraits>(std::move(other)),
std::basic_iostream<char>(std::move(other))
{
this->set_rdbuf(&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_);
Protocol, Clock, WaitTraits>::streambuf_);
}
/// Move-assign a basic_socket_iostream from another.
@@ -234,8 +222,7 @@ public:
{
std::basic_iostream<char>::operator=(std::move(other));
detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::operator=(std::move(other));
Protocol, Clock, WaitTraits>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_STD_IOSTREAM_MOVE)
@@ -256,8 +243,7 @@ public:
explicit basic_socket_iostream(T... x)
: std::basic_iostream<char>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_)
Protocol, Clock, WaitTraits>::streambuf_)
{
this->setf(std::ios_base::unitbuf);
if (rdbuf()->connect(x...) == 0)
@@ -295,18 +281,15 @@ public:
}
/// Return a pointer to the underlying streambuf.
basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Clock, WaitTraits ASIO_SVC_TARG1>* rdbuf() const
basic_socket_streambuf<Protocol, Clock, WaitTraits>* rdbuf() const
{
return const_cast<basic_socket_streambuf<Protocol ASIO_SVC_TARG,
Clock, WaitTraits ASIO_SVC_TARG1>*>(
return const_cast<basic_socket_streambuf<Protocol, Clock, WaitTraits>*>(
&this->detail::socket_iostream_base<
Protocol ASIO_SVC_TARG, Clock,
WaitTraits ASIO_SVC_TARG1>::streambuf_);
Protocol, Clock, WaitTraits>::streambuf_);
}
/// Get a reference to the underlying socket.
basic_socket<Protocol ASIO_SVC_TARG>& socket()
basic_socket<Protocol>& socket()
{
return rdbuf()->socket();
}

View File

@@ -2,7 +2,7 @@
// basic_socket_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -28,19 +28,14 @@
#include "asio/detail/throw_error.hpp"
#include "asio/io_context.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#if defined(ASIO_HAS_BOOST_DATE_TIME)
# if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/deadline_timer_service.hpp"
# else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/deadline_timer_service.hpp"
# endif // defined(ASIO_ENABLE_OLD_SERVICES)
#else
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# include "asio/detail/deadline_timer_service.hpp"
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
# include "asio/steady_timer.hpp"
#endif
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
@@ -52,7 +47,7 @@
// {
// init_buffers();
// typedef typename Protocol::resolver resolver_type;
// resolver_type resolver(socket().get_executor().context());
// resolver_type resolver(socket().get_executor());
// connect_to_endpoints(
// resolver.resolve(x1, ..., xn, ec_));
// return !ec_ ? this : 0;
@@ -65,7 +60,7 @@
{ \
init_buffers(); \
typedef typename Protocol::resolver resolver_type; \
resolver_type resolver(socket().get_executor().context()); \
resolver_type resolver(socket().get_executor()); \
connect_to_endpoints( \
resolver.resolve(ASIO_VARIADIC_BYVAL_ARGS(n), ec_)); \
return !ec_ ? this : 0; \
@@ -74,10 +69,6 @@
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# define ASIO_SVC_T1 detail::deadline_timer_service<traits_helper>
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
@@ -121,17 +112,17 @@ protected:
#define ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>),
#if defined(ASIO_HAS_BOOST_DATE_TIME)
template <typename Protocol,
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = boost::posix_time::ptime,
typename WaitTraits = time_traits<Clock>
ASIO_SVC_TPARAM1_DEF2(= deadline_timer_service<Clock, WaitTraits>)>
#else
typename WaitTraits = time_traits<Clock> >
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock>
ASIO_SVC_TPARAM1_DEF1(= steady_timer::service_type)>
#endif
typename WaitTraits = wait_traits<Clock> >
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
class basic_socket_streambuf;
#endif // !defined(ASIO_BASIC_SOCKET_STREAMBUF_FWD_DECL)
@@ -142,27 +133,29 @@ template <typename Protocol,
typename Clock = chrono::steady_clock,
typename WaitTraits = wait_traits<Clock> >
#else // defined(GENERATING_DOCUMENTATION)
template <typename Protocol ASIO_SVC_TPARAM,
typename Clock, typename WaitTraits ASIO_SVC_TPARAM1>
template <typename Protocol, typename Clock, typename WaitTraits>
#endif // defined(GENERATING_DOCUMENTATION)
class basic_socket_streambuf
: public std::streambuf,
private detail::socket_streambuf_io_context,
private detail::socket_streambuf_buffers,
#if defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
private basic_socket<Protocol ASIO_SVC_TARG>
private basic_socket<Protocol>
#else // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
public basic_socket<Protocol ASIO_SVC_TARG>
public basic_socket<Protocol>
#endif // defined(ASIO_NO_DEPRECATED) || defined(GENERATING_DOCUMENTATION)
{
private:
// These typedefs are intended keep this class's implementation independent
// of whether it's using Boost.DateClock, Boost.Chrono or std::chrono.
#if defined(ASIO_HAS_BOOST_DATE_TIME)
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typedef WaitTraits traits_helper;
#else
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
typedef detail::chrono_time_traits<Clock, WaitTraits> traits_helper;
#endif
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
public:
/// The protocol type.
@@ -198,7 +191,7 @@ public:
/// Construct a basic_socket_streambuf without establishing a connection.
basic_socket_streambuf()
: detail::socket_streambuf_io_context(new io_context),
basic_socket<Protocol ASIO_SVC_TARG>(*default_io_context_),
basic_socket<Protocol>(*default_io_context_),
expiry_time_(max_expiry_time())
{
init_buffers();
@@ -208,7 +201,7 @@ public:
/// Construct a basic_socket_streambuf from the supplied socket.
explicit basic_socket_streambuf(basic_stream_socket<protocol_type> s)
: detail::socket_streambuf_io_context(0),
basic_socket<Protocol ASIO_SVC_TARG>(std::move(s)),
basic_socket<Protocol>(std::move(s)),
expiry_time_(max_expiry_time())
{
init_buffers();
@@ -217,7 +210,7 @@ public:
/// Move-construct a basic_socket_streambuf from another.
basic_socket_streambuf(basic_socket_streambuf&& other)
: detail::socket_streambuf_io_context(other),
basic_socket<Protocol ASIO_SVC_TARG>(std::move(other.socket())),
basic_socket<Protocol>(std::move(other.socket())),
ec_(other.ec_),
expiry_time_(other.expiry_time_)
{
@@ -290,7 +283,7 @@ public:
{
init_buffers();
typedef typename Protocol::resolver resolver_type;
resolver_type resolver(socket().get_executor().context());
resolver_type resolver(socket().get_executor());
connect_to_endpoints(resolver.resolve(x..., ec_));
return !ec_ ? this : 0;
}
@@ -313,7 +306,7 @@ public:
}
/// Get a reference to the underlying socket.
basic_socket<Protocol ASIO_SVC_TARG>& socket()
basic_socket<Protocol>& socket()
{
return *this;
}
@@ -666,11 +659,14 @@ private:
// Helper function to get the maximum expiry time.
static time_point max_expiry_time()
{
#if defined(ASIO_HAS_BOOST_DATE_TIME)
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
&& defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
return boost::posix_time::pos_infin;
#else // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
return (time_point::max)();
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// && defined(ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM)
}
enum { putback_max = 8 };
@@ -682,10 +678,6 @@ private:
#include "asio/detail/pop_options.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# undef ASIO_SVC_T1
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#if !defined(ASIO_HAS_VARIADIC_TEMPLATES)
# undef ASIO_PRIVATE_CONNECT_DEF
#endif // !defined(ASIO_HAS_VARIADIC_TEMPLATES)

View File

@@ -2,7 +2,7 @@
// basic_stream_socket.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -20,17 +20,23 @@
#include "asio/async_result.hpp"
#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/error.hpp"
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/stream_socket_service.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
#if !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
#define ASIO_BASIC_STREAM_SOCKET_FWD_DECL
// Forward declaration with defaulted arguments.
template <typename Protocol, typename Executor = executor>
class basic_stream_socket;
#endif // !defined(ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
/// Provides stream-oriented socket functionality.
/**
* The basic_stream_socket class template provides asynchronous and blocking
@@ -43,18 +49,28 @@ namespace asio {
* @par Concepts:
* AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
*/
template <typename Protocol
ASIO_SVC_TPARAM_DEF1(= stream_socket_service<Protocol>)>
template <typename Protocol, typename Executor>
class basic_stream_socket
: public basic_socket<Protocol ASIO_SVC_TARG>
: public basic_socket<Protocol, Executor>
{
public:
/// The type of the executor associated with the object.
typedef Executor executor_type;
/// Rebinds the socket type to another executor.
template <typename Executor1>
struct rebind_executor
{
/// The socket type when rebound to the specified executor.
typedef basic_stream_socket<Protocol, Executor1> other;
};
/// The native representation of a socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename basic_socket<
Protocol ASIO_SVC_TARG>::native_handle_type native_handle_type;
typedef typename basic_socket<Protocol,
Executor>::native_handle_type native_handle_type;
#endif
/// The protocol type.
@@ -69,11 +85,30 @@ public:
* needs to be opened and then connected or accepted before data can be sent
* or received on it.
*
* @param io_context The io_context object that the stream socket will use to
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*/
explicit basic_stream_socket(asio::io_context& io_context)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context)
explicit basic_stream_socket(const executor_type& ex)
: basic_socket<Protocol, Executor>(ex)
{
}
/// Construct a basic_stream_socket without opening it.
/**
* This constructor creates a stream socket without opening it. The socket
* needs to be opened and then connected or accepted before data can be sent
* or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*/
template <typename ExecutionContext>
explicit basic_stream_socket(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context)
{
}
@@ -82,16 +117,37 @@ public:
* This constructor creates and opens a stream socket. The socket needs to be
* connected or accepted before data can be sent or received on it.
*
* @param io_context The io_context object that the stream socket will use to
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
basic_stream_socket(asio::io_context& io_context,
const protocol_type& protocol)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, protocol)
basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
: basic_socket<Protocol, Executor>(ex, protocol)
{
}
/// Construct and open a basic_stream_socket.
/**
* This constructor creates and opens a stream socket. The socket needs to be
* connected or accepted before data can be sent or received on it.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol)
{
}
@@ -102,7 +158,7 @@ public:
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param io_context The io_context object that the stream socket will use to
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the stream
@@ -110,9 +166,33 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
basic_stream_socket(asio::io_context& io_context,
const endpoint_type& endpoint)
: basic_socket<Protocol ASIO_SVC_TARG>(io_context, endpoint)
basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
: basic_socket<Protocol, Executor>(ex, endpoint)
{
}
/// Construct a basic_stream_socket, opening it and binding it to the given
/// local endpoint.
/**
* This constructor creates a stream socket and automatically opens it bound
* to the specified endpoint on the local machine. The protocol used is the
* protocol associated with the given endpoint.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param endpoint An endpoint on the local machine to which the stream
* socket will be bound.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, endpoint)
{
}
@@ -121,7 +201,7 @@ public:
* This constructor creates a stream socket object to hold an existing native
* socket.
*
* @param io_context The io_context object that the stream socket will use to
* @param ex The I/O executor that the socket will use, by default, to
* dispatch handlers for any asynchronous operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
@@ -130,10 +210,34 @@ public:
*
* @throws asio::system_error Thrown on failure.
*/
basic_stream_socket(asio::io_context& io_context,
basic_stream_socket(const executor_type& ex,
const protocol_type& protocol, const native_handle_type& native_socket)
: basic_socket<Protocol ASIO_SVC_TARG>(
io_context, protocol, native_socket)
: basic_socket<Protocol, Executor>(ex, protocol, native_socket)
{
}
/// Construct a basic_stream_socket on an existing native socket.
/**
* This constructor creates a stream socket object to hold an existing native
* socket.
*
* @param context An execution context which provides the I/O executor that
* the socket will use, by default, to dispatch handlers for any asynchronous
* operations performed on the socket.
*
* @param protocol An object specifying protocol parameters to be used.
*
* @param native_socket The new underlying socket implementation.
*
* @throws asio::system_error Thrown on failure.
*/
template <typename ExecutionContext>
basic_stream_socket(ExecutionContext& context,
const protocol_type& protocol, const native_handle_type& native_socket,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(context, protocol, native_socket)
{
}
@@ -146,10 +250,11 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
basic_stream_socket(basic_stream_socket&& other)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -161,11 +266,12 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
basic_stream_socket& operator=(basic_stream_socket&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
@@ -178,13 +284,16 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
basic_stream_socket(
basic_stream_socket<Protocol1 ASIO_SVC_TARG1>&& other,
typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
: basic_socket<Protocol ASIO_SVC_TARG>(std::move(other))
template <typename Protocol1, typename Executor1>
basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value
>::type* = 0)
: basic_socket<Protocol, Executor>(std::move(other))
{
}
@@ -196,14 +305,17 @@ public:
* will occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_stream_socket(io_context&) constructor.
* constructed using the @c basic_stream_socket(const executor_type&)
* constructor.
*/
template <typename Protocol1 ASIO_SVC_TPARAM1>
typename enable_if<is_convertible<Protocol1, Protocol>::value,
basic_stream_socket>::type& operator=(
basic_stream_socket<Protocol1 ASIO_SVC_TARG1>&& other)
template <typename Protocol1, typename Executor1>
typename enable_if<
is_convertible<Protocol1, Protocol>::value
&& is_convertible<Executor1, Executor>::value,
basic_stream_socket&
>::type operator=(basic_stream_socket<Protocol1, Executor1>&& other)
{
basic_socket<Protocol ASIO_SVC_TARG>::operator=(std::move(other));
basic_socket<Protocol, Executor>::operator=(std::move(other));
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -246,8 +358,8 @@ public:
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;
}
@@ -284,8 +396,8 @@ public:
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;
}
@@ -312,8 +424,8 @@ public:
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.
@@ -334,9 +446,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -357,24 +469,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, 0,
ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(
this->get_implementation(), buffers, 0,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous send.
@@ -397,9 +495,9 @@ public:
* std::size_t bytes_transferred // Number of bytes sent.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note The send operation may not transmit all of the data to the peer.
* Consider using the @ref async_write function if you need to ensure that all
@@ -421,24 +519,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(
this->get_implementation(), buffers, flags,
ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(
this->get_implementation(), buffers, flags,
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this, buffers, flags);
}
/// Receive some data on the socket.
@@ -473,8 +556,8 @@ public:
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;
}
@@ -514,8 +597,8 @@ public:
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;
}
@@ -542,8 +625,8 @@ public:
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.
@@ -564,9 +647,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -589,22 +672,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Start an asynchronous receive.
@@ -627,9 +698,9 @@ public:
* std::size_t bytes_transferred // Number of bytes received.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note The receive operation may not receive all of the requested number of
* bytes. Consider using the @ref async_read function if you need to ensure
@@ -653,22 +724,9 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, flags, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this, buffers, flags);
}
/// Write some data to the socket.
@@ -702,8 +760,8 @@ public:
std::size_t write_some(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, "write_some");
return s;
}
@@ -728,7 +786,8 @@ public:
std::size_t write_some(const ConstBufferSequence& buffers,
asio::error_code& ec)
{
return this->get_service().send(this->get_implementation(), buffers, 0, ec);
return this->impl_.get_service().send(
this->impl_.get_implementation(), buffers, 0, ec);
}
/// Start an asynchronous write.
@@ -749,9 +808,9 @@ public:
* std::size_t bytes_transferred // Number of bytes written.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -772,22 +831,10 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_send(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_send(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WriteHandler,
void (asio::error_code, std::size_t)>(
initiate_async_send(), handler, this,
buffers, socket_base::message_flags(0));
}
/// Read some data from the socket.
@@ -822,8 +869,8 @@ public:
std::size_t read_some(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, "read_some");
return s;
}
@@ -849,8 +896,8 @@ public:
std::size_t read_some(const MutableBufferSequence& buffers,
asio::error_code& ec)
{
return this->get_service().receive(
this->get_implementation(), buffers, 0, ec);
return this->impl_.get_service().receive(
this->impl_.get_implementation(), buffers, 0, ec);
}
/// Start an asynchronous read.
@@ -871,9 +918,9 @@ public:
* std::size_t bytes_transferred // Number of bytes read.
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using 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
@@ -895,23 +942,48 @@ public:
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_receive(this->get_implementation(),
buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
this->get_service().async_receive(this->get_implementation(),
buffers, 0, init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<ReadHandler,
void (asio::error_code, std::size_t)>(
initiate_async_receive(), handler, this,
buffers, socket_base::message_flags(0));
}
private:
struct initiate_async_send
{
template <typename WriteHandler, typename ConstBufferSequence>
void operator()(ASIO_MOVE_ARG(WriteHandler) handler,
basic_stream_socket* self, const ConstBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WriteHandler.
ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
detail::non_const_lvalue<WriteHandler> handler2(handler);
self->impl_.get_service().async_send(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
struct initiate_async_receive
{
template <typename ReadHandler, typename MutableBufferSequence>
void operator()(ASIO_MOVE_ARG(ReadHandler) handler,
basic_stream_socket* self, const MutableBufferSequence& buffers,
socket_base::message_flags flags) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a ReadHandler.
ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
detail::non_const_lvalue<ReadHandler> handler2(handler);
self->impl_.get_service().async_receive(
self->impl_.get_implementation(), buffers, flags,
handler2.value, self->impl_.get_implementation_executor());
}
};
};
} // namespace asio

View File

@@ -2,7 +2,7 @@
// basic_streambuf.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// basic_streambuf_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// basic_waitable_timer.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -17,26 +17,20 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/basic_io_object.hpp"
#include "asio/detail/chrono_time_traits.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/executor.hpp"
#include "asio/wait_traits.hpp"
#if defined(ASIO_HAS_MOVE)
# include <utility>
#endif // defined(ASIO_HAS_MOVE)
#if defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/waitable_timer_service.hpp"
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# include "asio/detail/chrono_time_traits.hpp"
# include "asio/detail/deadline_timer_service.hpp"
# define ASIO_SVC_T \
detail::deadline_timer_service< \
detail::chrono_time_traits<Clock, WaitTraits> >
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#include "asio/detail/push_options.hpp"
namespace asio {
@@ -46,8 +40,8 @@ namespace asio {
// Forward declaration with defaulted arguments.
template <typename Clock,
typename WaitTraits = asio::wait_traits<Clock>
ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)>
typename WaitTraits = asio::wait_traits<Clock>,
typename Executor = executor>
class basic_waitable_timer;
#endif // !defined(ASIO_BASIC_WAITABLE_TIMER_FWD_DECL)
@@ -75,7 +69,7 @@ class basic_waitable_timer;
* Performing a blocking wait (C++11):
* @code
* // Construct a timer without setting an expiry time.
* asio::steady_timer timer(io_context);
* asio::steady_timer timer(my_context);
*
* // Set an expiry time relative to now.
* timer.expires_after(std::chrono::seconds(5));
@@ -98,7 +92,7 @@ class basic_waitable_timer;
* ...
*
* // Construct a timer with an absolute expiry time.
* asio::steady_timer timer(io_context,
* asio::steady_timer timer(my_context,
* std::chrono::steady_clock::now() + std::chrono::seconds(60));
*
* // Start an asynchronous wait.
@@ -144,13 +138,12 @@ class basic_waitable_timer;
* @li If a wait handler is cancelled, the asio::error_code passed to
* it contains the value asio::error::operation_aborted.
*/
template <typename Clock, typename WaitTraits ASIO_SVC_TPARAM>
template <typename Clock, typename WaitTraits, typename Executor>
class basic_waitable_timer
: ASIO_SVC_ACCESS basic_io_object<ASIO_SVC_T>
{
public:
/// The type of the executor associated with the object.
typedef io_context::executor_type executor_type;
typedef Executor executor_type;
/// The clock type.
typedef Clock clock_type;
@@ -170,11 +163,30 @@ public:
* expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*/
explicit basic_waitable_timer(asio::io_context& io_context)
: basic_io_object<ASIO_SVC_T>(io_context)
explicit basic_waitable_timer(const executor_type& ex)
: impl_(ex)
{
}
/// Constructor.
/**
* This constructor creates a timer without setting an expiry time. The
* expires_at() or expires_after() functions must be called to set an expiry
* time before the timer can be waited on.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
}
@@ -182,18 +194,41 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor object that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
basic_waitable_timer(asio::io_context& io_context,
const time_point& expiry_time)
: basic_io_object<ASIO_SVC_T>(io_context)
basic_waitable_timer(const executor_type& ex, const time_point& expiry_time)
: impl_(ex)
{
asio::error_code ec;
this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
}
/// Constructor to set a particular expiry time as an absolute time.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, expressed
* as an absolute time.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
const time_point& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
}
@@ -201,19 +236,43 @@ public:
/**
* This constructor creates a timer and sets the expiry time.
*
* @param io_context The io_context object that the timer will use to dispatch
* handlers for any asynchronous operations performed on the timer.
* @param ex The I/O executor that the timer will use, by default, to
* dispatch handlers for any asynchronous operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
basic_waitable_timer(asio::io_context& io_context,
const duration& expiry_time)
: basic_io_object<ASIO_SVC_T>(io_context)
basic_waitable_timer(const executor_type& ex, const duration& expiry_time)
: impl_(ex)
{
asio::error_code ec;
this->get_service().expires_after(
this->get_implementation(), expiry_time, ec);
impl_.get_service().expires_after(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_after");
}
/// Constructor to set a particular expiry time relative to now.
/**
* This constructor creates a timer and sets the expiry time.
*
* @param context An execution context which provides the I/O executor that
* the timer will use, by default, to dispatch handlers for any asynchronous
* operations performed on the timer.
*
* @param expiry_time The expiry time to be used for the timer, relative to
* now.
*/
template <typename ExecutionContext>
explicit basic_waitable_timer(ExecutionContext& context,
const duration& expiry_time,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0)
: impl_(context)
{
asio::error_code ec;
impl_.get_service().expires_after(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_after");
}
@@ -226,10 +285,11 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_waitable_timer(io_context&) constructor.
* constructed using the @c basic_waitable_timer(const executor_type&)
* constructor.
*/
basic_waitable_timer(basic_waitable_timer&& other)
: basic_io_object<ASIO_SVC_T>(std::move(other))
: impl_(std::move(other.impl_))
{
}
@@ -242,11 +302,12 @@ public:
* occur.
*
* @note Following the move, the moved-from object is in the same state as if
* constructed using the @c basic_waitable_timer(io_context&) constructor.
* constructed using the @c basic_waitable_timer(const executor_type&)
* constructor.
*/
basic_waitable_timer& operator=(basic_waitable_timer&& other)
{
basic_io_object<ASIO_SVC_T>::operator=(std::move(other));
impl_ = std::move(other.impl_);
return *this;
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
@@ -260,45 +321,11 @@ public:
{
}
#if defined(ASIO_ENABLE_OLD_SERVICES)
// These functions are provided by basic_io_object<>.
#else // defined(ASIO_ENABLE_OLD_SERVICES)
#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_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_context()
{
return basic_io_object<ASIO_SVC_T>::get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
/**
* This function may be used to obtain the io_context object that the I/O
* object uses to dispatch handlers for asynchronous operations.
*
* @return A reference to the io_context object that the I/O object will use
* to dispatch handlers. Ownership is not transferred to the caller.
*/
asio::io_context& get_io_service()
{
return basic_io_object<ASIO_SVC_T>::get_io_service();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Get the executor associated with the object.
executor_type get_executor() ASIO_NOEXCEPT
{
return basic_io_object<ASIO_SVC_T>::get_executor();
return impl_.get_executor();
}
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
/// Cancel any asynchronous operations that are waiting on the timer.
/**
@@ -325,7 +352,7 @@ public:
std::size_t cancel()
{
asio::error_code ec;
std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "cancel");
return s;
}
@@ -356,7 +383,7 @@ public:
*/
std::size_t cancel(asio::error_code& ec)
{
return this->get_service().cancel(this->get_implementation(), ec);
return impl_.get_service().cancel(impl_.get_implementation(), ec);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -387,8 +414,8 @@ public:
std::size_t cancel_one()
{
asio::error_code ec;
std::size_t s = this->get_service().cancel_one(
this->get_implementation(), ec);
std::size_t s = impl_.get_service().cancel_one(
impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "cancel_one");
return s;
}
@@ -421,7 +448,7 @@ public:
*/
std::size_t cancel_one(asio::error_code& ec)
{
return this->get_service().cancel_one(this->get_implementation(), ec);
return impl_.get_service().cancel_one(impl_.get_implementation(), ec);
}
/// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute
@@ -432,7 +459,7 @@ public:
*/
time_point expires_at() const
{
return this->get_service().expires_at(this->get_implementation());
return impl_.get_service().expires_at(impl_.get_implementation());
}
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -443,7 +470,7 @@ public:
*/
time_point expiry() const
{
return this->get_service().expiry(this->get_implementation());
return impl_.get_service().expiry(impl_.get_implementation());
}
/// Set the timer's expiry time as an absolute time.
@@ -471,8 +498,8 @@ public:
std::size_t expires_at(const time_point& expiry_time)
{
asio::error_code ec;
std::size_t s = this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_at");
return s;
}
@@ -504,8 +531,8 @@ public:
std::size_t expires_at(const time_point& expiry_time,
asio::error_code& ec)
{
return this->get_service().expires_at(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_at(
impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -534,8 +561,8 @@ public:
std::size_t expires_after(const duration& expiry_time)
{
asio::error_code ec;
std::size_t s = this->get_service().expires_after(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_after(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_after");
return s;
}
@@ -548,7 +575,7 @@ public:
*/
duration expires_from_now() const
{
return this->get_service().expires_from_now(this->get_implementation());
return impl_.get_service().expires_from_now(impl_.get_implementation());
}
/// (Deprecated: Use expires_after().) Set the timer's expiry time relative
@@ -577,8 +604,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time)
{
asio::error_code ec;
std::size_t s = this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
std::size_t s = impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
asio::detail::throw_error(ec, "expires_from_now");
return s;
}
@@ -609,8 +636,8 @@ public:
std::size_t expires_from_now(const duration& expiry_time,
asio::error_code& ec)
{
return this->get_service().expires_from_now(
this->get_implementation(), expiry_time, ec);
return impl_.get_service().expires_from_now(
impl_.get_implementation(), expiry_time, ec);
}
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -624,7 +651,7 @@ public:
void wait()
{
asio::error_code ec;
this->get_service().wait(this->get_implementation(), ec);
impl_.get_service().wait(impl_.get_implementation(), ec);
asio::detail::throw_error(ec, "wait");
}
@@ -637,7 +664,7 @@ public:
*/
void wait(asio::error_code& ec)
{
this->get_service().wait(this->get_implementation(), ec);
impl_.get_service().wait(impl_.get_implementation(), ec);
}
/// Start an asynchronous wait on the timer.
@@ -660,31 +687,17 @@ public:
* 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_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*/
template <typename WaitHandler>
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;
#if defined(ASIO_ENABLE_OLD_SERVICES)
return this->get_service().async_wait(this->get_implementation(),
ASIO_MOVE_CAST(WaitHandler)(handler));
#else // defined(ASIO_ENABLE_OLD_SERVICES)
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
this->get_service().async_wait(this->get_implementation(),
init.completion_handler);
return init.result.get();
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
return async_initiate<WaitHandler, void (asio::error_code)>(
initiate_async_wait(), handler, this);
}
private:
@@ -692,14 +705,32 @@ private:
basic_waitable_timer(const basic_waitable_timer&) ASIO_DELETED;
basic_waitable_timer& operator=(
const basic_waitable_timer&) ASIO_DELETED;
struct initiate_async_wait
{
template <typename WaitHandler>
void operator()(ASIO_MOVE_ARG(WaitHandler) handler,
basic_waitable_timer* self) const
{
// If you get an error on the following line it means that your handler
// does not meet the documented type requirements for a WaitHandler.
ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
detail::non_const_lvalue<WaitHandler> handler2(handler);
self->impl_.get_service().async_wait(
self->impl_.get_implementation(), handler2.value,
self->impl_.get_implementation_executor());
}
};
detail::io_object_impl<
detail::deadline_timer_service<
detail::chrono_time_traits<Clock, WaitTraits> >,
executor_type > impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#if !defined(ASIO_ENABLE_OLD_SERVICES)
# undef ASIO_SVC_T
#endif // !defined(ASIO_ENABLE_OLD_SERVICES)
#endif // ASIO_BASIC_WAITABLE_TIMER_HPP

View File

@@ -2,7 +2,7 @@
// bind_executor.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -547,37 +547,6 @@ private:
async_result<T, Signature> target_;
};
#if !defined(ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Signature>
struct handler_type<executor_binder<T, Executor>, Signature>
{
typedef executor_binder<
typename handler_type<T, Signature>::type, Executor> type;
};
template <typename T, typename Executor>
class async_result<executor_binder<T, Executor> >
{
public:
typedef typename async_result<T>::type type;
explicit async_result(executor_binder<T, Executor>& b)
: target_(b.get())
{
}
type get()
{
return target_.get();
}
private:
async_result<T> target_;
};
#endif // !defined(ASIO_NO_DEPRECATED)
template <typename T, typename Executor, typename Allocator>
struct associated_allocator<executor_binder<T, Executor>, Allocator>
{

View File

@@ -2,7 +2,7 @@
// buffer.hpp
// ~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -23,7 +23,7 @@
#include <string>
#include <vector>
#include "asio/detail/array_fwd.hpp"
#include "asio/detail/is_buffer_sequence.hpp"
#include "asio/detail/memory.hpp"
#include "asio/detail/string_view.hpp"
#include "asio/detail/throw_exception.hpp"
#include "asio/detail/type_traits.hpp"
@@ -346,41 +346,6 @@ public:
#endif // !defined(ASIO_NO_DEPRECATED)
/// Trait to determine whether a type satisfies the MutableBufferSequence
/// requirements.
template <typename T>
struct is_mutable_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_buffer_sequence<T, mutable_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the ConstBufferSequence
/// requirements.
template <typename T>
struct is_const_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_buffer_sequence<T, const_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
template <typename T>
struct is_dynamic_buffer
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_dynamic_buffer<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// (Deprecated: Use the socket/descriptor wait() and async_wait() member
/// functions.) An implementation of both the ConstBufferSequence and
/// MutableBufferSequence concepts to represent a null buffer sequence.
@@ -417,29 +382,45 @@ private:
/*@{*/
/// Get an iterator to the first element in a buffer sequence.
inline const mutable_buffer* buffer_sequence_begin(const mutable_buffer& b)
template <typename MutableBuffer>
inline const mutable_buffer* buffer_sequence_begin(const MutableBuffer& b,
typename enable_if<
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return &b;
return static_cast<const mutable_buffer*>(detail::addressof(b));
}
/// Get an iterator to the first element in a buffer sequence.
inline const const_buffer* buffer_sequence_begin(const const_buffer& b)
template <typename ConstBuffer>
inline const const_buffer* buffer_sequence_begin(const ConstBuffer& b,
typename enable_if<
is_convertible<const ConstBuffer*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return &b;
return static_cast<const const_buffer*>(detail::addressof(b));
}
#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to the first element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_begin(C& c) -> decltype(c.begin())
inline auto buffer_sequence_begin(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT -> decltype(c.begin())
{
return c.begin();
}
/// Get an iterator to the first element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
inline auto buffer_sequence_begin(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT -> decltype(c.begin())
{
return c.begin();
}
@@ -447,13 +428,21 @@ inline auto buffer_sequence_begin(const C& c) -> decltype(c.begin())
#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C>
inline typename C::iterator buffer_sequence_begin(C& c)
inline typename C::iterator buffer_sequence_begin(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return c.begin();
}
template <typename C>
inline typename C::const_iterator buffer_sequence_begin(const C& c)
inline typename C::const_iterator buffer_sequence_begin(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return c.begin();
}
@@ -470,29 +459,45 @@ inline typename C::const_iterator buffer_sequence_begin(const C& c)
/*@{*/
/// Get an iterator to one past the end element in a buffer sequence.
inline const mutable_buffer* buffer_sequence_end(const mutable_buffer& b)
template <typename MutableBuffer>
inline const mutable_buffer* buffer_sequence_end(const MutableBuffer& b,
typename enable_if<
is_convertible<const MutableBuffer*, const mutable_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return &b + 1;
return static_cast<const mutable_buffer*>(detail::addressof(b)) + 1;
}
/// Get an iterator to one past the end element in a buffer sequence.
inline const const_buffer* buffer_sequence_end(const const_buffer& b)
template <typename ConstBuffer>
inline const const_buffer* buffer_sequence_end(const ConstBuffer& b,
typename enable_if<
is_convertible<const ConstBuffer*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return &b + 1;
return static_cast<const const_buffer*>(detail::addressof(b)) + 1;
}
#if defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_end(C& c) -> decltype(c.end())
inline auto buffer_sequence_end(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT -> decltype(c.end())
{
return c.end();
}
/// Get an iterator to one past the end element in a buffer sequence.
template <typename C>
inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
inline auto buffer_sequence_end(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT -> decltype(c.end())
{
return c.end();
}
@@ -500,13 +505,21 @@ inline auto buffer_sequence_end(const C& c) -> decltype(c.end())
#else // defined(ASIO_HAS_DECLTYPE) || defined(GENERATING_DOCUMENTATION)
template <typename C>
inline typename C::iterator buffer_sequence_end(C& c)
inline typename C::iterator buffer_sequence_end(C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return c.end();
}
template <typename C>
inline typename C::const_iterator buffer_sequence_end(const C& c)
inline typename C::const_iterator buffer_sequence_end(const C& c,
typename enable_if<
!is_convertible<const C*, const mutable_buffer*>::value
&& !is_convertible<const C*, const const_buffer*>::value
>::type* = 0) ASIO_NOEXCEPT
{
return c.end();
}
@@ -706,7 +719,7 @@ public:
void operator()()
{
*iter_;
(void)*iter_;
}
private:
@@ -1403,7 +1416,7 @@ inline ASIO_MUTABLE_BUFFER buffer(
);
}
/// Create a new non-modifiable buffer that represents the given string.
/// Create a new modifiable buffer that represents the given string.
/**
* @returns A mutable_buffer value equivalent to:
* @code mutable_buffer(
@@ -1475,7 +1488,7 @@ inline ASIO_CONST_BUFFER buffer(
);
}
#if defined(ASIO_HAS_STD_STRING_VIEW) \
#if defined(ASIO_HAS_STRING_VIEW) \
|| defined(GENERATING_DOCUMENTATION)
/// Create a new modifiable buffer that represents the given string_view.
@@ -1520,7 +1533,7 @@ inline ASIO_CONST_BUFFER buffer(
);
}
#endif // defined(ASIO_HAS_STD_STRING_VIEW)
#endif // defined(ASIO_HAS_STRING_VIEW)
// || defined(GENERATING_DOCUMENTATION)
/*@}*/
@@ -1533,19 +1546,23 @@ template <typename Elem, typename Traits, typename Allocator>
class dynamic_string_buffer
{
public:
/// The type used to represent the input sequence as a list of buffers.
/// The type used to represent a sequence of constant buffers that refers to
/// the underlying memory.
typedef ASIO_CONST_BUFFER const_buffers_type;
/// The type used to represent the output sequence as a list of buffers.
/// The type used to represent a sequence of mutable buffers that refers to
/// the underlying memory.
typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;
/// Construct a dynamic buffer from a string.
/**
* @param s The string to be used as backing storage for the dynamic buffer.
* Any existing data in the string is treated as the dynamic buffer's input
* sequence. The object stores a reference to the string and the user is
* responsible for ensuring that the string object remains valid until the
* dynamic_string_buffer object is destroyed.
* The object stores a reference to the string and the user is responsible
* for ensuring that the string object remains valid while the
* dynamic_string_buffer object, and copies of the object, are in use.
*
* @b DynamicBuffer_v1: Any existing data in the string is treated as the
* dynamic buffer's input sequence.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@@ -1553,64 +1570,131 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT
: string_(s),
size_(string_.size()),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_((std::numeric_limits<std::size_t>::max)()),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size)
{
}
/// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
dynamic_string_buffer(const dynamic_string_buffer& other) ASIO_NOEXCEPT
: string_(other.string_),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer.
dynamic_string_buffer(dynamic_string_buffer&& other) ASIO_NOEXCEPT
: string_(other.string_),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Get the size of the input sequence.
/// @b DynamicBuffer_v1: Get the size of the input sequence.
/// @b DynamicBuffer_v2: Get the current size of the underlying memory.
/**
* @returns @b DynamicBuffer_v1 The current size of the input sequence.
* @b DynamicBuffer_v2: The current size of the underlying string if less than
* max_size(). Otherwise returns max_size().
*/
std::size_t size() const ASIO_NOEXCEPT
{
return size_;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
return size_;
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
return (std::min)(string_.size(), max_size());
}
/// Get the maximum size of the dynamic buffer.
/**
* @returns The allowed maximum of the sum of the sizes of the input sequence
* and output sequence.
* @returns The allowed maximum size of the underlying memory.
*/
std::size_t max_size() const ASIO_NOEXCEPT
{
return max_size_;
}
/// Get the current capacity of the dynamic buffer.
/// Get the maximum size that the buffer may grow to without triggering
/// reallocation.
/**
* @returns The current total capacity of the buffer, i.e. for both the input
* sequence and output sequence.
* @returns The current capacity of the underlying string if less than
* max_size(). Otherwise returns max_size().
*/
std::size_t capacity() const ASIO_NOEXCEPT
{
return string_.capacity();
return (std::min)(string_.capacity(), max_size());
}
/// Get a list of buffers that represents the input sequence.
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the input
/// sequence.
/**
* @returns An object of type @c const_buffers_type that satisfies
* ConstBufferSequence requirements, representing the basic_string memory in
* input sequence.
* the input sequence.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c basic_string member function that resizes or erases the string.
*/
const_buffers_type data() const ASIO_NOEXCEPT
{
return const_buffers_type(asio::buffer(string_, size_));
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Get a list of buffers that represents the output sequence, with the given
/// size.
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing the basic_string memory.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that resizes or erases the string.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT
{
return mutable_buffers_type(asio::buffer(
asio::buffer(string_, max_size_) + pos, n));
}
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @note The returned object is invalidated by any @c dynamic_string_buffer
* or @c basic_string member function that resizes or erases the string.
*/
const_buffers_type data(std::size_t pos,
std::size_t n) const ASIO_NOEXCEPT
{
return const_buffers_type(asio::buffer(
asio::buffer(string_, max_size_) + pos, n));
}
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the output
/// sequence, with the given size.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* basic_string object as necessary.
@@ -1627,18 +1711,22 @@ public:
*/
mutable_buffers_type prepare(std::size_t n)
{
if (size () > max_size() || max_size() - size() < n)
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_string_buffer too long");
asio::detail::throw_exception(ex);
}
if (size_ == (std::numeric_limits<std::size_t>::max)())
size_ = string_.size(); // Enable v1 behaviour.
string_.resize(size_ + n);
return asio::buffer(asio::buffer(string_) + size_, n);
}
/// Move bytes from the output sequence to the input sequence.
/// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
/// sequence.
/**
* @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output
@@ -1655,24 +1743,69 @@ public:
size_ += (std::min)(n, string_.size() - size_);
string_.resize(size_);
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
/// bytes.
/**
* Removes @c n characters from the beginning of the input sequence.
* Resizes the string to accommodate an additional @c n bytes at the end.
*
* @note If @c n is greater than the size of the input sequence, the entire
* input sequence is consumed and no error is issued.
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*/
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_string_buffer too long");
asio::detail::throw_exception(ex);
}
string_.resize(size() + n);
}
/// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
/// of bytes.
/**
* Erases @c n bytes from the end of the string by resizing the basic_string
* object. If @c n is greater than the current size of the string, the string
* is emptied.
*/
void shrink(std::size_t n)
{
string_.resize(n > size() ? 0 : size() - n);
}
/// @b DynamicBuffer_v1: Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Consume the specified number of bytes from the
/// beginning of the underlying memory.
/**
* @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
* input sequence. @note If @c n is greater than the size of the input
* sequence, the entire input sequence is consumed and no error is issued.
*
* @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the string.
* If @c n is greater than the current size of the string, the string is
* emptied.
*/
void consume(std::size_t n)
{
std::size_t consume_length = (std::min)(n, size_);
string_.erase(0, consume_length);
size_ -= consume_length;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
{
std::size_t consume_length = (std::min)(n, size_);
string_.erase(0, consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
string_.erase(0, n);
}
private:
std::basic_string<Elem, Traits, Allocator>& string_;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@@ -1684,19 +1817,20 @@ template <typename Elem, typename Allocator>
class dynamic_vector_buffer
{
public:
/// The type used to represent the input sequence as a list of buffers.
/// The type used to represent a sequence of constant buffers that refers to
/// the underlying memory.
typedef ASIO_CONST_BUFFER const_buffers_type;
/// The type used to represent the output sequence as a list of buffers.
/// The type used to represent a sequence of mutable buffers that refers to
/// the underlying memory.
typedef ASIO_MUTABLE_BUFFER mutable_buffers_type;
/// Construct a dynamic buffer from a string.
/// Construct a dynamic buffer from a vector.
/**
* @param v The vector to be used as backing storage for the dynamic buffer.
* Any existing data in the vector is treated as the dynamic buffer's input
* sequence. The object stores a reference to the vector and the user is
* responsible for ensuring that the vector object remains valid until the
* dynamic_vector_buffer object is destroyed.
* The object stores a reference to the vector and the user is responsible
* for ensuring that the vector object remains valid while the
* dynamic_vector_buffer object, and copies of the object, are in use.
*
* @param maximum_size Specifies a maximum size for the buffer, in bytes.
*/
@@ -1704,77 +1838,149 @@ public:
std::size_t maximum_size =
(std::numeric_limits<std::size_t>::max)()) ASIO_NOEXCEPT
: vector_(v),
size_(vector_.size()),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_((std::numeric_limits<std::size_t>::max)()),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(maximum_size)
{
}
/// @b DynamicBuffer_v2: Copy construct a dynamic buffer.
dynamic_vector_buffer(const dynamic_vector_buffer& other) ASIO_NOEXCEPT
: vector_(other.vector_),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move construct a dynamic buffer.
dynamic_vector_buffer(dynamic_vector_buffer&& other) ASIO_NOEXCEPT
: vector_(other.vector_),
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
size_(other.size_),
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
max_size_(other.max_size_)
{
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Get the size of the input sequence.
/// @b DynamicBuffer_v1: Get the size of the input sequence.
/// @b DynamicBuffer_v2: Get the current size of the underlying memory.
/**
* @returns @b DynamicBuffer_v1 The current size of the input sequence.
* @b DynamicBuffer_v2: The current size of the underlying vector if less than
* max_size(). Otherwise returns max_size().
*/
std::size_t size() const ASIO_NOEXCEPT
{
return size_;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
return size_;
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
return (std::min)(vector_.size(), max_size());
}
/// Get the maximum size of the dynamic buffer.
/**
* @returns The allowed maximum of the sum of the sizes of the input sequence
* and output sequence.
* @returns @b DynamicBuffer_v1: The allowed maximum of the sum of the sizes
* of the input sequence and output sequence. @b DynamicBuffer_v2: The allowed
* maximum size of the underlying memory.
*/
std::size_t max_size() const ASIO_NOEXCEPT
{
return max_size_;
}
/// Get the current capacity of the dynamic buffer.
/// Get the maximum size that the buffer may grow to without triggering
/// reallocation.
/**
* @returns The current total capacity of the buffer, i.e. for both the input
* sequence and output sequence.
* @returns @b DynamicBuffer_v1: The current total capacity of the buffer,
* i.e. for both the input sequence and output sequence. @b DynamicBuffer_v2:
* The current capacity of the underlying vector if less than max_size().
* Otherwise returns max_size().
*/
std::size_t capacity() const ASIO_NOEXCEPT
{
return vector_.capacity();
return (std::min)(vector_.capacity(), max_size());
}
/// Get a list of buffers that represents the input sequence.
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the input
/// sequence.
/**
* @returns An object of type @c const_buffers_type that satisfies
* ConstBufferSequence requirements, representing the basic_string memory in
* ConstBufferSequence requirements, representing the vector memory in the
* input sequence.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c vector member function that modifies the input sequence or output
* sequence.
*/
const_buffers_type data() const ASIO_NOEXCEPT
{
return const_buffers_type(asio::buffer(vector_, size_));
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Get a list of buffers that represents the output sequence, with the given
/// size.
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* basic_string object as necessary.
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing basic_string memory
* at the start of the output sequence of size @c n.
* MutableBufferSequence requirements, representing the vector memory.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c vector member function that resizes or erases the vector.
*/
mutable_buffers_type data(std::size_t pos, std::size_t n) ASIO_NOEXCEPT
{
return mutable_buffers_type(asio::buffer(
asio::buffer(vector_, max_size_) + pos, n));
}
/// @b DynamicBuffer_v2: Get a sequence of buffers that represents the
/// underlying memory.
/**
* @param pos Position of the first byte to represent in the buffer sequence
*
* @param n The number of bytes to return in the buffer sequence. If the
* underlying memory is shorter, the buffer sequence represents as many bytes
* as are available.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c vector member function that resizes or erases the vector.
*/
const_buffers_type data(std::size_t pos,
std::size_t n) const ASIO_NOEXCEPT
{
return const_buffers_type(asio::buffer(
asio::buffer(vector_, max_size_) + pos, n));
}
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// @b DynamicBuffer_v1: Get a list of buffers that represents the output
/// sequence, with the given size.
/**
* Ensures that the output sequence can accommodate @c n bytes, resizing the
* vector object as necessary.
*
* @returns An object of type @c mutable_buffers_type that satisfies
* MutableBufferSequence requirements, representing vector memory at the
* start of the output sequence of size @c n.
*
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*
* @note The returned object is invalidated by any @c dynamic_vector_buffer
* or @c basic_string member function that modifies the input sequence or
* output sequence.
* or @c vector member function that modifies the input sequence or output
* sequence.
*/
mutable_buffers_type prepare(std::size_t n)
{
@@ -1784,12 +1990,16 @@ public:
asio::detail::throw_exception(ex);
}
if (size_ == (std::numeric_limits<std::size_t>::max)())
size_ = vector_.size(); // Enable v1 behaviour.
vector_.resize(size_ + n);
return asio::buffer(asio::buffer(vector_) + size_, n);
}
/// Move bytes from the output sequence to the input sequence.
/// @b DynamicBuffer_v1: Move bytes from the output sequence to the input
/// sequence.
/**
* @param n The number of bytes to append from the start of the output
* sequence to the end of the input sequence. The remainder of the output
@@ -1806,24 +2016,69 @@ public:
size_ += (std::min)(n, vector_.size() - size_);
vector_.resize(size_);
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Grow the underlying memory by the specified number of
/// bytes.
/**
* Removes @c n characters from the beginning of the input sequence.
* Resizes the vector to accommodate an additional @c n bytes at the end.
*
* @note If @c n is greater than the size of the input sequence, the entire
* input sequence is consumed and no error is issued.
* @throws std::length_error If <tt>size() + n > max_size()</tt>.
*/
void grow(std::size_t n)
{
if (size() > max_size() || max_size() - size() < n)
{
std::length_error ex("dynamic_vector_buffer too long");
asio::detail::throw_exception(ex);
}
vector_.resize(size() + n);
}
/// @b DynamicBuffer_v2: Shrink the underlying memory by the specified number
/// of bytes.
/**
* Erases @c n bytes from the end of the vector by resizing the vector
* object. If @c n is greater than the current size of the vector, the vector
* is emptied.
*/
void shrink(std::size_t n)
{
vector_.resize(n > size() ? 0 : size() - n);
}
/// @b DynamicBuffer_v1: Remove characters from the input sequence.
/// @b DynamicBuffer_v2: Consume the specified number of bytes from the
/// beginning of the underlying memory.
/**
* @b DynamicBuffer_v1: Removes @c n characters from the beginning of the
* input sequence. @note If @c n is greater than the size of the input
* sequence, the entire input sequence is consumed and no error is issued.
*
* @b DynamicBuffer_v2: Erases @c n bytes from the beginning of the vector.
* If @c n is greater than the current size of the vector, the vector is
* emptied.
*/
void consume(std::size_t n)
{
std::size_t consume_length = (std::min)(n, size_);
vector_.erase(vector_.begin(), vector_.begin() + consume_length);
size_ -= consume_length;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
if (size_ != (std::numeric_limits<std::size_t>::max)())
{
std::size_t consume_length = (std::min)(n, size_);
vector_.erase(vector_.begin(), vector_.begin() + consume_length);
size_ -= consume_length;
return;
}
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
vector_.erase(vector_.begin(), vector_.begin() + (std::min)(size(), n));
}
private:
std::vector<Elem, Allocator>& vector_;
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
std::size_t size_;
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
const std::size_t max_size_;
};
@@ -2157,6 +2412,83 @@ inline std::size_t buffer_copy(const MutableBufferSequence& target,
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/detail/is_buffer_sequence.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
/// Trait to determine whether a type satisfies the MutableBufferSequence
/// requirements.
template <typename T>
struct is_mutable_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_buffer_sequence<T, mutable_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the ConstBufferSequence
/// requirements.
template <typename T>
struct is_const_buffer_sequence
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_buffer_sequence<T, const_buffer>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
#if !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Trait to determine whether a type satisfies the DynamicBuffer_v1
/// requirements.
template <typename T>
struct is_dynamic_buffer_v1
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_dynamic_buffer_v1<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
#endif // !defined(ASIO_NO_DYNAMIC_BUFFER_V1)
/// Trait to determine whether a type satisfies the DynamicBuffer_v2
/// requirements.
template <typename T>
struct is_dynamic_buffer_v2
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#else // defined(GENERATING_DOCUMENTATION)
: asio::detail::is_dynamic_buffer_v2<T>
#endif // defined(GENERATING_DOCUMENTATION)
{
};
/// Trait to determine whether a type satisfies the DynamicBuffer requirements.
/**
* If @c ASIO_NO_DYNAMIC_BUFFER_V1 is not defined, determines whether the
* type satisfies the DynamicBuffer_v1 requirements. Otherwise, if @c
* ASIO_NO_DYNAMIC_BUFFER_V1 is defined, determines whether the type
* satisfies the DynamicBuffer_v1 requirements.
*/
template <typename T>
struct is_dynamic_buffer
#if defined(GENERATING_DOCUMENTATION)
: integral_constant<bool, automatically_determined>
#elif defined(ASIO_NO_DYNAMIC_BUFFER_V1)
: asio::is_dynamic_buffer_v2<T>
#else // defined(ASIO_NO_DYNAMIC_BUFFER_V1)
: asio::is_dynamic_buffer_v1<T>
#endif // defined(ASIO_NO_DYNAMIC_BUFFER_V1)
{
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_BUFFER_HPP

View File

@@ -2,7 +2,7 @@
// buffered_read_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -26,7 +26,6 @@
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#include "asio/io_context.hpp"
#include "asio/detail/push_options.hpp"
@@ -105,22 +104,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@@ -2,7 +2,7 @@
// buffered_read_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// buffered_stream.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -23,7 +23,6 @@
#include "asio/buffered_stream_fwd.hpp"
#include "asio/detail/noncopyable.hpp"
#include "asio/error.hpp"
#include "asio/io_context.hpp"
#include "asio/detail/push_options.hpp"
@@ -96,22 +95,6 @@ public:
return stream_impl_.lowest_layer().get_executor();
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_context()
{
return stream_impl_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_service()
{
return stream_impl_.get_io_service();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@@ -2,7 +2,7 @@
// buffered_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// buffered_write_stream.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -25,7 +25,6 @@
#include "asio/detail/noncopyable.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#include "asio/io_context.hpp"
#include "asio/write.hpp"
#include "asio/detail/push_options.hpp"
@@ -105,22 +104,6 @@ public:
return next_layer_.lowest_layer().get_executor();
}
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_context()
{
return next_layer_.get_io_context();
}
/// (Deprecated: Use get_executor().) Get the io_context associated with the
/// object.
asio::io_context& get_io_service()
{
return next_layer_.get_io_service();
}
#endif // !defined(ASIO_NO_DEPRECATED)
/// Close the stream.
void close()
{

View File

@@ -2,7 +2,7 @@
// buffered_write_stream_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// buffers_iterator.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -0,0 +1,88 @@
//
// co_spawn.hpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_CO_SPAWN_HPP
#define ASIO_CO_SPAWN_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 "asio/awaitable.hpp"
#include "asio/execution_context.hpp"
#include "asio/is_executor.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
template <typename T>
struct awaitable_signature;
template <typename T, typename Executor>
struct awaitable_signature<awaitable<T, Executor>>
{
typedef void type(std::exception_ptr, T);
};
template <typename Executor>
struct awaitable_signature<awaitable<void, Executor>>
{
typedef void type(std::exception_ptr);
};
} // namespace detail
/// Spawn a new thread of execution.
/**
* The entry point function object @c f must have the signature:
*
* @code awaitable<void, E> f(); @endcode
*
* where @c E is convertible from @c Executor.
*/
template <typename Executor, typename F, typename CompletionToken>
ASIO_INITFN_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(const Executor& ex, F&& f, CompletionToken&& token,
typename enable_if<
is_executor<Executor>::value
>::type* = 0);
/// Spawn a new thread of execution.
/**
* The entry point function object @c f must have the signature:
*
* @code awaitable<void, E> f(); @endcode
*
* where @c E is convertible from @c ExecutionContext::executor_type.
*/
template <typename ExecutionContext, typename F, typename CompletionToken>
ASIO_INITFN_RESULT_TYPE(CompletionToken,
typename detail::awaitable_signature<typename result_of<F()>::type>::type)
co_spawn(ExecutionContext& ctx, F&& f, CompletionToken&& token,
typename enable_if<
is_convertible<ExecutionContext&, execution_context&>::value
>::type* = 0);
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/impl/co_spawn.hpp"
#endif // defined(ASIO_HAS_CO_AWAIT) || defined(GENERATING_DOCUMENTATION)
#endif // ASIO_CO_SPAWN_HPP

View File

@@ -2,7 +2,7 @@
// completion_condition.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -0,0 +1,136 @@
//
// compose.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_COMPOSE_HPP
#define ASIO_COMPOSE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/async_result.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
#if defined(ASIO_HAS_VARIADIC_TEMPLATES) \
|| defined(GENERATING_DOCUMENTATION)
/// Launch an asynchronous operation with a stateful implementation.
/**
* The async_compose function simplifies the implementation of composed
* asynchronous operations automatically wrapping a stateful function object
* with a conforming intermediate completion handler.
*
* @param implementation A function object that contains the implementation of
* the composed asynchronous operation. The first argument to the function
* object is a non-const reference to the enclosing intermediate completion
* handler. The remaining arguments are any arguments that originate from the
* completion handlers of any asynchronous operations performed by the
* implementation.
* @param token The completion token.
*
* @param io_objects_or_executors Zero or more I/O objects or I/O executors for
* which outstanding work must be maintained.
*
* @par Example:
*
* @code struct async_echo_implementation
* {
* tcp::socket& socket_;
* asio::mutable_buffer buffer_;
* enum { starting, reading, writing } state_;
*
* template <typename Self>
* void operator()(Self& self,
* asio::error_code error = {},
* std::size_t n = 0)
* {
* switch (state_)
* {
* case starting:
* state_ = reading;
* socket_.async_read_some(
* buffer_, std::move(self));
* break;
* case reading:
* if (error)
* {
* self.complete(error, 0);
* }
* else
* {
* state_ = writing;
* asio::async_write(socket_, buffer_,
* asio::transfer_exactly(n),
* std::move(self));
* }
* break;
* case writing:
* self.complete(error, n);
* break;
* }
* }
* };
*
* template <typename CompletionToken>
* auto async_echo(tcp::socket& socket,
* asio::mutable_buffer buffer,
* CompletionToken&& token) ->
* typename asio::async_result<
* typename std::decay<CompletionToken>::type,
* void(asio::error_code, std::size_t)>::return_type
* {
* return asio::async_compose<CompletionToken,
* void(asio::error_code, std::size_t)>(
* async_echo_implementation{socket, buffer,
* async_echo_implementation::starting},
* token, socket);
* } @endcode
*/
template <typename CompletionToken, typename Signature,
typename Implementation, typename... IoObjectsOrExecutors>
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_compose(ASIO_MOVE_ARG(Implementation) implementation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token,
ASIO_MOVE_ARG(IoObjectsOrExecutors)... io_objects_or_executors);
#else // defined(ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
template <typename CompletionToken, typename Signature, typename Implementation>
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature)
async_compose(ASIO_MOVE_ARG(Implementation) implementation,
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token);
#define ASIO_PRIVATE_ASYNC_COMPOSE_DEF(n) \
template <typename CompletionToken, typename Signature, \
typename Implementation, ASIO_VARIADIC_TPARAMS(n)> \
ASIO_INITFN_RESULT_TYPE(CompletionToken, Signature) \
async_compose(ASIO_MOVE_ARG(Implementation) implementation, \
ASIO_NONDEDUCED_MOVE_ARG(CompletionToken) token, \
ASIO_VARIADIC_MOVE_PARAMS(n));
/**/
ASIO_VARIADIC_GENERATE(ASIO_PRIVATE_ASYNC_COMPOSE_DEF)
#undef ASIO_PRIVATE_ASYNC_COMPOSE_DEF
#endif // defined(ASIO_HAS_VARIADIC_TEMPLATES)
// || defined(GENERATING_DOCUMENTATION)
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/impl/compose.hpp"
#endif // ASIO_COMPOSE_HPP

View File

@@ -2,7 +2,7 @@
// connect.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -58,7 +58,8 @@ struct is_endpoint_sequence
/**
* @defgroup connect asio::connect
*
* @brief Establishes a socket connection by trying each endpoint in a sequence.
* @brief The @c connect function is a composed operation that establishes a
* socket connection by trying each endpoint in a sequence.
*/
/*@{*/
@@ -81,14 +82,13 @@ struct is_endpoint_sequence
* Otherwise, contains the error from the last connection attempt.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::connect(s, r.resolve(q)); @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename EndpointSequence>
typename Protocol::endpoint connect(
basic_socket<Protocol ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@@ -113,9 +113,9 @@ typename Protocol::endpoint connect(
* default-constructed endpoint.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::error_code ec;
* asio::connect(s, r.resolve(q), ec);
* if (ec)
@@ -123,16 +123,15 @@ typename Protocol::endpoint connect(
* // An error occurred.
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename EndpointSequence>
typename Protocol::endpoint connect(
basic_socket<Protocol ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename EndpointSequence>
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, asio::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@@ -155,12 +154,12 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@@ -183,8 +182,8 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, asio::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -210,14 +209,14 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Otherwise, contains the error from the last connection attempt.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::connect(s, e.begin(), e.end()); @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -242,10 +241,10 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* endpoint. Otherwise, the end iterator.
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::error_code ec;
* asio::connect(s, e.begin(), e.end(), ec);
* if (ec)
@@ -253,8 +252,8 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* // An error occurred.
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
template <typename Protocol, typename Executor, typename Iterator>
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, asio::error_code& ec);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -301,17 +300,16 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* tcp::endpoint e = asio::connect(s,
* r.resolve(q), my_connect_condition());
* std::cout << "Connected to: " << e << std::endl; @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
typename Protocol::endpoint connect(
basic_socket<Protocol ASIO_SVC_TARG>& s,
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
@@ -361,9 +359,9 @@ typename Protocol::endpoint connect(
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::error_code ec;
* tcp::endpoint e = asio::connect(s,
* r.resolve(q), my_connect_condition(), ec);
@@ -376,18 +374,17 @@ typename Protocol::endpoint connect(
* std::cout << "Connected to: " << e << std::endl;
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename EndpointSequence, typename ConnectCondition>
typename Protocol::endpoint connect(
basic_socket<Protocol ASIO_SVC_TARG>& s,
typename Protocol::endpoint connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
asio::error_code& ec,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@@ -421,14 +418,14 @@ typename Protocol::endpoint connect(
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, ConnectCondition connect_condition,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
/// (Deprecated.) Establishes a socket connection by trying each endpoint in a
/// sequence.
/// (Deprecated: Use range overload.) Establishes a socket connection by trying
/// each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c connect member
@@ -462,9 +459,9 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition, asio::error_code& ec,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -515,17 +512,17 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* tcp::resolver::results_type::iterator i = asio::connect(
* s, e.begin(), e.end(), my_connect_condition());
* std::cout << "Connected to: " << i->endpoint() << std::endl; @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
Iterator connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition);
/// Establishes a socket connection by trying each endpoint in a sequence.
@@ -575,10 +572,10 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::resolver::results_type e = r.resolve(q);
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::error_code ec;
* tcp::resolver::results_type::iterator i = asio::connect(
* s, e.begin(), e.end(), my_connect_condition());
@@ -591,9 +588,9 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* std::cout << "Connected to: " << i->endpoint() << std::endl;
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename ConnectCondition>
Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
Iterator connect(basic_socket<Protocol, Executor>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
asio::error_code& ec);
@@ -602,8 +599,8 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
/**
* @defgroup async_connect asio::async_connect
*
* @brief Asynchronously establishes a socket connection by trying each
* endpoint in a sequence.
* @brief The @c async_connect function is a composed asynchronous operation
* that establishes a socket connection by trying each endpoint in a sequence.
*/
/*@{*/
@@ -634,14 +631,14 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* const typename Protocol::endpoint& endpoint
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
*
* // ...
*
@@ -668,19 +665,19 @@ Iterator connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* // ...
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename EndpointSequence, typename RangeConnectHandler>
ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints,
ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each
/// endpoint in a sequence.
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// connection by trying each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect
@@ -706,20 +703,20 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (asio::error_code, Iterator))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
Iterator begin, ASIO_MOVE_ARG(IteratorConnectHandler) handler,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
#endif // !defined(ASIO_NO_DEPRECATED)
@@ -752,13 +749,13 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* @code std::vector<tcp::endpoint> endpoints = ...;
* tcp::socket s(io_context);
* tcp::socket s(my_context);
* asio::async_connect(s,
* endpoints.begin(), endpoints.end(),
* connect_handler);
@@ -772,12 +769,11 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* // ...
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM,
template <typename Protocol, typename Executor,
typename Iterator, typename IteratorConnectHandler>
ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (asio::error_code, Iterator))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
Iterator begin, Iterator end,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin, Iterator end,
ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/// Asynchronously establishes a socket connection by trying each endpoint in a
@@ -818,9 +814,9 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* The following connect condition function object can be used to output
@@ -837,9 +833,9 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
*
* // ...
*
@@ -875,19 +871,19 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* }
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename EndpointSequence,
template <typename Protocol, typename Executor, typename EndpointSequence,
typename ConnectCondition, typename RangeConnectHandler>
ASIO_INITFN_RESULT_TYPE(RangeConnectHandler,
void (asio::error_code, typename Protocol::endpoint))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
async_connect(basic_socket<Protocol, Executor>& s,
const EndpointSequence& endpoints, ConnectCondition connect_condition,
ASIO_MOVE_ARG(RangeConnectHandler) handler,
typename enable_if<is_endpoint_sequence<
EndpointSequence>::value>::type* = 0);
#if !defined(ASIO_NO_DEPRECATED)
/// (Deprecated.) Asynchronously establishes a socket connection by trying each
/// endpoint in a sequence.
/// (Deprecated: Use range overload.) Asynchronously establishes a socket
/// connection by trying each endpoint in a sequence.
/**
* This function attempts to connect a socket to one of a sequence of
* endpoints. It does this by repeated calls to the socket's @c async_connect
@@ -924,19 +920,19 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @note This overload assumes that a default constructed object of type @c
* Iterator represents the end of the sequence. This is a valid assumption for
* iterator types such as @c asio::ip::tcp::resolver::iterator.
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator,
template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (asio::error_code, Iterator))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
ConnectCondition connect_condition,
ASIO_MOVE_ARG(IteratorConnectHandler) handler,
typename enable_if<!is_endpoint_sequence<Iterator>::value>::type* = 0);
@@ -982,9 +978,9 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* Iterator iterator
* ); @endcode
* Regardless of whether the asynchronous operation completes immediately or
* not, the handler will not be invoked from within this function. Invocation
* of the handler will be performed in a manner equivalent to using
* asio::io_context::post().
* not, the handler will not be invoked from within this function. On
* immediate completion, invocation of the handler will be performed in a
* manner equivalent to using asio::post().
*
* @par Example
* The following connect condition function object can be used to output
@@ -1001,9 +997,9 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* }
* }; @endcode
* It would be used with the asio::connect function as follows:
* @code tcp::resolver r(io_context);
* @code tcp::resolver r(my_context);
* tcp::resolver::query q("host", "service");
* tcp::socket s(io_context);
* tcp::socket s(my_context);
*
* // ...
*
@@ -1040,12 +1036,12 @@ async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s, Iterator begin,
* }
* } @endcode
*/
template <typename Protocol ASIO_SVC_TPARAM, typename Iterator,
template <typename Protocol, typename Executor, typename Iterator,
typename ConnectCondition, typename IteratorConnectHandler>
ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler,
void (asio::error_code, Iterator))
async_connect(basic_socket<Protocol ASIO_SVC_TARG>& s,
Iterator begin, Iterator end, ConnectCondition connect_condition,
async_connect(basic_socket<Protocol, Executor>& s, Iterator begin,
Iterator end, ConnectCondition connect_condition,
ASIO_MOVE_ARG(IteratorConnectHandler) handler);
/*@}*/

View File

@@ -2,7 +2,7 @@
// coroutine.hpp
// ~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -205,7 +205,7 @@ class coroutine_ref;
* {
* do
* {
* socket_.reset(new tcp::socket(io_context_));
* socket_.reset(new tcp::socket(my_context_));
* yield acceptor->async_accept(*socket_, *this);
* fork server(*this)();
* } while (is_parent());
@@ -227,7 +227,7 @@ class coroutine_ref;
* Note that @c fork doesn't do the actual forking by itself. It is the
* application's responsibility to create a clone of the coroutine and call it.
* The clone can be called immediately, as above, or scheduled for delayed
* execution using something like io_context::post().
* execution using something like asio::post().
*
* @par Alternate macro names
*

View File

@@ -1,466 +0,0 @@
//
// datagram_socket_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DATAGRAM_SOCKET_SERVICE_HPP
#define ASIO_DATAGRAM_SOCKET_SERVICE_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_ENABLE_OLD_SERVICES)
#include <cstddef>
#include "asio/async_result.hpp"
#include "asio/detail/type_traits.hpp"
#include "asio/error.hpp"
#include "asio/io_context.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
#include "asio/detail/push_options.hpp"
namespace asio {
/// Default service implementation for a datagram socket.
template <typename Protocol>
class datagram_socket_service
#if defined(GENERATING_DOCUMENTATION)
: public asio::io_context::service
#else
: public asio::detail::service_base<datagram_socket_service<Protocol> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static asio::io_context::id id;
#endif
/// The protocol type.
typedef Protocol protocol_type;
/// The endpoint type.
typedef typename Protocol::endpoint endpoint_type;
private:
// The type of the platform-specific implementation.
#if defined(ASIO_WINDOWS_RUNTIME)
typedef detail::null_socket_service<Protocol> service_impl_type;
#elif defined(ASIO_HAS_IOCP)
typedef detail::win_iocp_socket_service<Protocol> service_impl_type;
#else
typedef detail::reactive_socket_service<Protocol> service_impl_type;
#endif
public:
/// The type of a datagram socket.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined implementation_type;
#else
typedef typename service_impl_type::implementation_type implementation_type;
#endif
/// The native socket type.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined native_handle_type;
#else
typedef typename service_impl_type::native_handle_type native_handle_type;
#endif
/// Construct a new datagram socket service for the specified io_context.
explicit datagram_socket_service(asio::io_context& io_context)
: asio::detail::service_base<
datagram_socket_service<Protocol> >(io_context),
service_impl_(io_context)
{
}
/// Construct a new datagram socket implementation.
void construct(implementation_type& impl)
{
service_impl_.construct(impl);
}
#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Move-construct a new datagram socket implementation.
void move_construct(implementation_type& impl,
implementation_type& other_impl)
{
service_impl_.move_construct(impl, other_impl);
}
/// Move-assign from another datagram socket implementation.
void move_assign(implementation_type& impl,
datagram_socket_service& other_service,
implementation_type& other_impl)
{
service_impl_.move_assign(impl, other_service.service_impl_, other_impl);
}
// All socket services have access to each other's implementations.
template <typename Protocol1> friend class datagram_socket_service;
/// Move-construct a new datagram socket implementation from another protocol
/// type.
template <typename Protocol1>
void converting_move_construct(implementation_type& impl,
datagram_socket_service<Protocol1>& other_service,
typename datagram_socket_service<
Protocol1>::implementation_type& other_impl,
typename enable_if<is_convertible<
Protocol1, Protocol>::value>::type* = 0)
{
service_impl_.template converting_move_construct<Protocol1>(
impl, other_service.service_impl_, other_impl);
}
#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
/// Destroy a datagram socket implementation.
void destroy(implementation_type& impl)
{
service_impl_.destroy(impl);
}
// Open a new datagram socket implementation.
ASIO_SYNC_OP_VOID open(implementation_type& impl,
const protocol_type& protocol, asio::error_code& ec)
{
if (protocol.type() == ASIO_OS_DEF(SOCK_DGRAM))
service_impl_.open(impl, protocol, ec);
else
ec = asio::error::invalid_argument;
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Assign an existing native socket to a datagram socket.
ASIO_SYNC_OP_VOID assign(implementation_type& impl,
const protocol_type& protocol, const native_handle_type& native_socket,
asio::error_code& ec)
{
service_impl_.assign(impl, protocol, native_socket, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is open.
bool is_open(const implementation_type& impl) const
{
return service_impl_.is_open(impl);
}
/// Close a datagram socket implementation.
ASIO_SYNC_OP_VOID close(implementation_type& impl,
asio::error_code& ec)
{
service_impl_.close(impl, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Release ownership of the underlying socket.
native_handle_type release(implementation_type& impl,
asio::error_code& ec)
{
return service_impl_.release(impl, ec);
}
/// Get the native socket implementation.
native_handle_type native_handle(implementation_type& impl)
{
return service_impl_.native_handle(impl);
}
/// Cancel all asynchronous operations associated with the socket.
ASIO_SYNC_OP_VOID cancel(implementation_type& impl,
asio::error_code& ec)
{
service_impl_.cancel(impl, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Determine whether the socket is at the out-of-band data mark.
bool at_mark(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.at_mark(impl, ec);
}
/// Determine the number of bytes available for reading.
std::size_t available(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.available(impl, ec);
}
// Bind the datagram socket to the specified local endpoint.
ASIO_SYNC_OP_VOID bind(implementation_type& impl,
const endpoint_type& endpoint, asio::error_code& ec)
{
service_impl_.bind(impl, endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Connect the datagram socket to the specified endpoint.
ASIO_SYNC_OP_VOID connect(implementation_type& impl,
const endpoint_type& peer_endpoint, asio::error_code& ec)
{
service_impl_.connect(impl, peer_endpoint, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Start an asynchronous connect.
template <typename ConnectHandler>
ASIO_INITFN_RESULT_TYPE(ConnectHandler,
void (asio::error_code))
async_connect(implementation_type& impl,
const endpoint_type& peer_endpoint,
ASIO_MOVE_ARG(ConnectHandler) handler)
{
async_completion<ConnectHandler,
void (asio::error_code)> init(handler);
service_impl_.async_connect(impl, peer_endpoint, init.completion_handler);
return init.result.get();
}
/// Set a socket option.
template <typename SettableSocketOption>
ASIO_SYNC_OP_VOID set_option(implementation_type& impl,
const SettableSocketOption& option, asio::error_code& ec)
{
service_impl_.set_option(impl, option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get a socket option.
template <typename GettableSocketOption>
ASIO_SYNC_OP_VOID get_option(const implementation_type& impl,
GettableSocketOption& option, asio::error_code& ec) const
{
service_impl_.get_option(impl, option, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Perform an IO control command on the socket.
template <typename IoControlCommand>
ASIO_SYNC_OP_VOID io_control(implementation_type& impl,
IoControlCommand& command, asio::error_code& ec)
{
service_impl_.io_control(impl, command, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the socket.
bool non_blocking(const implementation_type& impl) const
{
return service_impl_.non_blocking(impl);
}
/// Sets the non-blocking mode of the socket.
ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl,
bool mode, asio::error_code& ec)
{
service_impl_.non_blocking(impl, mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Gets the non-blocking mode of the native socket implementation.
bool native_non_blocking(const implementation_type& impl) const
{
return service_impl_.native_non_blocking(impl);
}
/// Sets the non-blocking mode of the native socket implementation.
ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl,
bool mode, asio::error_code& ec)
{
service_impl_.native_non_blocking(impl, mode, ec);
ASIO_SYNC_OP_VOID_RETURN(ec);
}
/// Get the local endpoint.
endpoint_type local_endpoint(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.local_endpoint(impl, ec);
}
/// Get the remote endpoint.
endpoint_type remote_endpoint(const implementation_type& impl,
asio::error_code& ec) const
{
return service_impl_.remote_endpoint(impl, ec);
}
/// Disable sends or receives on the socket.
ASIO_SYNC_OP_VOID shutdown(implementation_type& impl,
socket_base::shutdown_type what, asio::error_code& ec)
{
service_impl_.shutdown(impl, 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.
ASIO_SYNC_OP_VOID wait(implementation_type& impl,
socket_base::wait_type w, asio::error_code& ec)
{
service_impl_.wait(impl, 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.
template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (asio::error_code))
async_wait(implementation_type& impl, socket_base::wait_type w,
ASIO_MOVE_ARG(WaitHandler) handler)
{
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
service_impl_.async_wait(impl, w, init.completion_handler);
return init.result.get();
}
/// Send the given data to the peer.
template <typename ConstBufferSequence>
std::size_t send(implementation_type& impl,
const ConstBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
{
return service_impl_.send(impl, buffers, flags, ec);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (asio::error_code, std::size_t))
async_send(implementation_type& impl, const ConstBufferSequence& buffers,
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_send(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
/// Send a datagram to the specified endpoint.
template <typename ConstBufferSequence>
std::size_t send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags, asio::error_code& ec)
{
return service_impl_.send_to(impl, buffers, destination, flags, ec);
}
/// Start an asynchronous send.
template <typename ConstBufferSequence, typename WriteHandler>
ASIO_INITFN_RESULT_TYPE(WriteHandler,
void (asio::error_code, std::size_t))
async_send_to(implementation_type& impl,
const ConstBufferSequence& buffers, const endpoint_type& destination,
socket_base::message_flags flags,
ASIO_MOVE_ARG(WriteHandler) handler)
{
async_completion<WriteHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_send_to(impl, buffers,
destination, flags, init.completion_handler);
return init.result.get();
}
/// Receive some data from the peer.
template <typename MutableBufferSequence>
std::size_t receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags, asio::error_code& ec)
{
return service_impl_.receive(impl, buffers, flags, ec);
}
/// Start an asynchronous receive.
template <typename MutableBufferSequence, typename ReadHandler>
ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (asio::error_code, std::size_t))
async_receive(implementation_type& impl,
const MutableBufferSequence& buffers,
socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_receive(impl, buffers, flags, init.completion_handler);
return init.result.get();
}
/// Receive a datagram with the endpoint of the sender.
template <typename MutableBufferSequence>
std::size_t receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags, asio::error_code& ec)
{
return service_impl_.receive_from(impl, buffers, sender_endpoint, flags,
ec);
}
/// Start an asynchronous receive that will get the endpoint of the sender.
template <typename MutableBufferSequence, typename ReadHandler>
ASIO_INITFN_RESULT_TYPE(ReadHandler,
void (asio::error_code, std::size_t))
async_receive_from(implementation_type& impl,
const MutableBufferSequence& buffers, endpoint_type& sender_endpoint,
socket_base::message_flags flags,
ASIO_MOVE_ARG(ReadHandler) handler)
{
async_completion<ReadHandler,
void (asio::error_code, std::size_t)> init(handler);
service_impl_.async_receive_from(impl, buffers,
sender_endpoint, flags, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown()
{
service_impl_.shutdown();
}
// The platform-specific implementation.
service_impl_type service_impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#endif // ASIO_DATAGRAM_SOCKET_SERVICE_HPP

View File

@@ -2,7 +2,7 @@
// deadline_timer.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -1,173 +0,0 @@
//
// deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DEADLINE_TIMER_SERVICE_HPP
#define ASIO_DEADLINE_TIMER_SERVICE_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_ENABLE_OLD_SERVICES)
#if defined(ASIO_HAS_BOOST_DATE_TIME) \
|| defined(GENERATING_DOCUMENTATION)
#include <cstddef>
#include "asio/async_result.hpp"
#include "asio/detail/deadline_timer_service.hpp"
#include "asio/io_context.hpp"
#include "asio/time_traits.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
/// Default service implementation for a timer.
template <typename TimeType,
typename TimeTraits = asio::time_traits<TimeType> >
class deadline_timer_service
#if defined(GENERATING_DOCUMENTATION)
: public asio::io_context::service
#else
: public asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >
#endif
{
public:
#if defined(GENERATING_DOCUMENTATION)
/// The unique service identifier.
static asio::io_context::id id;
#endif
/// The time traits type.
typedef TimeTraits traits_type;
/// The time type.
typedef typename traits_type::time_type time_type;
/// The duration type.
typedef typename traits_type::duration_type duration_type;
private:
// The type of the platform-specific implementation.
typedef detail::deadline_timer_service<traits_type> service_impl_type;
public:
/// The implementation type of the deadline timer.
#if defined(GENERATING_DOCUMENTATION)
typedef implementation_defined implementation_type;
#else
typedef typename service_impl_type::implementation_type implementation_type;
#endif
/// Construct a new timer service for the specified io_context.
explicit deadline_timer_service(asio::io_context& io_context)
: asio::detail::service_base<
deadline_timer_service<TimeType, TimeTraits> >(io_context),
service_impl_(io_context)
{
}
/// Construct a new timer implementation.
void construct(implementation_type& impl)
{
service_impl_.construct(impl);
}
/// Destroy a timer implementation.
void destroy(implementation_type& impl)
{
service_impl_.destroy(impl);
}
/// Cancel any asynchronous wait operations associated with the timer.
std::size_t cancel(implementation_type& impl, asio::error_code& ec)
{
return service_impl_.cancel(impl, ec);
}
/// Cancels one asynchronous wait operation associated with the timer.
std::size_t cancel_one(implementation_type& impl,
asio::error_code& ec)
{
return service_impl_.cancel_one(impl, ec);
}
/// Get the expiry time for the timer as an absolute time.
time_type expires_at(const implementation_type& impl) const
{
return service_impl_.expiry(impl);
}
/// Set the expiry time for the timer as an absolute time.
std::size_t expires_at(implementation_type& impl,
const time_type& expiry_time, asio::error_code& ec)
{
return service_impl_.expires_at(impl, expiry_time, ec);
}
/// Get the expiry time for the timer relative to now.
duration_type expires_from_now(const implementation_type& impl) const
{
return TimeTraits::subtract(service_impl_.expiry(impl), TimeTraits::now());
}
/// Set the expiry time for the timer relative to now.
std::size_t expires_from_now(implementation_type& impl,
const duration_type& expiry_time, asio::error_code& ec)
{
return service_impl_.expires_after(impl, expiry_time, ec);
}
// Perform a blocking wait on the timer.
void wait(implementation_type& impl, asio::error_code& ec)
{
service_impl_.wait(impl, ec);
}
// Start an asynchronous wait on the timer.
template <typename WaitHandler>
ASIO_INITFN_RESULT_TYPE(WaitHandler,
void (asio::error_code))
async_wait(implementation_type& impl,
ASIO_MOVE_ARG(WaitHandler) handler)
{
async_completion<WaitHandler,
void (asio::error_code)> init(handler);
service_impl_.async_wait(impl, init.completion_handler);
return init.result.get();
}
private:
// Destroy all user-defined handler objects owned by the service.
void shutdown()
{
service_impl_.shutdown();
}
// The platform-specific implementation.
service_impl_type service_impl_;
};
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // defined(ASIO_HAS_BOOST_DATE_TIME)
// || defined(GENERATING_DOCUMENTATION)
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
#endif // ASIO_DEADLINE_TIMER_SERVICE_HPP

View File

@@ -2,7 +2,7 @@
// defer.hpp
// ~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -31,6 +31,11 @@ namespace asio {
* executor. The function object is queued for execution, and is never called
* from the current thread prior to returning from <tt>defer()</tt>.
*
* The use of @c defer(), rather than @ref post(), indicates the caller's
* preference that the executor defer the queueing of the function object. This
* may allow the executor to optimise queueing for cases when the function
* object represents a continuation of the current call context.
*
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized
@@ -59,6 +64,11 @@ ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) defer(
* The function object is queued for execution, and is never called from the
* current thread prior to returning from <tt>defer()</tt>.
*
* The use of @c defer(), rather than @ref post(), indicates the caller's
* preference that the executor defer the queueing of the function object. This
* may allow the executor to optimise queueing for cases when the function
* object represents a continuation of the current call context.
*
* This function has the following effects:
*
* @li Constructs a function object handler of type @c Handler, initialized

View File

@@ -0,0 +1,62 @@
//
// detached.hpp
// ~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETACHED_HPP
#define ASIO_DETACHED_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include <memory>
#include "asio/detail/push_options.hpp"
namespace asio {
/// Class used to specify that an asynchronous operation is detached.
/**
* The detached_t class is used to indicate that an asynchronous operation is
* detached. That is, there is no completion handler waiting for the
* operation's result. A detached_t object may be passed as a handler to an
* asynchronous operation, typically using the special value
* @c asio::detached. For example:
* @code my_socket.async_send(my_buffer, asio::detached);
* @endcode
*/
class detached_t
{
public:
/// Constructor.
ASIO_CONSTEXPR detached_t()
{
}
};
/// A special value, similar to std::nothrow.
/**
* See the documentation for asio::detached_t for a usage example.
*/
#if defined(ASIO_HAS_CONSTEXPR) || defined(GENERATING_DOCUMENTATION)
constexpr detached_t detached;
#elif defined(ASIO_MSVC)
__declspec(selectany) detached_t detached;
#endif
} // namespace asio
#include "asio/detail/pop_options.hpp"
#include "asio/impl/detached.hpp"
#endif // ASIO_DETACHED_HPP

View File

@@ -2,7 +2,7 @@
// detail/array.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/array_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/assert.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/atomic_count.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/base_from_completion_cond.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -27,8 +27,9 @@ template <typename CompletionCondition>
class base_from_completion_cond
{
protected:
explicit base_from_completion_cond(CompletionCondition completion_condition)
: completion_condition_(completion_condition)
explicit base_from_completion_cond(CompletionCondition& completion_condition)
: completion_condition_(
ASIO_MOVE_CAST(CompletionCondition)(completion_condition))
{
}

View File

@@ -2,7 +2,7 @@
// detail/bind_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/buffer_resize_guard.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/buffer_sequence_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/buffered_stream_storage.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/call_stack.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/chrono.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/chrono_time_traits.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/completion_handler.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/concurrency_hint.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/conditionally_enabled_event.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/conditionally_enabled_mutex.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/config.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -11,6 +11,20 @@
#ifndef ASIO_DETAIL_CONFIG_HPP
#define ASIO_DETAIL_CONFIG_HPP
// boostify: non-boost code starts here
#if !defined(ASIO_STANDALONE)
# if !defined(ASIO_ENABLE_BOOST)
# if (__cplusplus >= 201103)
# define ASIO_STANDALONE 1
# elif defined(_MSC_VER) && defined(_MSVC_LANG)
# if (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)
# define ASIO_STANDALONE 1
# endif // (_MSC_VER >= 1900) && (_MSVC_LANG >= 201103)
# endif // defined(_MSC_VER) && defined(_MSVC_LANG)
# endif // !defined(ASIO_ENABLE_BOOST)
#endif // !defined(ASIO_STANDALONE)
// boostify: non-boost code ends here
#if defined(ASIO_STANDALONE)
# define ASIO_DISABLE_BOOST_ARRAY 1
# define ASIO_DISABLE_BOOST_ASSERT 1
@@ -69,7 +83,7 @@
|| (!defined(__MWERKS__) && !defined(__EDG_VERSION__)))
# define ASIO_MSVC _MSC_VER
# endif // defined(ASIO_HAS_BOOST_CONFIG) && defined(BOOST_MSVC)
#endif // defined(ASIO_MSVC)
#endif // !defined(ASIO_MSVC)
// Clang / libc++ detection.
#if defined(__clang__)
@@ -108,15 +122,26 @@
# define ASIO_HAS_MOVE 1
# endif // (_MSC_VER >= 1700)
# endif // defined(ASIO_MSVC)
# if defined(__INTEL_CXX11_MODE__)
# if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# define BOOST_ASIO_HAS_MOVE 1
# endif // defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1500)
# if defined(__ICL) && (__ICL >= 1500)
# define BOOST_ASIO_HAS_MOVE 1
# endif // defined(__ICL) && (__ICL >= 1500)
# endif // defined(__INTEL_CXX11_MODE__)
# endif // !defined(ASIO_DISABLE_MOVE)
#endif // !defined(ASIO_HAS_MOVE)
// If ASIO_MOVE_CAST isn't defined, and move support is available, define
// ASIO_MOVE_ARG and ASIO_MOVE_CAST to take advantage of rvalue
// references and perfect forwarding.
// * ASIO_MOVE_ARG,
// * ASIO_NONDEDUCED_MOVE_ARG, and
// * ASIO_MOVE_CAST
// to take advantage of rvalue references and perfect forwarding.
#if defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
# define ASIO_MOVE_ARG(type) type&&
# define ASIO_MOVE_ARG2(type1, type2) type1, type2&&
# define ASIO_NONDEDUCED_MOVE_ARG(type) type&
# define ASIO_MOVE_CAST(type) static_cast<type&&>
# define ASIO_MOVE_CAST2(type1, type2) static_cast<type1, type2&&>
#endif // defined(ASIO_HAS_MOVE) && !defined(ASIO_MOVE_CAST)
@@ -142,6 +167,7 @@
# else
# define ASIO_MOVE_ARG(type) type
# endif
# define ASIO_NONDEDUCED_MOVE_ARG(type) const type&
# define ASIO_MOVE_CAST(type) static_cast<const type&>
# define ASIO_MOVE_CAST2(type1, type2) static_cast<const type1, type2&>
#endif // !defined(ASIO_MOVE_CAST)
@@ -226,7 +252,7 @@
// Support noexcept on compilers known to allow it.
#if !defined(ASIO_NOEXCEPT)
# if !defined(ASIO_DISABLE_NOEXCEPT)
# if (BOOST_VERSION >= 105300)
# if defined(ASIO_HAS_BOOST_CONFIG) && (BOOST_VERSION >= 105300)
# define ASIO_NOEXCEPT BOOST_NOEXCEPT
# define ASIO_NOEXCEPT_OR_NOTHROW BOOST_NOEXCEPT_OR_NOTHROW
# elif defined(__clang__)
@@ -272,9 +298,9 @@
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(ASIO_MSVC)
# if (_MSC_VER >= 1700)
# if (_MSC_VER >= 1800)
# define ASIO_HAS_DECLTYPE 1
# endif // (_MSC_VER >= 1700)
# endif // (_MSC_VER >= 1800)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_DECLTYPE)
#endif // !defined(ASIO_HAS_DECLTYPE)
@@ -440,7 +466,13 @@
# if __has_include(<atomic>)
# define ASIO_HAS_STD_ATOMIC 1
# endif // __has_include(<atomic>)
# endif // (__cplusplus >= 201103)
# elif defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
# if (__clang_major__ >= 10)
# if __has_include(<atomic>)
# define ASIO_HAS_STD_ATOMIC 1
# endif // __has_include(<atomic>)
# endif // (__clang_major__ >= 10)
# endif /// defined(__apple_build_version__) && defined(_LIBCPP_VERSION)
# endif // defined(__clang__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
@@ -770,32 +802,77 @@
# endif // !defined(ASIO_DISABLE_STD_FUTURE)
#endif // !defined(ASIO_HAS_STD_FUTURE)
// Standard library support for experimental::string_view.
// Standard library support for std::string_view.
#if !defined(ASIO_HAS_STD_STRING_VIEW)
# if !defined(ASIO_DISABLE_STD_STRING_VIEW)
# if defined(__clang__)
# if (__cplusplus >= 201402)
# if __has_include(<experimental/string_view>)
# if defined(ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201402)
# if __has_include(<string_view>)
# define ASIO_HAS_STD_STRING_VIEW 1
# endif // __has_include(<string_view>)
# endif // (__cplusplus >= 201402)
# else // defined(ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201703)
# if __has_include(<string_view>)
# define ASIO_HAS_STD_STRING_VIEW 1
# endif // __has_include(<string_view>)
# endif // (__cplusplus >= 201703)
# endif // defined(ASIO_HAS_CLANG_LIBCXX)
# elif defined(__GNUC__)
# if (__GNUC__ >= 7)
# if (__cplusplus >= 201703)
# define ASIO_HAS_STD_STRING_VIEW 1
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402)
# endif // (__cplusplus >= 201703)
# endif // (__GNUC__ >= 7)
# elif defined(ASIO_MSVC)
# if (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# define ASIO_HAS_STD_STRING_VIEW 1
# endif // (_MSC_VER >= 1910 && _MSVC_LANG >= 201703)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)
#endif // !defined(ASIO_HAS_STD_STRING_VIEW)
// Standard library support for std::experimental::string_view.
#if !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
# if !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
# if defined(__clang__)
# if defined(ASIO_HAS_CLANG_LIBCXX)
# if (_LIBCPP_VERSION < 7000)
# if (__cplusplus >= 201402)
# if __has_include(<experimental/string_view>)
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402)
# endif // (_LIBCPP_VERSION < 7000)
# else // defined(ASIO_HAS_CLANG_LIBCXX)
# if (__cplusplus >= 201402)
# if __has_include(<experimental/string_view>)
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // __has_include(<experimental/string_view>)
# endif // (__cplusplus >= 201402)
# endif // // defined(ASIO_HAS_CLANG_LIBCXX)
# endif // defined(__clang__)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
# if (__cplusplus >= 201402)
# define ASIO_HAS_STD_STRING_VIEW 1
# define ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW 1
# endif // (__cplusplus >= 201402)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 4)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(ASIO_MSVC)
# if (_MSC_VER >= 1910 && _HAS_CXX17)
# define ASIO_HAS_STD_STRING_VIEW
# endif // (_MSC_VER >= 1910)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_STD_STRING_VIEW)
#endif // !defined(ASIO_HAS_STD_STRING_VIEW)
# endif // !defined(ASIO_DISABLE_STD_EXPERIMENTAL_STRING_VIEW)
#endif // !defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
// Standard library has a string_view that we can use.
#if !defined(ASIO_HAS_STRING_VIEW)
# if !defined(ASIO_DISABLE_STRING_VIEW)
# if defined(ASIO_HAS_STD_STRING_VIEW)
# define ASIO_HAS_STRING_VIEW 1
# elif defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
# define ASIO_HAS_STRING_VIEW 1
# endif // defined(ASIO_HAS_STD_EXPERIMENTAL_STRING_VIEW)
# endif // !defined(ASIO_DISABLE_STRING_VIEW)
#endif // !defined(ASIO_HAS_STRING_VIEW)
// Standard library support for iostream move construction and assignment.
#if !defined(ASIO_HAS_STD_IOSTREAM_MOVE)
@@ -815,6 +892,17 @@
# endif // !defined(ASIO_DISABLE_STD_IOSTREAM_MOVE)
#endif // !defined(ASIO_HAS_STD_IOSTREAM_MOVE)
// Standard library has invoke_result (which supersedes result_of).
#if !defined(ASIO_HAS_STD_INVOKE_RESULT)
# if !defined(ASIO_DISABLE_STD_INVOKE_RESULT)
# if defined(ASIO_MSVC)
# if (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# define ASIO_HAS_STD_INVOKE_RESULT 1
# endif // (_MSC_VER >= 1911 && _MSVC_LANG >= 201703)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_STD_INVOKE_RESULT)
#endif // !defined(ASIO_HAS_STD_INVOKE_RESULT)
// Windows App target. Windows but with a limited API.
#if !defined(ASIO_WINDOWS_APP)
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0603)
@@ -860,15 +948,15 @@
# if defined(_MSC_VER) || defined(__BORLANDC__)
# pragma message( \
"Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately. For example:\n"\
"- add -D_WIN32_WINNT=0x0501 to the compiler command line; or\n"\
"- add _WIN32_WINNT=0x0501 to your project's Preprocessor Definitions.\n"\
"Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).")
"- add -D_WIN32_WINNT=0x0601 to the compiler command line; or\n"\
"- add _WIN32_WINNT=0x0601 to your project's Preprocessor Definitions.\n"\
"Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).")
# else // defined(_MSC_VER) || defined(__BORLANDC__)
# warning Please define _WIN32_WINNT or _WIN32_WINDOWS appropriately.
# warning For example, add -D_WIN32_WINNT=0x0501 to the compiler command line.
# warning Assuming _WIN32_WINNT=0x0501 (i.e. Windows XP target).
# warning For example, add -D_WIN32_WINNT=0x0601 to the compiler command line.
# warning Assuming _WIN32_WINNT=0x0601 (i.e. Windows 7 target).
# endif // defined(_MSC_VER) || defined(__BORLANDC__)
# define _WIN32_WINNT 0x0501
# define _WIN32_WINNT 0x0601
# endif // !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)
# if defined(_MSC_VER)
# if defined(_WIN32) && !defined(WIN32)
@@ -939,7 +1027,8 @@
|| defined(__FreeBSD__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__)
|| defined(__linux__) \
|| defined(__HAIKU__)
# define ASIO_HAS_UNISTD_H 1
# endif
# endif // !defined(ASIO_HAS_BOOST_CONFIG)
@@ -1303,33 +1392,6 @@
// || (defined(__MACH__) && defined(__APPLE__))
#endif // !defined(ASIO_DISABLE_SSIZE_T)
// Helper macros to manage the transition away from the old services-based API.
#if defined(ASIO_ENABLE_OLD_SERVICES)
# define ASIO_SVC_TPARAM , typename Service
# define ASIO_SVC_TPARAM_DEF1(d1) , typename Service d1
# define ASIO_SVC_TPARAM_DEF2(d1, d2) , typename Service d1, d2
# define ASIO_SVC_TARG , Service
# define ASIO_SVC_T Service
# define ASIO_SVC_TPARAM1 , typename Service1
# define ASIO_SVC_TPARAM1_DEF1(d1) , typename Service1 d1
# define ASIO_SVC_TPARAM1_DEF2(d1, d2) , typename Service1 d1, d2
# define ASIO_SVC_TARG1 , Service1
# define ASIO_SVC_T1 Service1
# define ASIO_SVC_ACCESS public
#else // defined(ASIO_ENABLE_OLD_SERVICES)
# define ASIO_SVC_TPARAM
# define ASIO_SVC_TPARAM_DEF1(d1)
# define ASIO_SVC_TPARAM_DEF2(d1, d2)
# define ASIO_SVC_TARG
// ASIO_SVC_T is defined at each point of use.
# define ASIO_SVC_TPARAM1
# define ASIO_SVC_TPARAM1_DEF1(d1)
# define ASIO_SVC_TPARAM1_DEF2(d1, d2)
# define ASIO_SVC_TARG1
// ASIO_SVC_T1 is defined at each point of use.
# define ASIO_SVC_ACCESS protected
#endif // defined(ASIO_ENABLE_OLD_SERVICES)
// Helper macros to manage transition away from error_code return values.
#if defined(ASIO_NO_DEPRECATED)
# define ASIO_SYNC_OP_VOID void
@@ -1369,4 +1431,24 @@
# define ASIO_UNUSED_VARIABLE
#endif // !defined(ASIO_UNUSED_VARIABLE)
// Support co_await on compilers known to allow it.
#if !defined(ASIO_HAS_CO_AWAIT)
# if !defined(ASIO_DISABLE_CO_AWAIT)
# if defined(ASIO_MSVC)
# if (_MSC_FULL_VER >= 190023506)
# if defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
# define ASIO_HAS_CO_AWAIT 1
# endif // defined(_RESUMABLE_FUNCTIONS_SUPPORTED)
# endif // (_MSC_FULL_VER >= 190023506)
# endif // defined(ASIO_MSVC)
# endif // !defined(ASIO_DISABLE_CO_AWAIT)
# if defined(__clang__)
# if (__cpp_coroutines >= 201703)
# if __has_include(<experimental/coroutine>)
# define ASIO_HAS_CO_AWAIT 1
# endif // __has_include(<experimental/coroutine>)
# endif // (__cpp_coroutines >= 201703)
# endif // defined(__clang__)
#endif // !defined(ASIO_HAS_CO_AWAIT)
#endif // ASIO_DETAIL_CONFIG_HPP

View File

@@ -2,7 +2,7 @@
// detail/consuming_buffers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -101,7 +101,7 @@ public:
std::advance(next, next_elem_);
std::size_t elem_offset = next_elem_offset_;
while (next != end && max_size > 0 && result.count < result.max_buffers)
while (next != end && max_size > 0 && (result.count) < result.max_buffers)
{
Buffer next_buf = Buffer(*next) + elem_offset;
result.elems[result.count] = asio::buffer(next_buf, max_size);
@@ -400,7 +400,7 @@ public:
// No-op.
}
std::size_t total_consume() const
std::size_t total_consumed() const
{
return 0;
}

View File

@@ -2,7 +2,7 @@
// detail/cstddef.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/cstdint.hpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/date_time_fwd.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/deadline_timer_service.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -18,7 +18,7 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include "asio/error.hpp"
#include "asio/io_context.hpp"
#include "asio/execution_context.hpp"
#include "asio/detail/bind_handler.hpp"
#include "asio/detail/fenced_block.hpp"
#include "asio/detail/memory.hpp"
@@ -43,7 +43,7 @@ namespace detail {
template <typename Time_Traits>
class deadline_timer_service
: public service_base<deadline_timer_service<Time_Traits> >
: public execution_context_service_base<deadline_timer_service<Time_Traits> >
{
public:
// The time type.
@@ -63,9 +63,10 @@ public:
};
// Constructor.
deadline_timer_service(asio::io_context& io_context)
: service_base<deadline_timer_service<Time_Traits> >(io_context),
scheduler_(asio::use_service<timer_scheduler>(io_context))
deadline_timer_service(execution_context& context)
: execution_context_service_base<
deadline_timer_service<Time_Traits> >(context),
scheduler_(asio::use_service<timer_scheduler>(context))
{
scheduler_.init_task();
scheduler_.add_timer_queue(timer_queue_);
@@ -225,14 +226,15 @@ public:
}
// Start an asynchronous wait on the timer.
template <typename Handler>
void async_wait(implementation_type& impl, Handler& handler)
template <typename Handler, typename IoExecutor>
void async_wait(implementation_type& impl,
Handler& handler, const IoExecutor& io_ex)
{
// Allocate and construct an operation to wrap the handler.
typedef wait_handler<Handler> op;
typedef wait_handler<Handler, IoExecutor> op;
typename op::ptr p = { asio::detail::addressof(handler),
op::ptr::allocate(handler), 0 };
p.p = new (p.v) op(handler);
p.p = new (p.v) op(handler, io_ex);
impl.might_have_pending_waits = true;

View File

@@ -2,7 +2,7 @@
// detail/dependent_type.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/descriptor_ops.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/descriptor_read_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -66,20 +66,21 @@ private:
MutableBufferSequence buffers_;
};
template <typename MutableBufferSequence, typename Handler>
template <typename MutableBufferSequence, typename Handler, typename IoExecutor>
class descriptor_read_op
: public descriptor_read_op_base<MutableBufferSequence>
{
public:
ASIO_DEFINE_HANDLER_PTR(descriptor_read_op);
descriptor_read_op(int descriptor,
const MutableBufferSequence& buffers, Handler& handler)
descriptor_read_op(int descriptor, const MutableBufferSequence& buffers,
Handler& handler, const IoExecutor& io_ex)
: descriptor_read_op_base<MutableBufferSequence>(
descriptor, buffers, &descriptor_read_op::do_complete),
handler_(ASIO_MOVE_CAST(Handler)(handler))
handler_(ASIO_MOVE_CAST(Handler)(handler)),
io_executor_(io_ex)
{
handler_work<Handler>::start(handler_);
handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -89,7 +90,7 @@ public:
// Take ownership of the handler object.
descriptor_read_op* o(static_cast<descriptor_read_op*>(base));
ptr p = { asio::detail::addressof(o->handler_), o, o };
handler_work<Handler> w(o->handler_);
handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
ASIO_HANDLER_COMPLETION((*o));
@@ -116,6 +117,7 @@ public:
private:
Handler handler_;
IoExecutor io_executor_;
};
} // namespace detail

View File

@@ -2,7 +2,7 @@
// detail/descriptor_write_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -66,20 +66,21 @@ private:
ConstBufferSequence buffers_;
};
template <typename ConstBufferSequence, typename Handler>
template <typename ConstBufferSequence, typename Handler, typename IoExecutor>
class descriptor_write_op
: public descriptor_write_op_base<ConstBufferSequence>
{
public:
ASIO_DEFINE_HANDLER_PTR(descriptor_write_op);
descriptor_write_op(int descriptor,
const ConstBufferSequence& buffers, Handler& handler)
descriptor_write_op(int descriptor, const ConstBufferSequence& buffers,
Handler& handler, const IoExecutor& io_ex)
: descriptor_write_op_base<ConstBufferSequence>(
descriptor, buffers, &descriptor_write_op::do_complete),
handler_(ASIO_MOVE_CAST(Handler)(handler))
handler_(ASIO_MOVE_CAST(Handler)(handler)),
io_executor_(io_ex)
{
handler_work<Handler>::start(handler_);
handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
}
static void do_complete(void* owner, operation* base,
@@ -89,7 +90,7 @@ public:
// Take ownership of the handler object.
descriptor_write_op* o(static_cast<descriptor_write_op*>(base));
ptr p = { asio::detail::addressof(o->handler_), o, o };
handler_work<Handler> w(o->handler_);
handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
ASIO_HANDLER_COMPLETION((*o));
@@ -116,6 +117,7 @@ public:
private:
Handler handler_;
IoExecutor io_executor_;
};
} // namespace detail

View File

@@ -2,7 +2,7 @@
// detail/dev_poll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/epoll_reactor.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -32,6 +32,10 @@
#include "asio/detail/wait_op.hpp"
#include "asio/execution_context.hpp"
#if defined(ASIO_HAS_TIMERFD)
# include <sys/timerfd.h>
#endif // defined(ASIO_HAS_TIMERFD)
#include "asio/detail/push_options.hpp"
namespace asio {

View File

@@ -2,7 +2,7 @@
// detail/event.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/eventfd_select_interrupter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2008 Roelof Naude (roelof.naude at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying

View File

@@ -0,0 +1,104 @@
//
// detail/executor_function.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_DETAIL_EXECUTOR_FUNCTION_HPP
#define ASIO_DETAIL_EXECUTOR_FUNCTION_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/handler_alloc_helpers.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace detail {
class executor_function_base
{
public:
void complete()
{
func_(this, true);
}
void destroy()
{
func_(this, false);
}
protected:
typedef void (*func_type)(executor_function_base*, bool);
executor_function_base(func_type func)
: func_(func)
{
}
// Prevents deletion through this type.
~executor_function_base()
{
}
private:
func_type func_;
};
template <typename Function, typename Alloc>
class executor_function : public executor_function_base
{
public:
ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(
thread_info_base::executor_function_tag, executor_function);
template <typename F>
executor_function(ASIO_MOVE_ARG(F) f, const Alloc& allocator)
: executor_function_base(&executor_function::do_complete),
function_(ASIO_MOVE_CAST(F)(f)),
allocator_(allocator)
{
}
static void do_complete(executor_function_base* base, bool call)
{
// Take ownership of the function object.
executor_function* o(static_cast<executor_function*>(base));
Alloc allocator(o->allocator_);
ptr p = { detail::addressof(allocator), o, o };
// Make a copy of the function so that the memory can be deallocated before
// the upcall is made. Even if we're not about to make an upcall, a
// sub-object of the function may be the true owner of the memory
// associated with the function. Consequently, a local copy of the function
// is required to ensure that any owning sub-object remains valid until
// after we have deallocated the memory here.
Function function(ASIO_MOVE_CAST(Function)(o->function_));
p.reset();
// Make the upcall if required.
if (call)
{
function();
}
}
private:
Function function_;
Alloc allocator_;
};
} // namespace detail
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_EXECUTOR_FUNCTION_HPP

View File

@@ -2,7 +2,7 @@
// detail/executor_op.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/fd_set_adapter.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/functional.hpp
// ~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -0,0 +1,33 @@
//
// detail/future.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_DETAIL_FUTURE_HPP
#define ASIO_DETAIL_FUTURE_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_STD_FUTURE)
# include <future>
// Even though the future header is available, libstdc++ may not implement the
// std::future class itself. However, we need to have already included the
// future header to reliably test for _GLIBCXX_HAS_GTHREADS.
# if defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)
# if defined(_GLIBCXX_HAS_GTHREADS)
# define ASIO_HAS_STD_FUTURE_CLASS 1
# endif // defined(_GLIBCXX_HAS_GTHREADS)
# else // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)
# define ASIO_HAS_STD_FUTURE_CLASS 1
# endif // defined(__GNUC__) && !defined(ASIO_HAS_CLANG_LIBCXX)
#endif // defined(ASIO_HAS_STD_FUTURE)
#endif // ASIO_DETAIL_FUTURE_HPP

View File

@@ -2,7 +2,7 @@
// detail/gcc_arm_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/gcc_hppa_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/gcc_sync_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/gcc_x86_fenced_block.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/global.hpp
// ~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/handler_alloc_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -192,7 +192,7 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \
/**/
#define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
#define ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR(purpose, op) \
struct ptr \
{ \
const Alloc* a; \
@@ -205,9 +205,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
static op* allocate(const Alloc& a) \
{ \
typedef typename ::asio::detail::get_recycling_allocator< \
Alloc>::type recycling_allocator_type; \
Alloc, purpose>::type recycling_allocator_type; \
ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
::asio::detail::get_recycling_allocator<Alloc>::get(a)); \
::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(a)); \
return a1.allocate(1); \
} \
void reset() \
@@ -220,9 +221,10 @@ struct get_hook_allocator<Handler, std::allocator<T> >
if (v) \
{ \
typedef typename ::asio::detail::get_recycling_allocator< \
Alloc>::type recycling_allocator_type; \
Alloc, purpose>::type recycling_allocator_type; \
ASIO_REBIND_ALLOC(recycling_allocator_type, op) a1( \
::asio::detail::get_recycling_allocator<Alloc>::get(*a)); \
::asio::detail::get_recycling_allocator< \
Alloc, purpose>::get(*a)); \
a1.deallocate(static_cast<op*>(v), 1); \
v = 0; \
} \
@@ -230,6 +232,11 @@ struct get_hook_allocator<Handler, std::allocator<T> >
} \
/**/
#define ASIO_DEFINE_HANDLER_ALLOCATOR_PTR(op) \
ASIO_DEFINE_TAGGED_HANDLER_ALLOCATOR_PTR( \
::asio::detail::thread_info_base::default_tag, op ) \
/**/
#include "asio/detail/pop_options.hpp"
#endif // ASIO_DETAIL_HANDLER_ALLOC_HELPERS_HPP

View File

@@ -2,7 +2,7 @@
// detail/handler_cont_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/handler_invoke_helpers.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/handler_tracking.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

View File

@@ -2,7 +2,7 @@
// detail/handler_type_requirements.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -127,7 +127,7 @@ struct handler_type_requirements
{
};
#define ASIO_COMPLETION_HANDLER_CHECK( \
#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
handler_type, handler) \
\
typedef ASIO_HANDLER_TYPE(handler_type, \
@@ -492,7 +492,7 @@ struct handler_type_requirements
#else // !defined(ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS)
#define ASIO_COMPLETION_HANDLER_CHECK( \
#define ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \
handler_type, handler) \
typedef int ASIO_UNUSED_TYPEDEF

Some files were not shown because too many files have changed in this diff Show More