io_uring_descriptor_service.ipp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. //
  2. // detail/impl/io_uring_descriptor_service.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 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 BOOST_ASIO_DETAIL_IMPL_IO_URING_DESCRIPTOR_SERVICE_IPP
  11. #define BOOST_ASIO_DETAIL_IMPL_IO_URING_DESCRIPTOR_SERVICE_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #if defined(BOOST_ASIO_HAS_IO_URING)
  17. #include <boost/asio/error.hpp>
  18. #include <boost/asio/detail/io_uring_descriptor_service.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. namespace detail {
  23. io_uring_descriptor_service::io_uring_descriptor_service(
  24. execution_context& context)
  25. : execution_context_service_base<io_uring_descriptor_service>(context),
  26. io_uring_service_(boost::asio::use_service<io_uring_service>(context))
  27. {
  28. io_uring_service_.init_task();
  29. }
  30. void io_uring_descriptor_service::shutdown()
  31. {
  32. }
  33. void io_uring_descriptor_service::construct(
  34. io_uring_descriptor_service::implementation_type& impl)
  35. {
  36. impl.descriptor_ = -1;
  37. impl.state_ = 0;
  38. impl.io_object_data_ = 0;
  39. }
  40. void io_uring_descriptor_service::move_construct(
  41. io_uring_descriptor_service::implementation_type& impl,
  42. io_uring_descriptor_service::implementation_type& other_impl)
  43. noexcept
  44. {
  45. impl.descriptor_ = other_impl.descriptor_;
  46. other_impl.descriptor_ = -1;
  47. impl.state_ = other_impl.state_;
  48. other_impl.state_ = 0;
  49. impl.io_object_data_ = other_impl.io_object_data_;
  50. other_impl.io_object_data_ = 0;
  51. }
  52. void io_uring_descriptor_service::move_assign(
  53. io_uring_descriptor_service::implementation_type& impl,
  54. io_uring_descriptor_service& /*other_service*/,
  55. io_uring_descriptor_service::implementation_type& other_impl)
  56. {
  57. destroy(impl);
  58. impl.descriptor_ = other_impl.descriptor_;
  59. other_impl.descriptor_ = -1;
  60. impl.state_ = other_impl.state_;
  61. other_impl.state_ = 0;
  62. impl.io_object_data_ = other_impl.io_object_data_;
  63. other_impl.io_object_data_ = 0;
  64. }
  65. void io_uring_descriptor_service::destroy(
  66. io_uring_descriptor_service::implementation_type& impl)
  67. {
  68. if (is_open(impl))
  69. {
  70. BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  71. "descriptor", &impl, impl.descriptor_, "close"));
  72. io_uring_service_.deregister_io_object(impl.io_object_data_);
  73. boost::system::error_code ignored_ec;
  74. descriptor_ops::close(impl.descriptor_, impl.state_, ignored_ec);
  75. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  76. }
  77. }
  78. boost::system::error_code io_uring_descriptor_service::assign(
  79. io_uring_descriptor_service::implementation_type& impl,
  80. const native_handle_type& native_descriptor, boost::system::error_code& ec)
  81. {
  82. if (is_open(impl))
  83. {
  84. ec = boost::asio::error::already_open;
  85. BOOST_ASIO_ERROR_LOCATION(ec);
  86. return ec;
  87. }
  88. io_uring_service_.register_io_object(impl.io_object_data_);
  89. impl.descriptor_ = native_descriptor;
  90. impl.state_ = descriptor_ops::possible_dup;
  91. ec = success_ec_;
  92. return ec;
  93. }
  94. boost::system::error_code io_uring_descriptor_service::close(
  95. io_uring_descriptor_service::implementation_type& impl,
  96. boost::system::error_code& ec)
  97. {
  98. if (is_open(impl))
  99. {
  100. BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  101. "descriptor", &impl, impl.descriptor_, "close"));
  102. io_uring_service_.deregister_io_object(impl.io_object_data_);
  103. descriptor_ops::close(impl.descriptor_, impl.state_, ec);
  104. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  105. }
  106. else
  107. {
  108. ec = success_ec_;
  109. }
  110. // The descriptor is closed by the OS even if close() returns an error.
  111. //
  112. // (Actually, POSIX says the state of the descriptor is unspecified. On
  113. // Linux the descriptor is apparently closed anyway; e.g. see
  114. // http://lkml.org/lkml/2005/9/10/129
  115. construct(impl);
  116. BOOST_ASIO_ERROR_LOCATION(ec);
  117. return ec;
  118. }
  119. io_uring_descriptor_service::native_handle_type
  120. io_uring_descriptor_service::release(
  121. io_uring_descriptor_service::implementation_type& impl)
  122. {
  123. native_handle_type descriptor = impl.descriptor_;
  124. if (is_open(impl))
  125. {
  126. BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  127. "descriptor", &impl, impl.descriptor_, "release"));
  128. io_uring_service_.deregister_io_object(impl.io_object_data_);
  129. io_uring_service_.cleanup_io_object(impl.io_object_data_);
  130. construct(impl);
  131. }
  132. return descriptor;
  133. }
  134. boost::system::error_code io_uring_descriptor_service::cancel(
  135. io_uring_descriptor_service::implementation_type& impl,
  136. boost::system::error_code& ec)
  137. {
  138. if (!is_open(impl))
  139. {
  140. ec = boost::asio::error::bad_descriptor;
  141. BOOST_ASIO_ERROR_LOCATION(ec);
  142. return ec;
  143. }
  144. BOOST_ASIO_HANDLER_OPERATION((io_uring_service_.context(),
  145. "descriptor", &impl, impl.descriptor_, "cancel"));
  146. io_uring_service_.cancel_ops(impl.io_object_data_);
  147. ec = success_ec_;
  148. return ec;
  149. }
  150. void io_uring_descriptor_service::start_op(
  151. io_uring_descriptor_service::implementation_type& impl,
  152. int op_type, io_uring_operation* op, bool is_continuation, bool noop)
  153. {
  154. if (!noop)
  155. {
  156. io_uring_service_.start_op(op_type,
  157. impl.io_object_data_, op, is_continuation);
  158. }
  159. else
  160. {
  161. io_uring_service_.post_immediate_completion(op, is_continuation);
  162. }
  163. }
  164. } // namespace detail
  165. } // namespace asio
  166. } // namespace boost
  167. #include <boost/asio/detail/pop_options.hpp>
  168. #endif // defined(BOOST_ASIO_HAS_IO_URING)
  169. #endif // BOOST_ASIO_DETAIL_IMPL_IO_URING_DESCRIPTOR_SERVICE_IPP