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