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