File indexing completed on 2025-01-18 09:28:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP
0012 #define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_ACCEPT_OP_HPP
0013
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif
0017
0018 #include <boost/asio/detail/config.hpp>
0019 #include <boost/asio/detail/bind_handler.hpp>
0020 #include <boost/asio/detail/fenced_block.hpp>
0021 #include <boost/asio/detail/handler_alloc_helpers.hpp>
0022 #include <boost/asio/detail/handler_work.hpp>
0023 #include <boost/asio/detail/memory.hpp>
0024 #include <boost/asio/detail/reactor_op.hpp>
0025 #include <boost/asio/detail/socket_holder.hpp>
0026 #include <boost/asio/detail/socket_ops.hpp>
0027
0028 #include <boost/asio/detail/push_options.hpp>
0029
0030 namespace boost {
0031 namespace asio {
0032 namespace detail {
0033
0034 template <typename Socket, typename Protocol>
0035 class reactive_socket_accept_op_base : public reactor_op
0036 {
0037 public:
0038 reactive_socket_accept_op_base(const boost::system::error_code& success_ec,
0039 socket_type socket, socket_ops::state_type state, Socket& peer,
0040 const Protocol& protocol, typename Protocol::endpoint* peer_endpoint,
0041 func_type complete_func)
0042 : reactor_op(success_ec,
0043 &reactive_socket_accept_op_base::do_perform, complete_func),
0044 socket_(socket),
0045 state_(state),
0046 peer_(peer),
0047 protocol_(protocol),
0048 peer_endpoint_(peer_endpoint),
0049 addrlen_(peer_endpoint ? peer_endpoint->capacity() : 0)
0050 {
0051 }
0052
0053 static status do_perform(reactor_op* base)
0054 {
0055 BOOST_ASIO_ASSUME(base != 0);
0056 reactive_socket_accept_op_base* o(
0057 static_cast<reactive_socket_accept_op_base*>(base));
0058
0059 socket_type new_socket = invalid_socket;
0060 status result = socket_ops::non_blocking_accept(o->socket_,
0061 o->state_, o->peer_endpoint_ ? o->peer_endpoint_->data() : 0,
0062 o->peer_endpoint_ ? &o->addrlen_ : 0, o->ec_, new_socket)
0063 ? done : not_done;
0064 o->new_socket_.reset(new_socket);
0065
0066 BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_accept", o->ec_));
0067
0068 return result;
0069 }
0070
0071 void do_assign()
0072 {
0073 if (new_socket_.get() != invalid_socket)
0074 {
0075 if (peer_endpoint_)
0076 peer_endpoint_->resize(addrlen_);
0077 peer_.assign(protocol_, new_socket_.get(), ec_);
0078 if (!ec_)
0079 new_socket_.release();
0080 }
0081 }
0082
0083 private:
0084 socket_type socket_;
0085 socket_ops::state_type state_;
0086 socket_holder new_socket_;
0087 Socket& peer_;
0088 Protocol protocol_;
0089 typename Protocol::endpoint* peer_endpoint_;
0090 std::size_t addrlen_;
0091 };
0092
0093 template <typename Socket, typename Protocol,
0094 typename Handler, typename IoExecutor>
0095 class reactive_socket_accept_op :
0096 public reactive_socket_accept_op_base<Socket, Protocol>
0097 {
0098 public:
0099 typedef Handler handler_type;
0100 typedef IoExecutor io_executor_type;
0101
0102 BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_accept_op);
0103
0104 reactive_socket_accept_op(const boost::system::error_code& success_ec,
0105 socket_type socket, socket_ops::state_type state, Socket& peer,
0106 const Protocol& protocol, typename Protocol::endpoint* peer_endpoint,
0107 Handler& handler, const IoExecutor& io_ex)
0108 : reactive_socket_accept_op_base<Socket, Protocol>(
0109 success_ec, socket, state, peer, protocol, peer_endpoint,
0110 &reactive_socket_accept_op::do_complete),
0111 handler_(static_cast<Handler&&>(handler)),
0112 work_(handler_, io_ex)
0113 {
0114 }
0115
0116 static void do_complete(void* owner, operation* base,
0117 const boost::system::error_code& ,
0118 std::size_t )
0119 {
0120
0121 BOOST_ASIO_ASSUME(base != 0);
0122 reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base));
0123 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0124
0125
0126 if (owner)
0127 o->do_assign();
0128
0129 BOOST_ASIO_HANDLER_COMPLETION((*o));
0130
0131
0132 handler_work<Handler, IoExecutor> w(
0133 static_cast<handler_work<Handler, IoExecutor>&&>(
0134 o->work_));
0135
0136 BOOST_ASIO_ERROR_LOCATION(o->ec_);
0137
0138
0139
0140
0141
0142
0143
0144 detail::binder1<Handler, boost::system::error_code>
0145 handler(o->handler_, o->ec_);
0146 p.h = boost::asio::detail::addressof(handler.handler_);
0147 p.reset();
0148
0149
0150 if (owner)
0151 {
0152 fenced_block b(fenced_block::half);
0153 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
0154 w.complete(handler, handler.handler_);
0155 BOOST_ASIO_HANDLER_INVOCATION_END;
0156 }
0157 }
0158
0159 static void do_immediate(operation* base, bool, const void* io_ex)
0160 {
0161
0162 BOOST_ASIO_ASSUME(base != 0);
0163 reactive_socket_accept_op* o(static_cast<reactive_socket_accept_op*>(base));
0164 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0165
0166
0167 o->do_assign();
0168
0169 BOOST_ASIO_HANDLER_COMPLETION((*o));
0170
0171
0172 immediate_handler_work<Handler, IoExecutor> w(
0173 static_cast<handler_work<Handler, IoExecutor>&&>(
0174 o->work_));
0175
0176 BOOST_ASIO_ERROR_LOCATION(o->ec_);
0177
0178
0179
0180
0181
0182
0183
0184 detail::binder1<Handler, boost::system::error_code>
0185 handler(o->handler_, o->ec_);
0186 p.h = boost::asio::detail::addressof(handler.handler_);
0187 p.reset();
0188
0189 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_));
0190 w.complete(handler, handler.handler_, io_ex);
0191 BOOST_ASIO_HANDLER_INVOCATION_END;
0192 }
0193
0194 private:
0195 Handler handler_;
0196 handler_work<Handler, IoExecutor> work_;
0197 };
0198
0199 template <typename Protocol, typename PeerIoExecutor,
0200 typename Handler, typename IoExecutor>
0201 class reactive_socket_move_accept_op :
0202 private Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
0203 public reactive_socket_accept_op_base<
0204 typename Protocol::socket::template rebind_executor<PeerIoExecutor>::other,
0205 Protocol>
0206 {
0207 public:
0208 typedef Handler handler_type;
0209 typedef IoExecutor io_executor_type;
0210
0211 BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_move_accept_op);
0212
0213 reactive_socket_move_accept_op(const boost::system::error_code& success_ec,
0214 const PeerIoExecutor& peer_io_ex, socket_type socket,
0215 socket_ops::state_type state, const Protocol& protocol,
0216 typename Protocol::endpoint* peer_endpoint, Handler& handler,
0217 const IoExecutor& io_ex)
0218 : peer_socket_type(peer_io_ex),
0219 reactive_socket_accept_op_base<peer_socket_type, Protocol>(
0220 success_ec, socket, state, *this, protocol, peer_endpoint,
0221 &reactive_socket_move_accept_op::do_complete),
0222 handler_(static_cast<Handler&&>(handler)),
0223 work_(handler_, io_ex)
0224 {
0225 }
0226
0227 static void do_complete(void* owner, operation* base,
0228 const boost::system::error_code& ,
0229 std::size_t )
0230 {
0231
0232 BOOST_ASIO_ASSUME(base != 0);
0233 reactive_socket_move_accept_op* o(
0234 static_cast<reactive_socket_move_accept_op*>(base));
0235 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0236
0237
0238 if (owner)
0239 o->do_assign();
0240
0241 BOOST_ASIO_HANDLER_COMPLETION((*o));
0242
0243
0244 handler_work<Handler, IoExecutor> w(
0245 static_cast<handler_work<Handler, IoExecutor>&&>(
0246 o->work_));
0247
0248 BOOST_ASIO_ERROR_LOCATION(o->ec_);
0249
0250
0251
0252
0253
0254
0255
0256 detail::move_binder2<Handler,
0257 boost::system::error_code, peer_socket_type>
0258 handler(0, static_cast<Handler&&>(o->handler_), o->ec_,
0259 static_cast<peer_socket_type&&>(*o));
0260 p.h = boost::asio::detail::addressof(handler.handler_);
0261 p.reset();
0262
0263
0264 if (owner)
0265 {
0266 fenced_block b(fenced_block::half);
0267 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
0268 w.complete(handler, handler.handler_);
0269 BOOST_ASIO_HANDLER_INVOCATION_END;
0270 }
0271 }
0272
0273 static void do_immediate(operation* base, bool, const void* io_ex)
0274 {
0275
0276 BOOST_ASIO_ASSUME(base != 0);
0277 reactive_socket_move_accept_op* o(
0278 static_cast<reactive_socket_move_accept_op*>(base));
0279 ptr p = { boost::asio::detail::addressof(o->handler_), o, o };
0280
0281
0282 o->do_assign();
0283
0284 BOOST_ASIO_HANDLER_COMPLETION((*o));
0285
0286
0287 immediate_handler_work<Handler, IoExecutor> w(
0288 static_cast<handler_work<Handler, IoExecutor>&&>(
0289 o->work_));
0290
0291 BOOST_ASIO_ERROR_LOCATION(o->ec_);
0292
0293
0294
0295
0296
0297
0298
0299 detail::move_binder2<Handler,
0300 boost::system::error_code, peer_socket_type>
0301 handler(0, static_cast<Handler&&>(o->handler_), o->ec_,
0302 static_cast<peer_socket_type&&>(*o));
0303 p.h = boost::asio::detail::addressof(handler.handler_);
0304 p.reset();
0305
0306 BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, "..."));
0307 w.complete(handler, handler.handler_, io_ex);
0308 BOOST_ASIO_HANDLER_INVOCATION_END;
0309 }
0310
0311 private:
0312 typedef typename Protocol::socket::template
0313 rebind_executor<PeerIoExecutor>::other peer_socket_type;
0314
0315 Handler handler_;
0316 handler_work<Handler, IoExecutor> work_;
0317 };
0318
0319 }
0320 }
0321 }
0322
0323 #include <boost/asio/detail/pop_options.hpp>
0324
0325 #endif