io_uring_file_service.ipp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //
  2. // detail/impl/io_uring_file_service.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_FILE_SERVICE_IPP
  11. #define ASIO_DETAIL_IMPL_IO_URING_FILE_SERVICE_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_FILE) \
  17. && defined(ASIO_HAS_IO_URING)
  18. #include <cstring>
  19. #include <sys/stat.h>
  20. #include "asio/detail/io_uring_file_service.hpp"
  21. #include "asio/detail/push_options.hpp"
  22. namespace asio {
  23. namespace detail {
  24. io_uring_file_service::io_uring_file_service(
  25. execution_context& context)
  26. : execution_context_service_base<io_uring_file_service>(context),
  27. descriptor_service_(context)
  28. {
  29. }
  30. void io_uring_file_service::shutdown()
  31. {
  32. descriptor_service_.shutdown();
  33. }
  34. asio::error_code io_uring_file_service::open(
  35. io_uring_file_service::implementation_type& impl,
  36. const char* path, file_base::flags open_flags,
  37. asio::error_code& ec)
  38. {
  39. if (is_open(impl))
  40. {
  41. ec = asio::error::already_open;
  42. ASIO_ERROR_LOCATION(ec);
  43. return ec;
  44. }
  45. descriptor_ops::state_type state = 0;
  46. int fd = descriptor_ops::open(path, static_cast<int>(open_flags), 0777, ec);
  47. if (fd < 0)
  48. {
  49. ASIO_ERROR_LOCATION(ec);
  50. return ec;
  51. }
  52. // We're done. Take ownership of the serial port descriptor.
  53. if (descriptor_service_.assign(impl, fd, ec))
  54. {
  55. asio::error_code ignored_ec;
  56. descriptor_ops::close(fd, state, ignored_ec);
  57. }
  58. (void)::posix_fadvise(native_handle(impl), 0, 0,
  59. impl.is_stream_ ? POSIX_FADV_SEQUENTIAL : POSIX_FADV_RANDOM);
  60. ASIO_ERROR_LOCATION(ec);
  61. return ec;
  62. }
  63. uint64_t io_uring_file_service::size(
  64. const io_uring_file_service::implementation_type& impl,
  65. asio::error_code& ec) const
  66. {
  67. struct stat s;
  68. int result = ::fstat(native_handle(impl), &s);
  69. descriptor_ops::get_last_error(ec, result != 0);
  70. ASIO_ERROR_LOCATION(ec);
  71. return !ec ? s.st_size : 0;
  72. }
  73. asio::error_code io_uring_file_service::resize(
  74. io_uring_file_service::implementation_type& impl,
  75. uint64_t n, asio::error_code& ec)
  76. {
  77. int result = ::ftruncate(native_handle(impl), n);
  78. descriptor_ops::get_last_error(ec, result != 0);
  79. ASIO_ERROR_LOCATION(ec);
  80. return ec;
  81. }
  82. asio::error_code io_uring_file_service::sync_all(
  83. io_uring_file_service::implementation_type& impl,
  84. asio::error_code& ec)
  85. {
  86. int result = ::fsync(native_handle(impl));
  87. descriptor_ops::get_last_error(ec, result != 0);
  88. return ec;
  89. }
  90. asio::error_code io_uring_file_service::sync_data(
  91. io_uring_file_service::implementation_type& impl,
  92. asio::error_code& ec)
  93. {
  94. #if defined(_POSIX_SYNCHRONIZED_IO)
  95. int result = ::fdatasync(native_handle(impl));
  96. #else // defined(_POSIX_SYNCHRONIZED_IO)
  97. int result = ::fsync(native_handle(impl));
  98. #endif // defined(_POSIX_SYNCHRONIZED_IO)
  99. descriptor_ops::get_last_error(ec, result != 0);
  100. ASIO_ERROR_LOCATION(ec);
  101. return ec;
  102. }
  103. uint64_t io_uring_file_service::seek(
  104. io_uring_file_service::implementation_type& impl, int64_t offset,
  105. file_base::seek_basis whence, asio::error_code& ec)
  106. {
  107. int64_t result = ::lseek(native_handle(impl), offset, whence);
  108. descriptor_ops::get_last_error(ec, result < 0);
  109. ASIO_ERROR_LOCATION(ec);
  110. return !ec ? static_cast<uint64_t>(result) : 0;
  111. }
  112. } // namespace detail
  113. } // namespace asio
  114. #include "asio/detail/pop_options.hpp"
  115. #endif // defined(ASIO_HAS_FILE)
  116. // && defined(ASIO_HAS_IO_URING)
  117. #endif // ASIO_DETAIL_IMPL_IO_URING_FILE_SERVICE_IPP