]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/basic_seq_packet_socket.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / asio / basic_seq_packet_socket.hpp
1 //
2 // basic_seq_packet_socket.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10
11 #ifndef BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
12 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18 #include <boost/asio/detail/config.hpp>
19 #include <cstddef>
20 #include <boost/asio/basic_socket.hpp>
21 #include <boost/asio/detail/handler_type_requirements.hpp>
22 #include <boost/asio/detail/throw_error.hpp>
23 #include <boost/asio/error.hpp>
24
25 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
26 # include <boost/asio/seq_packet_socket_service.hpp>
27 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
28
29 #include <boost/asio/detail/push_options.hpp>
30
31 namespace boost {
32 namespace asio {
33
34 /// Provides sequenced packet socket functionality.
35 /**
36 * The basic_seq_packet_socket class template provides asynchronous and blocking
37 * sequenced packet socket functionality.
38 *
39 * @par Thread Safety
40 * @e Distinct @e objects: Safe.@n
41 * @e Shared @e objects: Unsafe.
42 */
43 template <typename Protocol
44 BOOST_ASIO_SVC_TPARAM_DEF1(= seq_packet_socket_service<Protocol>)>
45 class basic_seq_packet_socket
46 : public basic_socket<Protocol BOOST_ASIO_SVC_TARG>
47 {
48 public:
49 /// The native representation of a socket.
50 #if defined(GENERATING_DOCUMENTATION)
51 typedef implementation_defined native_handle_type;
52 #else
53 typedef typename basic_socket<
54 Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type;
55 #endif
56
57 /// The protocol type.
58 typedef Protocol protocol_type;
59
60 /// The endpoint type.
61 typedef typename Protocol::endpoint endpoint_type;
62
63 /// Construct a basic_seq_packet_socket without opening it.
64 /**
65 * This constructor creates a sequenced packet socket without opening it. The
66 * socket needs to be opened and then connected or accepted before data can
67 * be sent or received on it.
68 *
69 * @param io_context The io_context object that the sequenced packet socket
70 * will use to dispatch handlers for any asynchronous operations performed on
71 * the socket.
72 */
73 explicit basic_seq_packet_socket(boost::asio::io_context& io_context)
74 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context)
75 {
76 }
77
78 /// Construct and open a basic_seq_packet_socket.
79 /**
80 * This constructor creates and opens a sequenced_packet socket. The socket
81 * needs to be connected or accepted before data can be sent or received on
82 * it.
83 *
84 * @param io_context The io_context object that the sequenced packet socket
85 * will use to dispatch handlers for any asynchronous operations performed on
86 * the socket.
87 *
88 * @param protocol An object specifying protocol parameters to be used.
89 *
90 * @throws boost::system::system_error Thrown on failure.
91 */
92 basic_seq_packet_socket(boost::asio::io_context& io_context,
93 const protocol_type& protocol)
94 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, protocol)
95 {
96 }
97
98 /// Construct a basic_seq_packet_socket, opening it and binding it to the
99 /// given local endpoint.
100 /**
101 * This constructor creates a sequenced packet socket and automatically opens
102 * it bound to the specified endpoint on the local machine. The protocol used
103 * is the protocol associated with the given endpoint.
104 *
105 * @param io_context The io_context object that the sequenced packet socket
106 * will use to dispatch handlers for any asynchronous operations performed on
107 * the socket.
108 *
109 * @param endpoint An endpoint on the local machine to which the sequenced
110 * packet socket will be bound.
111 *
112 * @throws boost::system::system_error Thrown on failure.
113 */
114 basic_seq_packet_socket(boost::asio::io_context& io_context,
115 const endpoint_type& endpoint)
116 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(io_context, endpoint)
117 {
118 }
119
120 /// Construct a basic_seq_packet_socket on an existing native socket.
121 /**
122 * This constructor creates a sequenced packet socket object to hold an
123 * existing native socket.
124 *
125 * @param io_context The io_context object that the sequenced packet socket
126 * will use to dispatch handlers for any asynchronous operations performed on
127 * the socket.
128 *
129 * @param protocol An object specifying protocol parameters to be used.
130 *
131 * @param native_socket The new underlying socket implementation.
132 *
133 * @throws boost::system::system_error Thrown on failure.
134 */
135 basic_seq_packet_socket(boost::asio::io_context& io_context,
136 const protocol_type& protocol, const native_handle_type& native_socket)
137 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(
138 io_context, protocol, native_socket)
139 {
140 }
141
142 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
143 /// Move-construct a basic_seq_packet_socket from another.
144 /**
145 * This constructor moves a sequenced packet socket from one object to
146 * another.
147 *
148 * @param other The other basic_seq_packet_socket object from which the move
149 * will occur.
150 *
151 * @note Following the move, the moved-from object is in the same state as if
152 * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
153 */
154 basic_seq_packet_socket(basic_seq_packet_socket&& other)
155 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
156 {
157 }
158
159 /// Move-assign a basic_seq_packet_socket from another.
160 /**
161 * This assignment operator moves a sequenced packet socket from one object to
162 * another.
163 *
164 * @param other The other basic_seq_packet_socket object from which the move
165 * will occur.
166 *
167 * @note Following the move, the moved-from object is in the same state as if
168 * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
169 */
170 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
171 {
172 basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
173 return *this;
174 }
175
176 /// Move-construct a basic_seq_packet_socket from a socket of another protocol
177 /// type.
178 /**
179 * This constructor moves a sequenced packet socket from one object to
180 * another.
181 *
182 * @param other The other basic_seq_packet_socket object from which the move
183 * will occur.
184 *
185 * @note Following the move, the moved-from object is in the same state as if
186 * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
187 */
188 template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
189 basic_seq_packet_socket(
190 basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other,
191 typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0)
192 : basic_socket<Protocol BOOST_ASIO_SVC_TARG>(std::move(other))
193 {
194 }
195
196 /// Move-assign a basic_seq_packet_socket from a socket of another protocol
197 /// type.
198 /**
199 * This assignment operator moves a sequenced packet socket from one object to
200 * another.
201 *
202 * @param other The other basic_seq_packet_socket object from which the move
203 * will occur.
204 *
205 * @note Following the move, the moved-from object is in the same state as if
206 * constructed using the @c basic_seq_packet_socket(io_context&) constructor.
207 */
208 template <typename Protocol1 BOOST_ASIO_SVC_TPARAM1>
209 typename enable_if<is_convertible<Protocol1, Protocol>::value,
210 basic_seq_packet_socket>::type& operator=(
211 basic_seq_packet_socket<Protocol1 BOOST_ASIO_SVC_TARG1>&& other)
212 {
213 basic_socket<Protocol BOOST_ASIO_SVC_TARG>::operator=(std::move(other));
214 return *this;
215 }
216 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
217
218 /// Destroys the socket.
219 /**
220 * This function destroys the socket, cancelling any outstanding asynchronous
221 * operations associated with the socket as if by calling @c cancel.
222 */
223 ~basic_seq_packet_socket()
224 {
225 }
226
227 /// Send some data on the socket.
228 /**
229 * This function is used to send data on the sequenced packet socket. The
230 * function call will block until the data has been sent successfully, or an
231 * until error occurs.
232 *
233 * @param buffers One or more data buffers to be sent on the socket.
234 *
235 * @param flags Flags specifying how the send call is to be made.
236 *
237 * @returns The number of bytes sent.
238 *
239 * @throws boost::system::system_error Thrown on failure.
240 *
241 * @par Example
242 * To send a single data buffer use the @ref buffer function as follows:
243 * @code
244 * socket.send(boost::asio::buffer(data, size), 0);
245 * @endcode
246 * See the @ref buffer documentation for information on sending multiple
247 * buffers in one go, and how to use it with arrays, boost::array or
248 * std::vector.
249 */
250 template <typename ConstBufferSequence>
251 std::size_t send(const ConstBufferSequence& buffers,
252 socket_base::message_flags flags)
253 {
254 boost::system::error_code ec;
255 std::size_t s = this->get_service().send(
256 this->get_implementation(), buffers, flags, ec);
257 boost::asio::detail::throw_error(ec, "send");
258 return s;
259 }
260
261 /// Send some data on the socket.
262 /**
263 * This function is used to send data on the sequenced packet socket. The
264 * function call will block the data has been sent successfully, or an until
265 * error occurs.
266 *
267 * @param buffers One or more data buffers to be sent on the socket.
268 *
269 * @param flags Flags specifying how the send call is to be made.
270 *
271 * @param ec Set to indicate what error occurred, if any.
272 *
273 * @returns The number of bytes sent. Returns 0 if an error occurred.
274 *
275 * @note The send operation may not transmit all of the data to the peer.
276 * Consider using the @ref write function if you need to ensure that all data
277 * is written before the blocking operation completes.
278 */
279 template <typename ConstBufferSequence>
280 std::size_t send(const ConstBufferSequence& buffers,
281 socket_base::message_flags flags, boost::system::error_code& ec)
282 {
283 return this->get_service().send(
284 this->get_implementation(), buffers, flags, ec);
285 }
286
287 /// Start an asynchronous send.
288 /**
289 * This function is used to asynchronously send data on the sequenced packet
290 * socket. The function call always returns immediately.
291 *
292 * @param buffers One or more data buffers to be sent on the socket. Although
293 * the buffers object may be copied as necessary, ownership of the underlying
294 * memory blocks is retained by the caller, which must guarantee that they
295 * remain valid until the handler is called.
296 *
297 * @param flags Flags specifying how the send call is to be made.
298 *
299 * @param handler The handler to be called when the send operation completes.
300 * Copies will be made of the handler as required. The function signature of
301 * the handler must be:
302 * @code void handler(
303 * const boost::system::error_code& error, // Result of operation.
304 * std::size_t bytes_transferred // Number of bytes sent.
305 * ); @endcode
306 * Regardless of whether the asynchronous operation completes immediately or
307 * not, the handler will not be invoked from within this function. Invocation
308 * of the handler will be performed in a manner equivalent to using
309 * boost::asio::io_context::post().
310 *
311 * @par Example
312 * To send a single data buffer use the @ref buffer function as follows:
313 * @code
314 * socket.async_send(boost::asio::buffer(data, size), 0, handler);
315 * @endcode
316 * See the @ref buffer documentation for information on sending multiple
317 * buffers in one go, and how to use it with arrays, boost::array or
318 * std::vector.
319 */
320 template <typename ConstBufferSequence, typename WriteHandler>
321 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,
322 void (boost::system::error_code, std::size_t))
323 async_send(const ConstBufferSequence& buffers,
324 socket_base::message_flags flags,
325 BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
326 {
327 // If you get an error on the following line it means that your handler does
328 // not meet the documented type requirements for a WriteHandler.
329 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
330
331 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
332 return this->get_service().async_send(this->get_implementation(),
333 buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
334 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
335 async_completion<WriteHandler,
336 void (boost::system::error_code, std::size_t)> init(handler);
337
338 this->get_service().async_send(this->get_implementation(),
339 buffers, flags, init.completion_handler);
340
341 return init.result.get();
342 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
343 }
344
345 /// Receive some data on the socket.
346 /**
347 * This function is used to receive data on the sequenced packet socket. The
348 * function call will block until data has been received successfully, or
349 * until an error occurs.
350 *
351 * @param buffers One or more buffers into which the data will be received.
352 *
353 * @param out_flags After the receive call completes, contains flags
354 * associated with the received data. For example, if the
355 * socket_base::message_end_of_record bit is set then the received data marks
356 * the end of a record.
357 *
358 * @returns The number of bytes received.
359 *
360 * @throws boost::system::system_error Thrown on failure. An error code of
361 * boost::asio::error::eof indicates that the connection was closed by the
362 * peer.
363 *
364 * @par Example
365 * To receive into a single data buffer use the @ref buffer function as
366 * follows:
367 * @code
368 * socket.receive(boost::asio::buffer(data, size), out_flags);
369 * @endcode
370 * See the @ref buffer documentation for information on receiving into
371 * multiple buffers in one go, and how to use it with arrays, boost::array or
372 * std::vector.
373 */
374 template <typename MutableBufferSequence>
375 std::size_t receive(const MutableBufferSequence& buffers,
376 socket_base::message_flags& out_flags)
377 {
378 boost::system::error_code ec;
379 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
380 std::size_t s = this->get_service().receive(
381 this->get_implementation(), buffers, 0, out_flags, ec);
382 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
383 std::size_t s = this->get_service().receive_with_flags(
384 this->get_implementation(), buffers, 0, out_flags, ec);
385 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
386 boost::asio::detail::throw_error(ec, "receive");
387 return s;
388 }
389
390 /// Receive some data on the socket.
391 /**
392 * This function is used to receive data on the sequenced packet socket. The
393 * function call will block until data has been received successfully, or
394 * until an error occurs.
395 *
396 * @param buffers One or more buffers into which the data will be received.
397 *
398 * @param in_flags Flags specifying how the receive call is to be made.
399 *
400 * @param out_flags After the receive call completes, contains flags
401 * associated with the received data. For example, if the
402 * socket_base::message_end_of_record bit is set then the received data marks
403 * the end of a record.
404 *
405 * @returns The number of bytes received.
406 *
407 * @throws boost::system::system_error Thrown on failure. An error code of
408 * boost::asio::error::eof indicates that the connection was closed by the
409 * peer.
410 *
411 * @note The receive operation may not receive all of the requested number of
412 * bytes. Consider using the @ref read function if you need to ensure that the
413 * requested amount of data is read before the blocking operation completes.
414 *
415 * @par Example
416 * To receive into a single data buffer use the @ref buffer function as
417 * follows:
418 * @code
419 * socket.receive(boost::asio::buffer(data, size), 0, out_flags);
420 * @endcode
421 * See the @ref buffer documentation for information on receiving into
422 * multiple buffers in one go, and how to use it with arrays, boost::array or
423 * std::vector.
424 */
425 template <typename MutableBufferSequence>
426 std::size_t receive(const MutableBufferSequence& buffers,
427 socket_base::message_flags in_flags,
428 socket_base::message_flags& out_flags)
429 {
430 boost::system::error_code ec;
431 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
432 std::size_t s = this->get_service().receive(
433 this->get_implementation(), buffers, in_flags, out_flags, ec);
434 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
435 std::size_t s = this->get_service().receive_with_flags(
436 this->get_implementation(), buffers, in_flags, out_flags, ec);
437 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
438 boost::asio::detail::throw_error(ec, "receive");
439 return s;
440 }
441
442 /// Receive some data on a connected socket.
443 /**
444 * This function is used to receive data on the sequenced packet socket. The
445 * function call will block until data has been received successfully, or
446 * until an error occurs.
447 *
448 * @param buffers One or more buffers into which the data will be received.
449 *
450 * @param in_flags Flags specifying how the receive call is to be made.
451 *
452 * @param out_flags After the receive call completes, contains flags
453 * associated with the received data. For example, if the
454 * socket_base::message_end_of_record bit is set then the received data marks
455 * the end of a record.
456 *
457 * @param ec Set to indicate what error occurred, if any.
458 *
459 * @returns The number of bytes received. Returns 0 if an error occurred.
460 *
461 * @note The receive operation may not receive all of the requested number of
462 * bytes. Consider using the @ref read function if you need to ensure that the
463 * requested amount of data is read before the blocking operation completes.
464 */
465 template <typename MutableBufferSequence>
466 std::size_t receive(const MutableBufferSequence& buffers,
467 socket_base::message_flags in_flags,
468 socket_base::message_flags& out_flags, boost::system::error_code& ec)
469 {
470 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
471 return this->get_service().receive(this->get_implementation(),
472 buffers, in_flags, out_flags, ec);
473 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
474 return this->get_service().receive_with_flags(this->get_implementation(),
475 buffers, in_flags, out_flags, ec);
476 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
477 }
478
479 /// Start an asynchronous receive.
480 /**
481 * This function is used to asynchronously receive data from the sequenced
482 * packet socket. The function call always returns immediately.
483 *
484 * @param buffers One or more buffers into which the data will be received.
485 * Although the buffers object may be copied as necessary, ownership of the
486 * underlying memory blocks is retained by the caller, which must guarantee
487 * that they remain valid until the handler is called.
488 *
489 * @param out_flags Once the asynchronous operation completes, contains flags
490 * associated with the received data. For example, if the
491 * socket_base::message_end_of_record bit is set then the received data marks
492 * the end of a record. The caller must guarantee that the referenced
493 * variable remains valid until the handler is called.
494 *
495 * @param handler The handler to be called when the receive operation
496 * completes. Copies will be made of the handler as required. The function
497 * signature of the handler must be:
498 * @code void handler(
499 * const boost::system::error_code& error, // Result of operation.
500 * std::size_t bytes_transferred // Number of bytes received.
501 * ); @endcode
502 * Regardless of whether the asynchronous operation completes immediately or
503 * not, the handler will not be invoked from within this function. Invocation
504 * of the handler will be performed in a manner equivalent to using
505 * boost::asio::io_context::post().
506 *
507 * @par Example
508 * To receive into a single data buffer use the @ref buffer function as
509 * follows:
510 * @code
511 * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler);
512 * @endcode
513 * See the @ref buffer documentation for information on receiving into
514 * multiple buffers in one go, and how to use it with arrays, boost::array or
515 * std::vector.
516 */
517 template <typename MutableBufferSequence, typename ReadHandler>
518 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
519 void (boost::system::error_code, std::size_t))
520 async_receive(const MutableBufferSequence& buffers,
521 socket_base::message_flags& out_flags,
522 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
523 {
524 // If you get an error on the following line it means that your handler does
525 // not meet the documented type requirements for a ReadHandler.
526 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
527
528 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
529 return this->get_service().async_receive(
530 this->get_implementation(), buffers, 0, out_flags,
531 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
532 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
533 async_completion<ReadHandler,
534 void (boost::system::error_code, std::size_t)> init(handler);
535
536 this->get_service().async_receive_with_flags(
537 this->get_implementation(), buffers, 0, out_flags,
538 init.completion_handler);
539
540 return init.result.get();
541 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
542 }
543
544 /// Start an asynchronous receive.
545 /**
546 * This function is used to asynchronously receive data from the sequenced
547 * data socket. The function call always returns immediately.
548 *
549 * @param buffers One or more buffers into which the data will be received.
550 * Although the buffers object may be copied as necessary, ownership of the
551 * underlying memory blocks is retained by the caller, which must guarantee
552 * that they remain valid until the handler is called.
553 *
554 * @param in_flags Flags specifying how the receive call is to be made.
555 *
556 * @param out_flags Once the asynchronous operation completes, contains flags
557 * associated with the received data. For example, if the
558 * socket_base::message_end_of_record bit is set then the received data marks
559 * the end of a record. The caller must guarantee that the referenced
560 * variable remains valid until the handler is called.
561 *
562 * @param handler The handler to be called when the receive operation
563 * completes. Copies will be made of the handler as required. The function
564 * signature of the handler must be:
565 * @code void handler(
566 * const boost::system::error_code& error, // Result of operation.
567 * std::size_t bytes_transferred // Number of bytes received.
568 * ); @endcode
569 * Regardless of whether the asynchronous operation completes immediately or
570 * not, the handler will not be invoked from within this function. Invocation
571 * of the handler will be performed in a manner equivalent to using
572 * boost::asio::io_context::post().
573 *
574 * @par Example
575 * To receive into a single data buffer use the @ref buffer function as
576 * follows:
577 * @code
578 * socket.async_receive(
579 * boost::asio::buffer(data, size),
580 * 0, out_flags, handler);
581 * @endcode
582 * See the @ref buffer documentation for information on receiving into
583 * multiple buffers in one go, and how to use it with arrays, boost::array or
584 * std::vector.
585 */
586 template <typename MutableBufferSequence, typename ReadHandler>
587 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,
588 void (boost::system::error_code, std::size_t))
589 async_receive(const MutableBufferSequence& buffers,
590 socket_base::message_flags in_flags,
591 socket_base::message_flags& out_flags,
592 BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
593 {
594 // If you get an error on the following line it means that your handler does
595 // not meet the documented type requirements for a ReadHandler.
596 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
597
598 #if defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
599 return this->get_service().async_receive(
600 this->get_implementation(), buffers, in_flags, out_flags,
601 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
602 #else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
603 async_completion<ReadHandler,
604 void (boost::system::error_code, std::size_t)> init(handler);
605
606 this->get_service().async_receive_with_flags(
607 this->get_implementation(), buffers, in_flags, out_flags,
608 init.completion_handler);
609
610 return init.result.get();
611 #endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES)
612 }
613 };
614
615 } // namespace asio
616 } // namespace boost
617
618 #include <boost/asio/detail/pop_options.hpp>
619
620 #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP