![]() |
|
|||
File indexing completed on 2025-07-01 08:09:32
0001 // 0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) 0003 // 0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0006 // 0007 // Official repository: https://github.com/boostorg/beast 0008 // 0009 0010 #ifndef BOOST_BEAST_CORE_FLAT_STREAM_HPP 0011 #define BOOST_BEAST_CORE_FLAT_STREAM_HPP 0012 0013 #include <boost/beast/core/detail/config.hpp> 0014 #include <boost/beast/core/error.hpp> 0015 #include <boost/beast/core/flat_buffer.hpp> 0016 #include <boost/beast/core/stream_traits.hpp> 0017 #include <boost/beast/core/detail/flat_stream.hpp> 0018 #include <boost/asio/async_result.hpp> 0019 #include <cstdlib> 0020 #include <utility> 0021 0022 namespace boost { 0023 namespace beast { 0024 0025 /** (Deprecated: This wrapper is no longer needed; Asio linearizes 0026 scatter/gather I/O in ssl::stream.) Stream wrapper to improve write 0027 performance. 0028 0029 This wrapper flattens writes for buffer sequences having length 0030 greater than 1 and total size below a predefined amount, using 0031 a dynamic memory allocation. It is primarily designed to overcome 0032 a performance limitation of the current version of `net::ssl::stream`, 0033 which does not use OpenSSL's scatter/gather interface for its 0034 low-level read some and write some operations. 0035 0036 It is normally not necessary to use this class directly if you 0037 are already using @ref ssl_stream. The following examples shows 0038 how to use this class with the ssl stream that comes with 0039 networking: 0040 0041 @par Example 0042 0043 To use the @ref flat_stream template with SSL streams, declare 0044 a variable of the correct type. Parameters passed to the constructor 0045 will be forwarded to the next layer's constructor: 0046 0047 @code 0048 flat_stream<net::ssl::stream<ip::tcp::socket>> fs{ioc, ctx}; 0049 @endcode 0050 Alternatively you can write 0051 @code 0052 ssl::stream<ip::tcp::socket> ss{ioc, ctx}; 0053 flat_stream<net::ssl::stream<ip::tcp::socket>&> fs{ss}; 0054 @endcode 0055 0056 The resulting stream may be passed to any stream algorithms which 0057 operate on synchronous or asynchronous read or write streams, 0058 examples include: 0059 0060 @li `net::read`, `net::async_read` 0061 0062 @li `net::write`, `net::async_write` 0063 0064 @li `net::read_until`, `net::async_read_until` 0065 0066 The stream may also be used as a template parameter in other 0067 stream wrappers, such as for websocket: 0068 @code 0069 websocket::stream<flat_stream<net::ssl::stream<ip::tcp::socket>>> ws{ioc, ctx}; 0070 @endcode 0071 0072 @tparam NextLayer The type representing the next layer, to which 0073 data will be read and written during operations. For synchronous 0074 operations, the type must support the @b SyncStream concept. For 0075 asynchronous operations, the type must support the @b AsyncStream 0076 concept. This type will usually be some variation of 0077 `net::ssl::stream`. 0078 0079 @par Concepts 0080 @li SyncStream 0081 @li AsyncStream 0082 0083 @see 0084 @li https://github.com/boostorg/asio/issues/100 0085 @li https://github.com/boostorg/beast/issues/1108 0086 @li https://stackoverflow.com/questions/38198638/openssl-ssl-write-from-multiple-buffers-ssl-writev 0087 @li https://stackoverflow.com/questions/50026167/performance-drop-on-port-from-beast-1-0-0-b66-to-boost-1-67-0-beast 0088 */ 0089 template<class NextLayer> 0090 class flat_stream 0091 #if ! BOOST_BEAST_DOXYGEN 0092 : private detail::flat_stream_base 0093 #endif 0094 { 0095 NextLayer stream_; 0096 flat_buffer buffer_; 0097 0098 BOOST_STATIC_ASSERT(has_get_executor<NextLayer>::value); 0099 0100 struct ops; 0101 0102 template<class ConstBufferSequence> 0103 std::size_t 0104 stack_write_some( 0105 std::size_t size, 0106 ConstBufferSequence const& buffers, 0107 error_code& ec); 0108 0109 public: 0110 /// The type of the next layer. 0111 using next_layer_type = 0112 typename std::remove_reference<NextLayer>::type; 0113 0114 /// The type of the executor associated with the object. 0115 using executor_type = beast::executor_type<next_layer_type>; 0116 0117 flat_stream(flat_stream&&) = default; 0118 flat_stream(flat_stream const&) = default; 0119 flat_stream& operator=(flat_stream&&) = default; 0120 flat_stream& operator=(flat_stream const&) = default; 0121 0122 /** Destructor 0123 0124 The treatment of pending operations will be the same as that 0125 of the next layer. 0126 */ 0127 ~flat_stream() = default; 0128 0129 /** Constructor 0130 0131 Arguments, if any, are forwarded to the next layer's constructor. 0132 */ 0133 template<class... Args> 0134 explicit 0135 flat_stream(Args&&... args); 0136 0137 //-------------------------------------------------------------------------- 0138 0139 /** Get the executor associated with the object. 0140 0141 This function may be used to obtain the executor object that the 0142 stream uses to dispatch handlers for asynchronous operations. 0143 0144 @return A copy of the executor that stream will use to dispatch handlers. 0145 */ 0146 executor_type 0147 get_executor() noexcept 0148 { 0149 return stream_.get_executor(); 0150 } 0151 0152 /** Get a reference to the next layer 0153 0154 This function returns a reference to the next layer 0155 in a stack of stream layers. 0156 0157 @return A reference to the next layer in the stack of 0158 stream layers. 0159 */ 0160 next_layer_type& 0161 next_layer() noexcept 0162 { 0163 return stream_; 0164 } 0165 0166 /** Get a reference to the next layer 0167 0168 This function returns a reference to the next layer in a 0169 stack of stream layers. 0170 0171 @return A reference to the next layer in the stack of 0172 stream layers. 0173 */ 0174 next_layer_type const& 0175 next_layer() const noexcept 0176 { 0177 return stream_; 0178 } 0179 0180 //-------------------------------------------------------------------------- 0181 0182 /** Read some data from the stream. 0183 0184 This function is used to read data from the stream. The function call will 0185 block until one or more bytes of data has been read successfully, or until 0186 an error occurs. 0187 0188 @param buffers The buffers into which the data will be read. 0189 0190 @returns The number of bytes read. 0191 0192 @throws boost::system::system_error Thrown on failure. 0193 0194 @note The `read_some` operation may not read all of the requested number of 0195 bytes. Consider using the function `net::read` if you need to ensure 0196 that the requested amount of data is read before the blocking operation 0197 completes. 0198 */ 0199 template<class MutableBufferSequence> 0200 std::size_t 0201 read_some(MutableBufferSequence const& buffers); 0202 0203 /** Read some data from the stream. 0204 0205 This function is used to read data from the stream. The function call will 0206 block until one or more bytes of data has been read successfully, or until 0207 an error occurs. 0208 0209 @param buffers The buffers into which the data will be read. 0210 0211 @param ec Set to indicate what error occurred, if any. 0212 0213 @returns The number of bytes read. 0214 0215 @note The `read_some` operation may not read all of the requested number of 0216 bytes. Consider using the function `net::read` if you need to ensure 0217 that the requested amount of data is read before the blocking operation 0218 completes. 0219 */ 0220 template<class MutableBufferSequence> 0221 std::size_t 0222 read_some( 0223 MutableBufferSequence const& buffers, 0224 error_code& ec); 0225 0226 /** Start an asynchronous read. 0227 0228 This function is used to asynchronously read one or more bytes of data from 0229 the stream. The function call always returns immediately. 0230 0231 @param buffers The buffers into which the data will be read. Although the 0232 buffers object may be copied as necessary, ownership of the underlying 0233 buffers is retained by the caller, which must guarantee that they remain 0234 valid until the handler is called. 0235 0236 @param handler The completion handler to invoke when the operation 0237 completes. The implementation takes ownership of the handler by 0238 performing a decay-copy. The equivalent function signature of 0239 the handler must be: 0240 @code 0241 void handler( 0242 error_code const& error, // Result of operation. 0243 std::size_t bytes_transferred // Number of bytes read. 0244 ); 0245 @endcode 0246 If the handler has an associated immediate executor, 0247 an immediate completion will be dispatched to it. 0248 Otherwise, the handler will not be invoked from within 0249 this function. Invocation of the handler will be performed 0250 by dispatching to the immediate executor. If no 0251 immediate executor is specified, this is equivalent 0252 to using `net::post`. 0253 @note The `read_some` operation may not read all of the requested number of 0254 bytes. Consider using the function `net::async_read` if you need 0255 to ensure that the requested amount of data is read before the asynchronous 0256 operation completes. 0257 */ 0258 template< 0259 class MutableBufferSequence, 0260 BOOST_BEAST_ASYNC_TPARAM2 ReadHandler = 0261 net::default_completion_token_t<executor_type>> 0262 BOOST_BEAST_ASYNC_RESULT2(ReadHandler) 0263 async_read_some( 0264 MutableBufferSequence const& buffers, 0265 ReadHandler&& handler = 0266 net::default_completion_token_t<executor_type>{}); 0267 0268 /** Write some data to the stream. 0269 0270 This function is used to write data on the stream. The function call will 0271 block until one or more bytes of data has been written successfully, or 0272 until an error occurs. 0273 0274 @param buffers The data to be written. 0275 0276 @returns The number of bytes written. 0277 0278 @throws boost::system::system_error Thrown on failure. 0279 0280 @note The `write_some` operation may not transmit all of the data to the 0281 peer. Consider using the function `net::write` if you need to 0282 ensure that all data is written before the blocking operation completes. 0283 */ 0284 template<class ConstBufferSequence> 0285 std::size_t 0286 write_some(ConstBufferSequence const& buffers); 0287 0288 /** Write some data to the stream. 0289 0290 This function is used to write data on the stream. The function call will 0291 block until one or more bytes of data has been written successfully, or 0292 until an error occurs. 0293 0294 @param buffers The data to be written. 0295 0296 @param ec Set to indicate what error occurred, if any. 0297 0298 @returns The number of bytes written. 0299 0300 @note The `write_some` operation may not transmit all of the data to the 0301 peer. Consider using the function `net::write` if you need to 0302 ensure that all data is written before the blocking operation completes. 0303 */ 0304 template<class ConstBufferSequence> 0305 std::size_t 0306 write_some( 0307 ConstBufferSequence const& buffers, 0308 error_code& ec); 0309 0310 /** Start an asynchronous write. 0311 0312 This function is used to asynchronously write one or more bytes of data to 0313 the stream. The function call always returns immediately. 0314 0315 @param buffers The data to be written to the stream. Although the buffers 0316 object may be copied as necessary, ownership of the underlying buffers is 0317 retained by the caller, which must guarantee that they remain valid until 0318 the handler is called. 0319 0320 @param handler The completion handler to invoke when the operation 0321 completes. The implementation takes ownership of the handler by 0322 performing a decay-copy. The equivalent function signature of 0323 the handler must be: 0324 @code 0325 void handler( 0326 error_code const& ec, // Result of operation. 0327 std::size_t bytes_transferred // Number of bytes written. 0328 ); 0329 @endcode 0330 If the handler has an associated immediate executor, 0331 an immediate completion will be dispatched to it. 0332 Otherwise, the handler will not be invoked from within 0333 this function. Invocation of the handler will be performed 0334 by dispatching to the immediate executor. If no 0335 immediate executor is specified, this is equivalent 0336 to using `net::post`. 0337 @note The `async_write_some` operation may not transmit all of the data to 0338 the peer. Consider using the function `net::async_write` if you need 0339 to ensure that all data is written before the asynchronous operation completes. 0340 */ 0341 template< 0342 class ConstBufferSequence, 0343 BOOST_BEAST_ASYNC_TPARAM2 WriteHandler = 0344 net::default_completion_token_t<executor_type>> 0345 BOOST_BEAST_ASYNC_RESULT2(WriteHandler) 0346 async_write_some( 0347 ConstBufferSequence const& buffers, 0348 WriteHandler&& handler = 0349 net::default_completion_token_t<executor_type>{}); 0350 }; 0351 0352 } // beast 0353 } // boost 0354 0355 #include <boost/beast/core/impl/flat_stream.hpp> 0356 0357 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |