co_usb
Loading...
Searching...
No Matches
handler_service.hpp
Go to the documentation of this file.
1
6#pragma once
7
11#include "co_usb/usb_error.hpp"
12#include <boost/capy/ex/execution_context.hpp>
13#include <boost/capy/ex/executor_ref.hpp>
14#include <concepts>
15#include <libusb.h>
16#include <span>
17#include <stdexcept>
18#include <stop_token>
19#include <system_error>
20#include <utility>
21
22namespace co_usb
23{
24struct context;
25}
26
27namespace co_usb::ev::detail
28{
29
73struct handler_service : public boost::capy::execution_context::service
74{
75 friend struct co_usb::context;
76
81 explicit handler_service (boost::capy::execution_context &exec_ctx)
82 : boost::capy::execution_context::service{}, m_handler{}
83 {
84 }
85
91 ~handler_service () override
92 {
93 shutdown();
94 libusb_exit(m_usb_ctx);
95 }
96
102 auto init_context () noexcept -> std::error_code
103 {
104 libusb_context *ctx;
105 auto r = libusb_init(&ctx);
106 if (r != LIBUSB_SUCCESS)
107 {
108 return make_usb_error_code(static_cast<usb_error>(r));
109 }
110 if (m_usb_ctx)
111 {
112 libusb_exit(m_usb_ctx);
113 }
114 m_usb_ctx = ctx;
115 return {};
116 }
117
123 auto init_context (std::span<const libusb_init_option> options) noexcept -> std::error_code
124 {
125 libusb_context *ctx;
126 auto r = libusb_init_context(&ctx, options.data(), options.size());
127 if (r != LIBUSB_SUCCESS)
128 {
129 return make_usb_error_code(static_cast<usb_error>(r));
130 }
131 if (m_usb_ctx)
132 {
133 libusb_exit(m_usb_ctx);
134 }
135 m_usb_ctx = ctx;
136 return {};
137 }
138
158 template <detail::EventHandler HandlerTy, typename... Args>
159 requires(!std::same_as<HandlerTy, any_event_handler> &&
160 !std::same_as<HandlerTy, event_handler_ref> &&
161 std::constructible_from<HandlerTy, Args...>)
162 auto emplace_handler (Args &&...args,
163 std::pmr::memory_resource *memres = std::pmr::get_default_resource())
165 {
166 if (m_handler.valid())
167 {
168 m_stop.request_stop();
169 m_handler.stop();
170 m_stop = std::stop_source{};
171 }
172 m_handler.emplace<HandlerTy>(memres, std::forward<Args>(args)...);
173 return m_handler;
174 }
175
180 auto get_token () const noexcept -> std::stop_token
181 {
182 return m_stop.get_token();
183 }
184
192 {
193 libusb_interrupt_event_handler(m_usb_ctx);
194 m_stop.request_stop();
195 }
196
202 {
203 return m_handler;
204 }
205
210 auto start () -> bool
211 {
212 return m_handler.start(m_usb_ctx, m_stop.get_token());
213 }
214
220 auto shutdown () -> void override
221 {
222 m_stop.request_stop();
223 m_handler.stop();
224 }
225
230 auto usb_context () -> libusb_context *
231 {
232 return m_usb_ctx;
233 }
234
235 private:
236 any_event_handler m_handler;
237 std::stop_source m_stop;
238 libusb_context *m_usb_ctx{nullptr};
239};
240
248inline auto get_handler_service (boost::capy::executor_ref exec) -> handler_service &
249{
250 handler_service *srv = exec.context().find_service<handler_service>();
251 if (!srv)
252 throw std::runtime_error{"co_usb handler service is not present"};
253 return *srv;
254}
255
263inline auto nothrow_get_handler_service (boost::capy::executor_ref exec) -> handler_service *
264{
265 handler_service *srv = exec.context().find_service<handler_service>();
266 return srv;
267}
268
269} // namespace co_usb::ev::detail
Owning type-erased wrapper for EventHandler.
Concept defining an event handler for libusb.
Definition event_handler.hpp:42
Specification and implementation of EventHandler concept.
Type-erased reference to any event handler.
Definition event_handler.hpp:13
auto get_handler_service(boost::capy::executor_ref exec) -> handler_service &
Retrieve the handler_service from a given executor.
Definition handler_service.hpp:248
auto nothrow_get_handler_service(boost::capy::executor_ref exec) -> handler_service *
Retrieve the handler_service from a given executor.
Definition handler_service.hpp:263
Definition flag_type.hpp:6
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
Definition status.hpp:87
Owning type-erased wrapper for EventHandler.
Definition any_event_handler.hpp:31
auto start(libusb_context *usb_ctx, std::stop_token stop) -> bool
Definition any_event_handler.hpp:112
auto emplace(std::pmr::memory_resource *memres, Args &&...args)
Definition any_event_handler.hpp:62
auto stop() -> void
Definition any_event_handler.hpp:139
auto valid() const noexcept -> bool
Definition any_event_handler.hpp:107
Execution context service that owns a libusb context and an event handler.
Definition handler_service.hpp:74
auto init_context() noexcept -> std::error_code
Initializes libusb context without options.
Definition handler_service.hpp:102
auto get_token() const noexcept -> std::stop_token
Get the stop token used for coordinating shutdown.
Definition handler_service.hpp:180
handler_service(boost::capy::execution_context &exec_ctx)
Construct the handler service.
Definition handler_service.hpp:81
~handler_service() override
Destructor that stops the handler and releases the libusb context.
Definition handler_service.hpp:91
auto shutdown() -> void override
Shutdown hook invoked by the base service.
Definition handler_service.hpp:220
auto init_context(std::span< const libusb_init_option > options) noexcept -> std::error_code
Initializes libusb context with given options.
Definition handler_service.hpp:123
auto emplace_handler(Args &&...args, std::pmr::memory_resource *memres=std::pmr::get_default_resource()) -> event_handler_ref
Emplace a concrete event handler and return a reference wrapper.
Definition handler_service.hpp:162
auto handler() -> event_handler_ref
Get a reference to the stored event handler.
Definition handler_service.hpp:201
auto usb_context() -> libusb_context *
Access the underlying libusb context.
Definition handler_service.hpp:230
auto request_stop()
Request stop for the event handler.
Definition handler_service.hpp:191
friend struct co_usb::context
Definition handler_service.hpp:75
auto start() -> bool
Start the stored event handler.
Definition handler_service.hpp:210
Type-erased reference to any event handler.
Definition event_handler_ref.hpp:34
USB error enumeration.