Correct libusb usage on FreeBSD (#10736)

Change type of Handle on FreeBSD. On FreeBSD the libusb_hotplug_register_callback() function uses a pointer to a struct as a handle.

---------

Co-authored-by: Janek Bevendorff <janek@keepassxc.org>
This commit is contained in:
Guido Falsi 2024-06-19 22:50:56 +02:00 committed by GitHub
parent 5f2ee86d72
commit f4b91c17a9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 11 deletions

View File

@ -57,7 +57,7 @@ DeviceListener::registerHotplugCallback(bool arrived, bool left, int vendorId, i
void DeviceListener::deregisterHotplugCallback(Handle handle) void DeviceListener::deregisterHotplugCallback(Handle handle)
{ {
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS) #if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
m_listeners[0]->deregisterHotplugCallback(static_cast<int>(handle)); m_listeners[0]->deregisterHotplugCallback(handle);
#else #else
if (m_listeners.contains(handle)) { if (m_listeners.contains(handle)) {
m_listeners[handle]->deregisterHotplugCallback(); m_listeners[handle]->deregisterHotplugCallback();

View File

@ -20,6 +20,7 @@
#include <QPointer> #include <QPointer>
#include <QtConcurrent> #include <QtConcurrent>
#include <QtGlobal>
#include <libusb.h> #include <libusb.h>
DeviceListenerLibUsb::DeviceListenerLibUsb(QWidget* parent) DeviceListenerLibUsb::DeviceListenerLibUsb(QWidget* parent)
@ -49,7 +50,8 @@ namespace
} }
} // namespace } // namespace
int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int vendorId, int productId, const QUuid*) DeviceListenerLibUsb::Handle
DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int vendorId, int productId, const QUuid*)
{ {
if (!m_ctx) { if (!m_ctx) {
if (libusb_init(reinterpret_cast<libusb_context**>(&m_ctx)) != LIBUSB_SUCCESS) { if (libusb_init(reinterpret_cast<libusb_context**>(&m_ctx)) != LIBUSB_SUCCESS) {
@ -66,7 +68,8 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
events |= LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT; events |= LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
} }
int handle = 0; Handle handle = 0;
auto* handleNative = reinterpret_cast<libusb_hotplug_callback_handle*>(&handle);
const QPointer that = this; const QPointer that = this;
const int ret = libusb_hotplug_register_callback( const int ret = libusb_hotplug_register_callback(
static_cast<libusb_context*>(m_ctx), static_cast<libusb_context*>(m_ctx),
@ -77,14 +80,14 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
[](libusb_context* ctx, libusb_device* device, libusb_hotplug_event event, void* userData) -> int { [](libusb_context* ctx, libusb_device* device, libusb_hotplug_event event, void* userData) -> int {
if (!ctx) { if (!ctx) {
return 0; return true;
} }
emit static_cast<DeviceListenerLibUsb*>(userData)->devicePlugged( emit static_cast<DeviceListenerLibUsb*>(userData)->devicePlugged(
event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, ctx, device); event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, ctx, device);
return 0; return false;
}, },
that, that,
&handle); handleNative);
if (ret != LIBUSB_SUCCESS) { if (ret != LIBUSB_SUCCESS) {
qWarning("Failed to register USB listener callback."); qWarning("Failed to register USB listener callback.");
handle = 0; handle = 0;
@ -102,12 +105,17 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
return handle; return handle;
} }
void DeviceListenerLibUsb::deregisterHotplugCallback(int handle) void DeviceListenerLibUsb::deregisterHotplugCallback(Handle handle)
{ {
if (!m_ctx || !m_callbackHandles.contains(handle)) { if (!m_ctx || !m_callbackHandles.contains(handle)) {
return; return;
} }
libusb_hotplug_deregister_callback(static_cast<libusb_context*>(m_ctx), handle); #ifdef Q_OS_FREEBSD
auto* handleNative = reinterpret_cast<libusb_hotplug_callback_handle>(handle);
#else
auto handleNative = static_cast<libusb_hotplug_callback_handle>(handle);
#endif
libusb_hotplug_deregister_callback(static_cast<libusb_context*>(m_ctx), handleNative);
m_callbackHandles.remove(handle); m_callbackHandles.remove(handle);
if (m_callbackHandles.isEmpty() && m_usbEvents.isRunning()) { if (m_callbackHandles.isEmpty() && m_usbEvents.isRunning()) {

View File

@ -32,12 +32,14 @@ class DeviceListenerLibUsb : public QObject
Q_OBJECT Q_OBJECT
public: public:
typedef qintptr Handle;
explicit DeviceListenerLibUsb(QWidget* parent); explicit DeviceListenerLibUsb(QWidget* parent);
DeviceListenerLibUsb(const DeviceListenerLibUsb&) = delete; DeviceListenerLibUsb(const DeviceListenerLibUsb&) = delete;
~DeviceListenerLibUsb() override; ~DeviceListenerLibUsb() override;
int registerHotplugCallback(bool arrived, bool left, int vendorId = -1, int productId = -1, const QUuid* = nullptr); Handle
void deregisterHotplugCallback(int handle); registerHotplugCallback(bool arrived, bool left, int vendorId = -1, int productId = -1, const QUuid* = nullptr);
void deregisterHotplugCallback(Handle handle);
void deregisterAllHotplugCallbacks(); void deregisterAllHotplugCallbacks();
signals: signals:
@ -45,7 +47,7 @@ signals:
private: private:
void* m_ctx; void* m_ctx;
QSet<int> m_callbackHandles; QSet<Handle> m_callbackHandles;
QFuture<void> m_usbEvents; QFuture<void> m_usbEvents;
QAtomicInt m_completed; QAtomicInt m_completed;
}; };