Skip to content

Commit

Permalink
Correct libusb usage on FreeBSD (#10736)
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
madpilot78 and phoerious authored Jun 19, 2024
1 parent 5f2ee86 commit f4b91c1
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/gui/osutils/DeviceListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ DeviceListener::registerHotplugCallback(bool arrived, bool left, int vendorId, i
void DeviceListener::deregisterHotplugCallback(Handle handle)
{
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
m_listeners[0]->deregisterHotplugCallback(static_cast<int>(handle));
m_listeners[0]->deregisterHotplugCallback(handle);
#else
if (m_listeners.contains(handle)) {
m_listeners[handle]->deregisterHotplugCallback();
Expand Down
22 changes: 15 additions & 7 deletions src/gui/osutils/nixutils/DeviceListenerLibUsb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <QPointer>
#include <QtConcurrent>
#include <QtGlobal>
#include <libusb.h>

DeviceListenerLibUsb::DeviceListenerLibUsb(QWidget* parent)
Expand Down Expand Up @@ -49,7 +50,8 @@ 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 (libusb_init(reinterpret_cast<libusb_context**>(&m_ctx)) != LIBUSB_SUCCESS) {
Expand All @@ -66,7 +68,8 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
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 int ret = libusb_hotplug_register_callback(
static_cast<libusb_context*>(m_ctx),
Expand All @@ -77,14 +80,14 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
LIBUSB_HOTPLUG_MATCH_ANY,
[](libusb_context* ctx, libusb_device* device, libusb_hotplug_event event, void* userData) -> int {
if (!ctx) {
return 0;
return true;
}
emit static_cast<DeviceListenerLibUsb*>(userData)->devicePlugged(
event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, ctx, device);
return 0;
return false;
},
that,
&handle);
handleNative);
if (ret != LIBUSB_SUCCESS) {
qWarning("Failed to register USB listener callback.");
handle = 0;
Expand All @@ -102,12 +105,17 @@ int DeviceListenerLibUsb::registerHotplugCallback(bool arrived, bool left, int v
return handle;
}

void DeviceListenerLibUsb::deregisterHotplugCallback(int handle)
void DeviceListenerLibUsb::deregisterHotplugCallback(Handle handle)
{
if (!m_ctx || !m_callbackHandles.contains(handle)) {
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);

if (m_callbackHandles.isEmpty() && m_usbEvents.isRunning()) {
Expand Down
8 changes: 5 additions & 3 deletions src/gui/osutils/nixutils/DeviceListenerLibUsb.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,22 @@ class DeviceListenerLibUsb : public QObject
Q_OBJECT

public:
typedef qintptr Handle;
explicit DeviceListenerLibUsb(QWidget* parent);
DeviceListenerLibUsb(const DeviceListenerLibUsb&) = delete;
~DeviceListenerLibUsb() override;

int registerHotplugCallback(bool arrived, bool left, int vendorId = -1, int productId = -1, const QUuid* = nullptr);
void deregisterHotplugCallback(int handle);
Handle
registerHotplugCallback(bool arrived, bool left, int vendorId = -1, int productId = -1, const QUuid* = nullptr);
void deregisterHotplugCallback(Handle handle);
void deregisterAllHotplugCallbacks();

signals:
void devicePlugged(bool state, void* ctx, void* device);

private:
void* m_ctx;
QSet<int> m_callbackHandles;
QSet<Handle> m_callbackHandles;
QFuture<void> m_usbEvents;
QAtomicInt m_completed;
};
Expand Down

0 comments on commit f4b91c1

Please sign in to comment.