include/boost/corosio/native/detail/uring/uring_file_service_base.hpp
100.0% Lines (30 / 30)
100.0% Functions (18 / 18)
Functions (18)
Function
Calls
Lines
Blocks
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::uring_file_service_base(boost::corosio::detail::uring_scheduler&)
:64
53x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::uring_file_service_base(boost::corosio::detail::uring_scheduler&)
:64
82x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::uring_file_service_base(boost::corosio::detail::uring_scheduler&)
:64
75x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::~uring_file_service_base()
:70
53x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::~uring_file_service_base()
:70
82x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::~uring_file_service_base()
:70
75x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::construct()
:72
59x
100.0%
71.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::construct()
:72
111x
100.0%
71.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::construct()
:72
103x
100.0%
71.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::destroy(boost::corosio::io_object::implementation*)
:84
53x
100.0%
70.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::destroy(boost::corosio::io_object::implementation*)
:84
106x
100.0%
70.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::destroy(boost::corosio::io_object::implementation*)
:84
102x
100.0%
70.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::close(boost::corosio::io_object::handle&)
:94
97x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::close(boost::corosio::io_object::handle&)
:94
199x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::close(boost::corosio::io_object::handle&)
:94
188x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_descriptor_service, boost::corosio::detail::descriptor_service, boost::corosio::detail::uring_descriptor>::shutdown()
:100
53x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_random_access_file_service, boost::corosio::detail::random_access_file_service, boost::corosio::detail::uring_random_access_file>::shutdown()
:100
82x
100.0%
100.0%
boost::corosio::detail::uring_file_service_base<boost::corosio::detail::uring_stream_file_service, boost::corosio::detail::file_service, boost::corosio::detail::uring_stream_file>::shutdown()
:100
75x
100.0%
100.0%
| Line | TLA | Hits | Source Code |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2026 Michael Vandeberg | ||
| 3 | // | ||
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
| 6 | // | ||
| 7 | // Official repository: https://github.com/cppalliance/corosio | ||
| 8 | // | ||
| 9 | |||
| 10 | #ifndef BOOST_COROSIO_NATIVE_DETAIL_URING_URING_FILE_SERVICE_BASE_HPP | ||
| 11 | #define BOOST_COROSIO_NATIVE_DETAIL_URING_URING_FILE_SERVICE_BASE_HPP | ||
| 12 | |||
| 13 | #include <boost/corosio/detail/platform.hpp> | ||
| 14 | |||
| 15 | #if BOOST_COROSIO_HAS_URING | ||
| 16 | |||
| 17 | #include <boost/corosio/detail/intrusive.hpp> | ||
| 18 | #include <boost/corosio/io/io_object.hpp> | ||
| 19 | #include <boost/corosio/native/detail/uring/uring_scheduler.hpp> | ||
| 20 | |||
| 21 | #include <memory> | ||
| 22 | #include <mutex> | ||
| 23 | #include <unordered_map> | ||
| 24 | |||
| 25 | /* | ||
| 26 | Shared lifecycle plumbing for io_uring file services. | ||
| 27 | |||
| 28 | uring_stream_file_service and uring_random_access_file_service were | ||
| 29 | byte-for-byte identical apart from the impl type and open_file's parameter | ||
| 30 | type: both make_shared the file impl from the scheduler, track it in an | ||
| 31 | intrusive list + raw->shared_ptr map, and close every file on shutdown. | ||
| 32 | This base factors that out; the concrete services add only open_file. | ||
| 33 | |||
| 34 | This is a separate base from uring_socket_service_base because file | ||
| 35 | services differ from socket services in three ways that match the reactor | ||
| 36 | socket service instead: they track via an intrusive list + map (sockets: | ||
| 37 | map only), they CLOSE files on shutdown (sockets: cancel only), and the | ||
| 38 | impl ctor takes just the scheduler (sockets: service + scheduler). See | ||
| 39 | tasks/proactor-dedup-decisions.md (#14). | ||
| 40 | |||
| 41 | Requirements on File: derive from enable_shared_from_this<File> and | ||
| 42 | intrusive_list<File>::node, a `File(uring_scheduler&)` constructor, and | ||
| 43 | a `void close_file() noexcept` method (cancel in-flight ops + close fd). | ||
| 44 | uring_descriptor_service reuses it too, as asio's file service reuses | ||
| 45 | its descriptor service. | ||
| 46 | |||
| 47 | @tparam Derived The concrete service (CRTP; unused today but kept for | ||
| 48 | symmetry / future hooks). | ||
| 49 | @tparam ServiceBase The abstract service vtable base (file_service, | ||
| 50 | random_access_file_service). | ||
| 51 | @tparam File The concrete io_uring file impl type. | ||
| 52 | */ | ||
| 53 | |||
| 54 | namespace boost::corosio::detail { | ||
| 55 | |||
| 56 | template<class Derived, class ServiceBase, class File> | ||
| 57 | class uring_file_service_base : public ServiceBase | ||
| 58 | { | ||
| 59 | friend Derived; | ||
| 60 | |||
| 61 | // Private CRTP ctor: only `Derived` (the concrete service, a friend) | ||
| 62 | // constructs the base — prevents inheriting with the wrong Derived | ||
| 63 | // (bugprone-crtp-constructor-accessibility). | ||
| 64 | 210x | explicit uring_file_service_base(uring_scheduler& sched) noexcept | |
| 65 | 210x | : sched_(&sched) | |
| 66 | { | ||
| 67 | 210x | } | |
| 68 | |||
| 69 | public: | ||
| 70 | 210x | ~uring_file_service_base() override = default; | |
| 71 | |||
| 72 | 273x | io_object::implementation* construct() override | |
| 73 | { | ||
| 74 | 273x | auto ptr = std::make_shared<File>(*sched_); | |
| 75 | 273x | auto* impl = ptr.get(); | |
| 76 | { | ||
| 77 | 273x | std::lock_guard<std::mutex> lock(mutex_); | |
| 78 | 273x | file_list_.push_back(impl); | |
| 79 | 273x | file_ptrs_[impl] = std::move(ptr); | |
| 80 | 273x | } | |
| 81 | 273x | return impl; | |
| 82 | 273x | } | |
| 83 | |||
| 84 | 261x | void destroy(io_object::implementation* p) override | |
| 85 | { | ||
| 86 | // close_file() already does cancel_and_flush(fd_) before ::close. | ||
| 87 | 261x | auto& impl = static_cast<File&>(*p); | |
| 88 | 261x | impl.close_file(); | |
| 89 | 261x | std::lock_guard<std::mutex> lock(mutex_); | |
| 90 | 261x | file_list_.remove(&impl); | |
| 91 | 261x | file_ptrs_.erase(&impl); | |
| 92 | 261x | } | |
| 93 | |||
| 94 | 484x | void close(io_object::handle& h) override | |
| 95 | { | ||
| 96 | 484x | if (h.get()) | |
| 97 | 484x | static_cast<File&>(*h.get()).close_file(); | |
| 98 | 484x | } | |
| 99 | |||
| 100 | 210x | void shutdown() override | |
| 101 | { | ||
| 102 | // file_ptrs_ is deliberately not cleared: the scheduler shuts | ||
| 103 | // down after this service and drains its completed ops, so | ||
| 104 | // every impl must outlive that drain. The map frees them when | ||
| 105 | // the service is destroyed. | ||
| 106 | 210x | std::lock_guard<std::mutex> lock(mutex_); | |
| 107 | 222x | for (auto* impl = file_list_.pop_front(); impl != nullptr; | |
| 108 | 12x | impl = file_list_.pop_front()) | |
| 109 | 12x | impl->close_file(); | |
| 110 | 210x | } | |
| 111 | |||
| 112 | /// Return the scheduler used by files created by this service. | ||
| 113 | uring_scheduler& scheduler() noexcept | ||
| 114 | { | ||
| 115 | return *sched_; | ||
| 116 | } | ||
| 117 | |||
| 118 | protected: | ||
| 119 | uring_scheduler* sched_; | ||
| 120 | std::mutex mutex_; | ||
| 121 | intrusive_list<File> file_list_; | ||
| 122 | std::unordered_map<File*, std::shared_ptr<File>> file_ptrs_; | ||
| 123 | |||
| 124 | private: | ||
| 125 | uring_file_service_base(uring_file_service_base const&) = delete; | ||
| 126 | uring_file_service_base& operator=(uring_file_service_base const&) = delete; | ||
| 127 | }; | ||
| 128 | |||
| 129 | } // namespace boost::corosio::detail | ||
| 130 | |||
| 131 | #endif // BOOST_COROSIO_HAS_URING | ||
| 132 | |||
| 133 | #endif // BOOST_COROSIO_NATIVE_DETAIL_URING_URING_FILE_SERVICE_BASE_HPP | ||
| 134 |