[Spice-devel] [spice-gtk Win32 v5 13/22] Introduce SpiceUsbDeviceInfo to be kept instead of a libusb_device

Uri Lublin uril at redhat.com
Mon Jul 9 05:14:56 PDT 2012


For Windows, it's better not to keep references for libusb_devices
that are not used.
So instead of makeing SpiceUsbDevice a box for a libusb_device
it is going to be a box for a SpiceUsbDeviceInfo.
---
 gtk/usb-device-manager.c |  131 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 131 insertions(+), 0 deletions(-)

diff --git a/gtk/usb-device-manager.c b/gtk/usb-device-manager.c
index f77d09a..d4e947a 100644
--- a/gtk/usb-device-manager.c
+++ b/gtk/usb-device-manager.c
@@ -102,6 +102,16 @@ struct _SpiceUsbDeviceManagerPrivate {
 };
 
 #ifdef USE_USBREDIR
+
+typedef struct _SpiceUsbDeviceInfo {
+    guint8  busnum;
+    guint8  devaddr;
+    guint16 vid;
+    guint16 pid;
+    gint    ref;
+} SpiceUsbDeviceInfo;
+
+
 static void channel_new(SpiceSession *session, SpiceChannel *channel,
                         gpointer user_data);
 static void channel_destroy(SpiceSession *session, SpiceChannel *channel,
@@ -113,6 +123,12 @@ static void spice_usb_device_manager_uevent_cb(GUdevClient     *client,
 static void spice_usb_device_manager_add_dev(SpiceUsbDeviceManager  *self,
                                              GUdevDevice            *udev);
 
+static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev);
+static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device);
+static void spice_usb_device_unref(SpiceUsbDevice *device);
+
+static gboolean spice_usb_device_equal_libdev(SpiceUsbDevice *device,
+                                              libusb_device *libdev);
 G_DEFINE_BOXED_TYPE(SpiceUsbDevice, spice_usb_device,
                     (GBoxedCopyFunc)libusb_ref_device,
                     (GBoxedFreeFunc)libusb_unref_device)
@@ -1087,3 +1103,118 @@ gchar *spice_usb_device_get_description(SpiceUsbDevice *_device, const gchar *fo
     return NULL;
 #endif
 }
+
+
+
+#ifdef USE_USBREDIR
+/*
+ * SpiceUsbDeviceInfo
+ */
+static SpiceUsbDeviceInfo *spice_usb_device_new(libusb_device *libdev)
+{
+    SpiceUsbDeviceInfo *info;
+    struct libusb_device_descriptor desc;
+    int errcode;
+    const gchar *errstr;
+    guint8 bus, addr;
+
+    g_return_val_if_fail(libdev != NULL, NULL);
+
+    bus = libusb_get_bus_number(libdev);
+    addr = libusb_get_device_address(libdev);
+
+    errcode = libusb_get_device_descriptor(libdev, &desc);
+    if (errcode < 0) {
+        errstr = spice_usbutil_libusb_strerror(errcode);
+        g_warning("cannot get device descriptor for (%p) %d.%d -- %s(%d)",
+                  libdev, bus, addr, errstr, errcode);
+        return NULL;
+    }
+
+    info = g_new0(SpiceUsbDeviceInfo, 1);
+
+    info->busnum  = bus;
+    info->devaddr = addr;
+    info->vid = desc.idVendor;
+    info->pid = desc.idProduct;
+    info->ref = 1;
+
+    return info;
+}
+
+guint8 spice_usb_device_get_busnum(SpiceUsbDevice *device)
+{
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, 0);
+
+    return info->busnum;
+}
+
+guint8 spice_usb_device_get_devaddr(SpiceUsbDevice *device)
+{
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, 0);
+
+    return info->devaddr;
+}
+
+guint16 spice_usb_device_get_vid(SpiceUsbDevice *device)
+{
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, 0);
+
+    return info->vid;
+}
+
+guint16 spice_usb_device_get_pid(SpiceUsbDevice *device)
+{
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, 0);
+
+    return info->pid;
+}
+
+static SpiceUsbDevice *spice_usb_device_ref(SpiceUsbDevice *device)
+{
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_val_if_fail(info != NULL, NULL);
+    g_atomic_int_inc(&info->ref);
+    return device;
+}
+
+static void spice_usb_device_unref(SpiceUsbDevice *device)
+{
+    gboolean ref_count_is_0;
+
+    SpiceUsbDeviceInfo *info = (SpiceUsbDeviceInfo *)device;
+
+    g_return_if_fail(info != NULL);
+
+    ref_count_is_0 = g_atomic_int_dec_and_test(&info->ref);
+    if (ref_count_is_0) {
+        g_free(info);
+    }
+}
+
+static gboolean
+spice_usb_device_equal_libdev(SpiceUsbDevice *device,
+                              libusb_device  *libdev)
+{
+    guint8 addr1, addr2, bus1, bus2;
+
+    if ((device == NULL) || (libdev == NULL))
+        return FALSE;
+
+    bus1  = spice_usb_device_get_busnum(device);
+    addr1 = spice_usb_device_get_devaddr(device);
+    bus2  = libusb_get_bus_number(libdev);
+    addr2 = libusb_get_device_address(libdev);
+
+    return ((bus1 == bus2) && (addr1 == addr2));
+}
+#endif /* USE_USBREDIR */
-- 
1.7.1



More information about the Spice-devel mailing list