]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/asio/detail/reactive_socket_accept_op.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / asio / detail / reactive_socket_accept_op.hpp
CommitLineData
7c673cae
FG
1//
2// detail/reactive_socket_accept_op.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4//
92f5a8d4 5// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7c673cae
FG
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_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP
12#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_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>
7c673cae
FG
19#include <boost/asio/detail/bind_handler.hpp>
20#include <boost/asio/detail/buffer_sequence_adapter.hpp>
21#include <boost/asio/detail/fenced_block.hpp>
b32b8144 22#include <boost/asio/detail/memory.hpp>
7c673cae
FG
23#include <boost/asio/detail/reactor_op.hpp>
24#include <boost/asio/detail/socket_holder.hpp>
25#include <boost/asio/detail/socket_ops.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31namespace detail {
32
33template <typename Socket, typename Protocol>
34class reactive_socket_accept_op_base : public reactor_op
35{
36public:
37 reactive_socket_accept_op_base(socket_type socket,
38 socket_ops::state_type state, Socket& peer, const Protocol& protocol,
39 typename Protocol::endpoint* peer_endpoint, func_type complete_func)
40 : reactor_op(&reactive_socket_accept_op_base::do_perform, complete_func),
41 socket_(socket),
42 state_(state),
43 peer_(peer),
44 protocol_(protocol),
b32b8144
FG
45 peer_endpoint_(peer_endpoint),
46 addrlen_(peer_endpoint ? peer_endpoint->capacity() : 0)
7c673cae
FG
47 {
48 }
49
b32b8144 50 static status do_perform(reactor_op* base)
7c673cae
FG
51 {
52 reactive_socket_accept_op_base* o(
53 static_cast<reactive_socket_accept_op_base*>(base));
54
7c673cae 55 socket_type new_socket = invalid_socket;
b32b8144
FG
56 status result = socket_ops::non_blocking_accept(o->socket_,
57 o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0,
58 o->peer_endpoint_ ? &o->addrlen_ : 0, o->ec_, new_socket)
59 ? done : not_done;
60 o->new_socket_.reset(new_socket);
7c673cae 61
b32b8144 62 BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_accept", o->ec_));
7c673cae
FG
63
64 return result;
65 }
66
b32b8144
FG
67 void do_assign()
68 {
69 if (new_socket_.get() != invalid_socket)
70 {
71 if (peer_endpoint_)
72 peer_endpoint_->resize(addrlen_);
73 peer_.assign(protocol_, new_socket_.get(), ec_);
74 if (!ec_)
75 new_socket_.release();
76 }
77 }
78
7c673cae
FG
79private:
80 socket_type socket_;
81 socket_ops::state_type state_;
b32b8144 82 socket_holder new_socket_;
7c673cae
FG
83 Socket& peer_;
84 Protocol protocol_;
85 typename Protocol::endpoint* peer_endpoint_;
b32b8144 86 std::size_t addrlen_;
7c673cae
FG
87};
88
92f5a8d4
TL
89template <typename Socket, typename Protocol,
90 typename Handler, typename IoExecutor>
7c673cae
FG
91class reactive_socket_accept_op :
92 public reactive_socket_accept_op_base<Socket, Protocol>
93{
94public:
95 BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op);
96
97 reactive_socket_accept_op(socket_type socket,
98 socket_ops::state_type state, Socket& peer, const Protocol& protocol,
92f5a8d4
TL
99 typename Protocol::endpoint* peer_endpoint, Handler& handler,
100 const IoExecutor& io_ex)
7c673cae
FG
101 : reactive_socket_accept_op_base<Socket, Protocol>(socket, state, peer,
102 protocol, peer_endpoint, &reactive_socket_accept_op::do_complete),
92f5a8d4
TL
103 handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
104 io_executor_(io_ex)
7c673cae 105 {
92f5a8d4 106 handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
7c673cae
FG
107 }
108
b32b8144 109 static void do_complete(void* owner, operation* base,
7c673cae
FG
110 const boost::system::error_code& /*ec*/,
111 std::size_t /*bytes_transferred*/)
112 {
113 // Take ownership of the handler object.
114 reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base));
115 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
92f5a8d4 116 handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
b32b8144
FG
117
118 // On success, assign new connection to peer socket object.
119 if (owner)
120 o->do_assign();
7c673cae 121
b32b8144 122 BOOST_ASIO_HANDLER_COMPLETION((*o));
7c673cae
FG
123
124 // Make a copy of the handler so that the memory can be deallocated before
125 // the upcall is made. Even if we're not about to make an upcall, a
126 // sub-object of the handler may be the true owner of the memory associated
127 // with the handler. Consequently, a local copy of the handler is required
128 // to ensure that any owning sub-object remains valid until after we have
129 // deallocated the memory here.
130 detail::binder1<Handler, boost::system::error_code>
131 handler(o->handler_, o->ec_);
132 p.h = boost::asio::detail::addressof(handler.handler_);
133 p.reset();
134
135 // Make the upcall if required.
136 if (owner)
137 {
138 fenced_block b(fenced_block::half);
139 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
b32b8144
FG
140 w.complete(handler, handler.handler_);
141 BOOST_ASIO_HANDLER_INVOCATION_END;
142 }
143 }
144
145private:
146 Handler handler_;
92f5a8d4 147 IoExecutor io_executor_;
b32b8144
FG
148};
149
150#if defined(BOOST_ASIO_HAS_MOVE)
151
92f5a8d4
TL
152template <typename Protocol, typename PeerIoExecutor,
153 typename Handler, typename IoExecutor>
b32b8144 154class reactive_socket_move_accept_op :
92f5a8d4
TL
155 private Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
156 public reactive_socket_accept_op_base<
157 typename Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
158 Protocol>
b32b8144
FG
159{
160public:
161 BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_move_accept_op);
162
92f5a8d4
TL
163 reactive_socket_move_accept_op(const PeerIoExecutor& peer_io_ex,
164 socket_type socket, socket_ops::state_type state,
165 const Protocol& protocol, typename Protocol::endpoint* peer_endpoint,
166 Handler& handler, const IoExecutor& io_ex)
167 : peer_socket_type(peer_io_ex),
168 reactive_socket_accept_op_base<peer_socket_type, Protocol>(
b32b8144
FG
169 socket, state, *this, protocol, peer_endpoint,
170 &reactive_socket_move_accept_op::do_complete),
92f5a8d4
TL
171 handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)),
172 io_executor_(io_ex)
b32b8144 173 {
92f5a8d4 174 handler_work<Handler, IoExecutor>::start(handler_, io_executor_);
b32b8144
FG
175 }
176
177 static void do_complete(void* owner, operation* base,
178 const boost::system::error_code& /*ec*/,
179 std::size_t /*bytes_transferred*/)
180 {
181 // Take ownership of the handler object.
182 reactive_socket_move_accept_op* o(
183 static_cast<reactive_socket_move_accept_op*>(base));
184 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
92f5a8d4 185 handler_work<Handler, IoExecutor> w(o->handler_, o->io_executor_);
b32b8144
FG
186
187 // On success, assign new connection to peer socket object.
188 if (owner)
189 o->do_assign();
190
191 BOOST_ASIO_HANDLER_COMPLETION((*o));
192
193 // Make a copy of the handler so that the memory can be deallocated before
194 // the upcall is made. Even if we're not about to make an upcall, a
195 // sub-object of the handler may be the true owner of the memory associated
196 // with the handler. Consequently, a local copy of the handler is required
197 // to ensure that any owning sub-object remains valid until after we have
198 // deallocated the memory here.
199 detail::move_binder2<Handler,
92f5a8d4 200 boost::system::error_code, peer_socket_type>
b32b8144 201 handler(0, BOOST_ASIO_MOVE_CAST(Handler)(o->handler_), o->ec_,
92f5a8d4 202 BOOST_ASIO_MOVE_CAST(peer_socket_type)(*o));
b32b8144
FG
203 p.h = boost::asio::detail::addressof(handler.handler_);
204 p.reset();
205
206 // Make the upcall if required.
207 if (owner)
208 {
209 fenced_block b(fenced_block::half);
210 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
211 w.complete(handler, handler.handler_);
7c673cae
FG
212 BOOST_ASIO_HANDLER_INVOCATION_END;
213 }
214 }
215
216private:
92f5a8d4
TL
217 typedef typename Protocol::socket::template
218 rebind_executor<PeerIoExecutor>::other peer_socket_type;
219
7c673cae 220 Handler handler_;
92f5a8d4 221 IoExecutor io_executor_;
7c673cae
FG
222};
223
b32b8144
FG
224#endif // defined(BOOST_ASIO_HAS_MOVE)
225
7c673cae
FG
226} // namespace detail
227} // namespace asio
228} // namespace boost
229
230#include <boost/asio/detail/pop_options.hpp>
231
232#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP