13#include <boost/capy/buffers.hpp>
14#include <boost/capy/concept/io_awaitable.hpp>
15#include <boost/capy/continuation.hpp>
16#include <boost/capy/ex/io_env.hpp>
17#include <boost/capy/io_result.hpp>
21#include <memory_resource>
23#include <unordered_map>
29template <detail::TransferSequence TSeq, AnyBufferSequence BuffersTy>
33 using buf_iter_t =
decltype(boost::capy::begin(std::declval<BuffersTy const &>()));
34 using buffer_t = boost::capy::buffer_type<BuffersTy>;
38 uint8_t *
ptr{
nullptr};
50 std::pmr::unordered_map<libusb_transfer *, transfer_progress_t>
states;
53 boost::capy::continuation
cont;
64 self_t &self = *
static_cast<self_t *
>(tfer->user_data);
65 const auto resume_on_zero = [&] ()
67 if (self.await_state->in_flight == 0)
72 self.await_state->in_flight--;
75 std::unique_lock lock{self.await_state->mutex};
76 ok = (bool)self.await_state->ec;
85 if (tfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
87 for (
int i = 0; i < tfer->num_iso_packets; i++)
89 subtotal += tfer->iso_packet_desc[i].actual_length;
91 prg.
total += subtotal;
92 for (
int i = 0; i < tfer->num_iso_packets; i++)
94 if (tfer->status != LIBUSB_TRANSFER_COMPLETED) [[unlikely]]
97 std::unique_lock lock{self.await_state->mutex};
99 static_cast<status>(tfer->iso_packet_desc[i].status));
108 subtotal = tfer->actual_length;
109 prg.
total += subtotal;
111 if (tfer->status != LIBUSB_TRANSFER_COMPLETED) [[unlikely]]
114 std::unique_lock lock{self.await_state->mutex};
122 if (self.buf_current == self.buf_end) [[unlikely]]
129 prg.
ptr = (uint8_t *)buf.data();
131 tfer->buffer = prg.
ptr;
132 tfer->length = std::min(prg.
expected, self.single_transfer_limit);
137 tfer->buffer = prg.
ptr;
138 tfer->length = std::min(prg.
expected - prg.
total, self.single_transfer_limit);
140 int r = libusb_submit_transfer(tfer);
141 if (r != LIBUSB_SUCCESS) [[unlikely]]
144 std::unique_lock lock{self.await_state->mutex};
150 self.await_state->in_flight++;
163 assert((submission_size <= seq_view->size()) &&
164 "submission size must not be greater than number of transfers");
166 "submission size must not be greater than number of buffers");
175 boost::capy::io_env
const *io_env)
177 if (io_env->stop_token.stop_requested())
192 tfer->buffer = (uint8_t *)buf.data();
194 tfer->user_data =
this;
196 prg.
ptr = (uint8_t *)buf.data();
203 int r = libusb_submit_transfer(tfer);
204 if (r != LIBUSB_SUCCESS) [[unlikely]]
212 return std::noop_coroutine();
220 total += state.total;
235static_assert(boost::capy::IoAwaitable<
236 complete_sequence_awaitable<libusb_transfer *, boost::capy::mutable_buffer>>,
237 "Not a proper IoAwaitable");
238static_assert(boost::capy::IoAwaitable<complete_sequence_awaitable<std::vector<libusb_transfer *>,
239 boost::capy::const_buffer>>,
240 "Not a proper IoAwaitable");
Unified concept for buffer sequences.
constexpr auto transfer_of(Ty const &tfer_res) -> libusb_transfer *
Uniform accessor for obtaining a libusb_transfer * from a co_usb::transfer::detail::TransferResource.
Definition transfer_sequence.hpp:41
status
Status codes for transfers.
Definition status.hpp:22
Definition complete_io.hpp:21
std::error_code make_transfer_status(status e) noexcept
Definition status.hpp:74
usb_error
USB error enumeration.
Definition usb_error.hpp:20
std::error_code make_usb_error_code(usb_error e) noexcept
Definition usb_error.hpp:85
View of a certain transfer sequence. Provides a uniform range interface.
Status codes for transfers.
Definition complete_sequence_awaitable.hpp:44
boost::capy::continuation cont
Definition complete_sequence_awaitable.hpp:53
size_t in_flight
Definition complete_sequence_awaitable.hpp:58
std::error_code ec
Definition complete_sequence_awaitable.hpp:55
size_t err_idx
Definition complete_sequence_awaitable.hpp:56
await_state_t(std::pmr::memory_resource *memres)
Definition complete_sequence_awaitable.hpp:45
boost::capy::io_env const * io_env
Definition complete_sequence_awaitable.hpp:52
std::pmr::unordered_map< libusb_transfer *, transfer_progress_t > states
Definition complete_sequence_awaitable.hpp:50
std::mutex mutex
Definition complete_sequence_awaitable.hpp:49
Definition complete_sequence_awaitable.hpp:37
uint8_t * ptr
Definition complete_sequence_awaitable.hpp:38
size_t total
Definition complete_sequence_awaitable.hpp:40
size_t expected
Definition complete_sequence_awaitable.hpp:39
Definition complete_sequence_awaitable.hpp:31
size_t submission_size
Definition complete_sequence_awaitable.hpp:231
sequence_view< TSeq > * view
Definition complete_sequence_awaitable.hpp:226
std::coroutine_handle await_suspend(std::coroutine_handle<> h, boost::capy::io_env const *io_env)
Definition complete_sequence_awaitable.hpp:174
complete_sequence_awaitable(await_state_t *await_state, sequence_view< TSeq > *seq_view, BuffersTy const &buffers, size_t submission_size, size_t single_transfer_limit)
Definition complete_sequence_awaitable.hpp:153
await_state_t * await_state
Definition complete_sequence_awaitable.hpp:225
boost::capy::buffer_type< BuffersTy > buffer_t
Definition complete_sequence_awaitable.hpp:34
decltype(boost::capy::begin(std::declval< BuffersTy const & >())) buf_iter_t
Definition complete_sequence_awaitable.hpp:33
buf_iter_t buf_current
Definition complete_sequence_awaitable.hpp:228
static void transfer_callback(libusb_transfer *tfer)
Definition complete_sequence_awaitable.hpp:61
bool await_ready()
Definition complete_sequence_awaitable.hpp:169
size_t single_transfer_limit
Definition complete_sequence_awaitable.hpp:232
sequence_view< TSeq >::iterator_type tfer_iter_t
Definition complete_sequence_awaitable.hpp:32
buf_iter_t buf_end
Definition complete_sequence_awaitable.hpp:229
boost::capy::io_result< size_t > await_resume()
Definition complete_sequence_awaitable.hpp:215
View of a certain transfer sequence. Provides a uniform range interface.
Definition sequence_view.hpp:28
decltype(detail::transfer_begin(std::declval< Seq const & >())) iterator_type
Definition sequence_view.hpp:29
auto begin() const noexcept
Definition sequence_view.hpp:48
auto end() const noexcept
Definition sequence_view.hpp:53
Transfer resource and transfer sequence concepts.