Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:28:32

0001 //
0002 // detail/io_uring_socket_service_base.ipp
0003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0004 //
0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
0006 //
0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0009 //
0010 
0011 #ifndef BOOST_ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP
0012 #define BOOST_ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP
0013 
0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
0015 # pragma once
0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
0017 
0018 #include <boost/asio/detail/config.hpp>
0019 
0020 #if defined(BOOST_ASIO_HAS_IO_URING)
0021 
0022 #include <boost/asio/detail/io_uring_socket_service_base.hpp>
0023 
0024 #include <boost/asio/detail/push_options.hpp>
0025 
0026 namespace boost {
0027 namespace asio {
0028 namespace detail {
0029 
0030 io_uring_socket_service_base::io_uring_socket_service_base(
0031     execution_context& context)
0032   : io_uring_service_(boost::asio::use_service<io_uring_service>(context))
0033 {
0034   io_uring_service_.init_task();
0035 }
0036 
0037 void io_uring_socket_service_base::base_shutdown()
0038 {
0039 }
0040 
0041 void io_uring_socket_service_base::construct(
0042     io_uring_socket_service_base::base_implementation_type& impl)
0043 {
0044   impl.socket_ = invalid_socket;
0045   impl.state_ = 0;
0046   impl.io_object_data_ = 0;
0047 }
0048 
0049 void io_uring_socket_service_base::base_move_construct(
0050     io_uring_socket_service_base::base_implementation_type& impl,
0051     io_uring_socket_service_base::base_implementation_type& other_impl)
0052   noexcept
0053 {
0054   impl.socket_ = other_impl.socket_;
0055   other_impl.socket_ = invalid_socket;
0056 
0057   impl.state_ = other_impl.state_;
0058   other_impl.state_ = 0;
0059 
0060   impl.io_object_data_ = other_impl.io_object_data_;
0061   other_impl.io_object_data_ = 0;
0062 }
0063 
0064 void io_uring_socket_service_base::base_move_assign(
0065     io_uring_socket_service_base::base_implementation_type& impl,
0066     io_uring_socket_service_base& /*other_service*/,
0067     io_uring_socket_service_base::base_implementation_type& other_impl)
0068 {
0069   destroy(impl);
0070 
0071   impl.socket_ = other_impl.socket_;
0072   other_impl.socket_ = invalid_socket;
0073 
0074   impl.state_ = other_impl.state_;
0075   other_impl.state_ = 0;
0076 
0077   impl.io_object_data_ = other_impl.io_object_data_;
0078   other_impl.io_object_data_ = 0;
0079 }
0080 
0081 void io_uring_socket_service_base::destroy(
0082     io_uring_socket_service_base::base_implementation_type& impl)
0083 {
0084   if (impl.socket_ != invalid_socket)
0085   {
0086     BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
0087           "socket", &impl, impl.socket_, "close"));
0088 
0089     io_uring_service_.deregister_io_object(impl.io_object_data_);
0090     boost::system::error_code ignored_ec;
0091     socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
0092     io_uring_service_.cleanup_io_object(impl.io_object_data_);
0093   }
0094 }
0095 
0096 boost::system::error_code io_uring_socket_service_base::close(
0097     io_uring_socket_service_base::base_implementation_type& impl,
0098     boost::system::error_code& ec)
0099 {
0100   if (is_open(impl))
0101   {
0102     BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
0103           "socket", &impl, impl.socket_, "close"));
0104 
0105     io_uring_service_.deregister_io_object(impl.io_object_data_);
0106     socket_ops::close(impl.socket_, impl.state_, false, ec);
0107     io_uring_service_.cleanup_io_object(impl.io_object_data_);
0108   }
0109   else
0110   {
0111     ec = success_ec_;
0112   }
0113 
0114   // The descriptor is closed by the OS even if close() returns an error.
0115   //
0116   // (Actually, POSIX says the state of the descriptor is unspecified. On
0117   // Linux the descriptor is apparently closed anyway; e.g. see
0118   //   http://lkml.org/lkml/2005/9/10/129
0119   construct(impl);
0120 
0121   return ec;
0122 }
0123 
0124 socket_type io_uring_socket_service_base::release(
0125     io_uring_socket_service_base::base_implementation_type& impl,
0126     boost::system::error_code& ec)
0127 {
0128   if (!is_open(impl))
0129   {
0130     ec = boost::asio::error::bad_descriptor;
0131     return invalid_socket;
0132   }
0133 
0134   BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
0135         "socket", &impl, impl.socket_, "release"));
0136 
0137   io_uring_service_.deregister_io_object(impl.io_object_data_);
0138   io_uring_service_.cleanup_io_object(impl.io_object_data_);
0139   socket_type sock = impl.socket_;
0140   construct(impl);
0141   ec = success_ec_;
0142   return sock;
0143 }
0144 
0145 boost::system::error_code io_uring_socket_service_base::cancel(
0146     io_uring_socket_service_base::base_implementation_type& impl,
0147     boost::system::error_code& ec)
0148 {
0149   if (!is_open(impl))
0150   {
0151     ec = boost::asio::error::bad_descriptor;
0152     return ec;
0153   }
0154 
0155   BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
0156         "socket", &impl, impl.socket_, "cancel"));
0157 
0158   io_uring_service_.cancel_ops(impl.io_object_data_);
0159   ec = success_ec_;
0160   return ec;
0161 }
0162 
0163 boost::system::error_code io_uring_socket_service_base::do_open(
0164     io_uring_socket_service_base::base_implementation_type& impl,
0165     int af, int type, int protocol, boost::system::error_code& ec)
0166 {
0167   if (is_open(impl))
0168   {
0169     ec = boost::asio::error::already_open;
0170     return ec;
0171   }
0172 
0173   socket_holder sock(socket_ops::socket(af, type, protocol, ec));
0174   if (sock.get() == invalid_socket)
0175     return ec;
0176 
0177   io_uring_service_.register_io_object(impl.io_object_data_);
0178 
0179   impl.socket_ = sock.release();
0180   switch (type)
0181   {
0182   case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
0183   case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
0184   default: impl.state_ = 0; break;
0185   }
0186   ec = success_ec_;
0187   return ec;
0188 }
0189 
0190 boost::system::error_code io_uring_socket_service_base::do_assign(
0191     io_uring_socket_service_base::base_implementation_type& impl, int type,
0192     const io_uring_socket_service_base::native_handle_type& native_socket,
0193     boost::system::error_code& ec)
0194 {
0195   if (is_open(impl))
0196   {
0197     ec = boost::asio::error::already_open;
0198     return ec;
0199   }
0200 
0201   io_uring_service_.register_io_object(impl.io_object_data_);
0202 
0203   impl.socket_ = native_socket;
0204   switch (type)
0205   {
0206   case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
0207   case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
0208   default: impl.state_ = 0; break;
0209   }
0210   impl.state_ |= socket_ops::possible_dup;
0211   ec = success_ec_;
0212   return ec;
0213 }
0214 
0215 void io_uring_socket_service_base::start_op(
0216     io_uring_socket_service_base::base_implementation_type& impl,
0217     int op_type, io_uring_operation* op, bool is_continuation, bool noop)
0218 {
0219   if (!noop)
0220   {
0221     io_uring_service_.start_op(op_type,
0222         impl.io_object_data_, op, is_continuation);
0223   }
0224   else
0225   {
0226     io_uring_service_.post_immediate_completion(op, is_continuation);
0227   }
0228 }
0229 
0230 void io_uring_socket_service_base::start_accept_op(
0231     io_uring_socket_service_base::base_implementation_type& impl,
0232     io_uring_operation* op, bool is_continuation, bool peer_is_open)
0233 {
0234   if (!peer_is_open)
0235     start_op(impl, io_uring_service::read_op, op, is_continuation, false);
0236   else
0237   {
0238     op->ec_ = boost::asio::error::already_open;
0239     io_uring_service_.post_immediate_completion(op, is_continuation);
0240   }
0241 }
0242 
0243 } // namespace detail
0244 } // namespace asio
0245 } // namespace boost
0246 
0247 #include <boost/asio/detail/pop_options.hpp>
0248 
0249 #endif // defined(BOOST_ASIO_HAS_IO_URING)
0250 
0251 #endif // BOOST_ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP