io_uring_socket_service_base.ipp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. //
  2. // detail/io_uring_socket_service_base.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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. #ifndef ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP
  11. #define ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #if defined(ASIO_HAS_IO_URING)
  17. #include "asio/detail/io_uring_socket_service_base.hpp"
  18. #include "asio/detail/push_options.hpp"
  19. namespace asio {
  20. namespace detail {
  21. io_uring_socket_service_base::io_uring_socket_service_base(
  22. execution_context& context)
  23. : io_uring_service_(asio::use_service<io_uring_service>(context))
  24. {
  25. io_uring_service_.init_task();
  26. }
  27. void io_uring_socket_service_base::base_shutdown()
  28. {
  29. }
  30. void io_uring_socket_service_base::construct(
  31. io_uring_socket_service_base::base_implementation_type& impl)
  32. {
  33. impl.socket_ = invalid_socket;
  34. impl.state_ = 0;
  35. impl.io_object_data_ = 0;
  36. }
  37. void io_uring_socket_service_base::base_move_construct(
  38. io_uring_socket_service_base::base_implementation_type& impl,
  39. io_uring_socket_service_base::base_implementation_type& other_impl)
  40. noexcept
  41. {
  42. impl.socket_ = other_impl.socket_;
  43. other_impl.socket_ = invalid_socket;
  44. impl.state_ = other_impl.state_;
  45. other_impl.state_ = 0;
  46. impl.io_object_data_ = other_impl.io_object_data_;
  47. other_impl.io_object_data_ = 0;
  48. }
  49. void io_uring_socket_service_base::base_move_assign(
  50. io_uring_socket_service_base::base_implementation_type& impl,
  51. io_uring_socket_service_base& /*other_service*/,
  52. io_uring_socket_service_base::base_implementation_type& other_impl)
  53. {
  54. destroy(impl);
  55. impl.socket_ = other_impl.socket_;
  56. other_impl.socket_ = invalid_socket;
  57. impl.state_ = other_impl.state_;
  58. other_impl.state_ = 0;
  59. impl.io_object_data_ = other_impl.io_object_data_;
  60. other_impl.io_object_data_ = 0;
  61. }
  62. void io_uring_socket_service_base::destroy(
  63. io_uring_socket_service_base::base_implementation_type& impl)
  64. {
  65. if (impl.socket_ != invalid_socket)
  66. {
  67. ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  68. "socket", &impl, impl.socket_, "close"));
  69. io_uring_service_.deregister_io_object(impl.io_object_data_);
  70. asio::error_code ignored_ec;
  71. socket_ops::close(impl.socket_, impl.state_, true, ignored_ec);
  72. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  73. }
  74. }
  75. asio::error_code io_uring_socket_service_base::close(
  76. io_uring_socket_service_base::base_implementation_type& impl,
  77. asio::error_code& ec)
  78. {
  79. if (is_open(impl))
  80. {
  81. ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  82. "socket", &impl, impl.socket_, "close"));
  83. io_uring_service_.deregister_io_object(impl.io_object_data_);
  84. socket_ops::close(impl.socket_, impl.state_, false, ec);
  85. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  86. }
  87. else
  88. {
  89. ec = success_ec_;
  90. }
  91. // The descriptor is closed by the OS even if close() returns an error.
  92. //
  93. // (Actually, POSIX says the state of the descriptor is unspecified. On
  94. // Linux the descriptor is apparently closed anyway; e.g. see
  95. // http://lkml.org/lkml/2005/9/10/129
  96. construct(impl);
  97. return ec;
  98. }
  99. socket_type io_uring_socket_service_base::release(
  100. io_uring_socket_service_base::base_implementation_type& impl,
  101. asio::error_code& ec)
  102. {
  103. if (!is_open(impl))
  104. {
  105. ec = asio::error::bad_descriptor;
  106. return invalid_socket;
  107. }
  108. ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  109. "socket", &impl, impl.socket_, "release"));
  110. io_uring_service_.deregister_io_object(impl.io_object_data_);
  111. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  112. socket_type sock = impl.socket_;
  113. construct(impl);
  114. ec = success_ec_;
  115. return sock;
  116. }
  117. asio::error_code io_uring_socket_service_base::cancel(
  118. io_uring_socket_service_base::base_implementation_type& impl,
  119. asio::error_code& ec)
  120. {
  121. if (!is_open(impl))
  122. {
  123. ec = asio::error::bad_descriptor;
  124. return ec;
  125. }
  126. ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  127. "socket", &impl, impl.socket_, "cancel"));
  128. io_uring_service_.cancel_ops(impl.io_object_data_);
  129. ec = success_ec_;
  130. return ec;
  131. }
  132. asio::error_code io_uring_socket_service_base::do_open(
  133. io_uring_socket_service_base::base_implementation_type& impl,
  134. int af, int type, int protocol, asio::error_code& ec)
  135. {
  136. if (is_open(impl))
  137. {
  138. ec = asio::error::already_open;
  139. return ec;
  140. }
  141. socket_holder sock(socket_ops::socket(af, type, protocol, ec));
  142. if (sock.get() == invalid_socket)
  143. return ec;
  144. io_uring_service_.register_io_object(impl.io_object_data_);
  145. impl.socket_ = sock.release();
  146. switch (type)
  147. {
  148. case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
  149. case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
  150. default: impl.state_ = 0; break;
  151. }
  152. ec = success_ec_;
  153. return ec;
  154. }
  155. asio::error_code io_uring_socket_service_base::do_assign(
  156. io_uring_socket_service_base::base_implementation_type& impl, int type,
  157. const io_uring_socket_service_base::native_handle_type& native_socket,
  158. asio::error_code& ec)
  159. {
  160. if (is_open(impl))
  161. {
  162. ec = asio::error::already_open;
  163. return ec;
  164. }
  165. io_uring_service_.register_io_object(impl.io_object_data_);
  166. impl.socket_ = native_socket;
  167. switch (type)
  168. {
  169. case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break;
  170. case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break;
  171. default: impl.state_ = 0; break;
  172. }
  173. impl.state_ |= socket_ops::possible_dup;
  174. ec = success_ec_;
  175. return ec;
  176. }
  177. void io_uring_socket_service_base::start_op(
  178. io_uring_socket_service_base::base_implementation_type& impl,
  179. int op_type, io_uring_operation* op, bool is_continuation, bool noop)
  180. {
  181. if (!noop)
  182. {
  183. io_uring_service_.start_op(op_type,
  184. impl.io_object_data_, op, is_continuation);
  185. }
  186. else
  187. {
  188. io_uring_service_.post_immediate_completion(op, is_continuation);
  189. }
  190. }
  191. void io_uring_socket_service_base::start_accept_op(
  192. io_uring_socket_service_base::base_implementation_type& impl,
  193. io_uring_operation* op, bool is_continuation, bool peer_is_open)
  194. {
  195. if (!peer_is_open)
  196. start_op(impl, io_uring_service::read_op, op, is_continuation, false);
  197. else
  198. {
  199. op->ec_ = asio::error::already_open;
  200. io_uring_service_.post_immediate_completion(op, is_continuation);
  201. }
  202. }
  203. } // namespace detail
  204. } // namespace asio
  205. #include "asio/detail/pop_options.hpp"
  206. #endif // defined(ASIO_HAS_IO_URING)
  207. #endif // ASIO_DETAIL_IMPL_IO_URING_SOCKET_SERVICE_BASE_IPP