Make usbi_get_device_by_session_id return a ref to the found device
authorHans de Goede <hdegoede@redhat.com>
Fri, 6 Sep 2013 14:49:26 +0000 (16:49 +0200)
committerHans de Goede <hdegoede@redhat.com>
Fri, 6 Sep 2013 14:49:26 +0000 (16:49 +0200)
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
libusb/core.c
libusb/libusbi.h
libusb/os/darwin_usb.c
libusb/os/linux_usbfs.c
libusb/os/netbsd_usb.c
libusb/os/openbsd_usb.c
libusb/os/wince_usb.c
libusb/os/windows_usb.c
libusb/version_nano.h

index e816284..72faac4 100644 (file)
@@ -620,7 +620,7 @@ struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,
        usbi_mutex_lock(&ctx->usb_devs_lock);
        list_for_each_entry(dev, &ctx->usb_devs, list, struct libusb_device)
                if (dev->session_data == session_id) {
-                       ret = dev;
+                       ret = libusb_ref_device(dev);
                        break;
                }
        usbi_mutex_unlock(&ctx->usb_devs_lock);
index bc608b9..a4d74f6 100644 (file)
@@ -534,8 +534,8 @@ struct usbi_os_backend {
         *
         * After computing a session ID for a device, call
         * usbi_get_device_by_session_id(). This function checks if libusbx already
-        * knows about the device, and if so, it provides you with a libusb_device
-        * structure for it.
+        * knows about the device, and if so, it provides you with a reference
+        * to a libusb_device structure for it.
         *
         * If usbi_get_device_by_session_id() returns NULL, it is time to allocate
         * a new device structure for the device. Call usbi_alloc_device() to
index 889c62a..d0350fb 100644 (file)
@@ -293,6 +293,7 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
         /* signal the core that this device has been disconnected. the core will tear down this device
            when the reference count reaches 0 */
         usbi_disconnect_device(dev);
+        usb_unref_device(dev);
       }
     }
 
@@ -864,11 +865,6 @@ static int process_new_device (struct libusb_context *ctx, io_service_t service)
     dev->bus_number     = cached_device->location >> 24;
     dev->device_address = cached_device->address;
 
-    /* need to add a reference to the parent device */
-    if (dev->parent_dev) {
-      libusb_ref_device(dev->parent_dev);
-    }
-
     (*(priv->dev->device))->GetDeviceSpeed (priv->dev->device, &devSpeed);
 
     switch (devSpeed) {
index 142fa2b..f8defb8 100644 (file)
@@ -1048,9 +1048,11 @@ int linux_enumerate_device(struct libusb_context *ctx,
        usbi_dbg("busnum %d devaddr %d session_id %ld", busnum, devaddr,
                session_id);
 
-       if (usbi_get_device_by_session_id(ctx, session_id)) {
+       dev = usbi_get_device_by_session_id(ctx, session_id);
+       if (dev) {
                /* device already exists in the context */
                usbi_dbg("session_id %ld already exists", session_id);
+               libusb_unref_device(dev);
                return LIBUSB_SUCCESS;
        }
 
@@ -1101,6 +1103,7 @@ void linux_device_disconnected(uint8_t busnum, uint8_t devaddr, const char *sys_
                dev = usbi_get_device_by_session_id (ctx, session_id);
                if (NULL != dev) {
                        usbi_disconnect_device (dev);
+                       libusb_unref_device(dev);
                } else {
                        usbi_dbg("device not found for session %x", session_id);
                }
index 1e8d602..1da9e1e 100644 (file)
@@ -161,9 +161,7 @@ netbsd_get_device_list(struct libusb_context * ctx,
                session_id = (di.udi_bus << 8 | di.udi_addr);
                dev = usbi_get_device_by_session_id(ctx, session_id);
 
-               if (dev) {
-                       dev = libusb_ref_device(dev);
-               } else {
+               if (dev == NULL) {
                        dev = usbi_alloc_device(ctx, session_id);
                        if (dev == NULL)
                                return (LIBUSB_ERROR_NO_MEM);
index e1be242..01934ef 100644 (file)
@@ -186,9 +186,7 @@ obsd_get_device_list(struct libusb_context * ctx,
                        session_id = (di.udi_bus << 8 | di.udi_addr);
                        dev = usbi_get_device_by_session_id(ctx, session_id);
 
-                       if (dev) {
-                               dev = libusb_ref_device(dev);
-                       } else {
+                       if (dev == NULL) {
                                dev = usbi_alloc_device(ctx, session_id);
                                if (dev == NULL) {
                                        close(fd);
index 90c129b..c7ab7f6 100644 (file)
@@ -372,7 +372,6 @@ static int wince_get_device_list(
                if (dev) {
                        usbi_dbg("using existing device for %d/%d (session %ld)",
                                        bus_addr, dev_addr, session_id);
-                       libusb_ref_device(dev);
                        // Release just this element in the device list (as we already hold a 
                        // reference to it).
                        UkwReleaseDeviceList(driver_handle, &devices[i], 1);
index 1a9dae1..fdc60c7 100644 (file)
@@ -1103,8 +1103,10 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
                        if (tmp_dev->bus_number != 0) {
                                usbi_dbg("got bus number from ancestor #%d", i);
                                parent_dev->bus_number = tmp_dev->bus_number;
+                               libusb_unref_device(tmp_dev);
                                break;
                        }
+                       libusb_unref_device(tmp_dev);
                }
        }
        if (parent_dev->bus_number == 0) {
@@ -1116,7 +1118,7 @@ static int init_device(struct libusb_device* dev, struct libusb_device* parent_d
        dev->port_number = port_number;
        priv->depth = parent_priv->depth + 1;
        priv->parent_dev = parent_dev;
-       dev->parent_dev = libusb_ref_device(parent_dev);
+       dev->parent_dev = parent_dev;
 
        // If the device address is already set, we can stop here
        if (dev->device_address != 0) {
@@ -1537,6 +1539,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
                                parent_priv = _device_priv(parent_dev);
                                // virtual USB devices are also listed during GEN - don't process these yet
                                if ( (pass == GEN_PASS) && (parent_priv->apib->id != USB_API_HUB) ) {
+                                       libusb_unref_device(parent_dev);
                                        continue;
                                }
                                break;
@@ -1559,20 +1562,20 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
                                                LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
                                        }
                                        windows_device_priv_init(dev);
-                                       // Keep track of devices that need unref
-                                       unref_list[unref_cur++] = dev;
-                                       if (unref_cur >= unref_size) {
-                                               unref_size += 64;
-                                               unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
-                                               if (unref_list == NULL) {
-                                                       usbi_err(ctx, "could not realloc list for unref - aborting.");
-                                                       LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
-                                               }
-                                       }
                                } else {
                                        usbi_dbg("found existing device for session [%X] (%d.%d)",
                                                session_id, dev->bus_number, dev->device_address);
                                }
+                                // Keep track of devices that need unref
+                                unref_list[unref_cur++] = dev;
+                                if (unref_cur >= unref_size) {
+                                        unref_size += 64;
+                                        unref_list = usbi_reallocf(unref_list, unref_size*sizeof(libusb_device*));
+                                        if (unref_list == NULL) {
+                                                usbi_err(ctx, "could not realloc list for unref - aborting.");
+                                                LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
+                                        }
+                                }
                                priv = _device_priv(dev);
                        }
 
@@ -1658,6 +1661,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered
                                                break;
                                        }
                                }
+                               libusb_unref_device(parent_dev);
                                break;
                        }
                }
index d8a3c31..995c478 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10833
+#define LIBUSB_NANO 10834