From 733ffffe44ad93bd81feddb0a8072510fd7a8321 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 6 Sep 2013 16:49:26 +0200 Subject: [PATCH] Make usbi_get_device_by_session_id return a ref to the found device Signed-off-by: Hans de Goede --- libusb/core.c | 2 +- libusb/libusbi.h | 4 ++-- libusb/os/darwin_usb.c | 6 +----- libusb/os/linux_usbfs.c | 5 ++++- libusb/os/netbsd_usb.c | 4 +--- libusb/os/openbsd_usb.c | 4 +--- libusb/os/wince_usb.c | 1 - libusb/os/windows_usb.c | 26 +++++++++++++++----------- libusb/version_nano.h | 2 +- 9 files changed, 26 insertions(+), 28 deletions(-) diff --git a/libusb/core.c b/libusb/core.c index e816284..72faac4 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -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); diff --git a/libusb/libusbi.h b/libusb/libusbi.h index bc608b9..a4d74f6 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h @@ -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 diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index 889c62a..d0350fb 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -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) { diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c index 142fa2b..f8defb8 100644 --- a/libusb/os/linux_usbfs.c +++ b/libusb/os/linux_usbfs.c @@ -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); } diff --git a/libusb/os/netbsd_usb.c b/libusb/os/netbsd_usb.c index 1e8d602..1da9e1e 100644 --- a/libusb/os/netbsd_usb.c +++ b/libusb/os/netbsd_usb.c @@ -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); diff --git a/libusb/os/openbsd_usb.c b/libusb/os/openbsd_usb.c index e1be242..01934ef 100644 --- a/libusb/os/openbsd_usb.c +++ b/libusb/os/openbsd_usb.c @@ -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); diff --git a/libusb/os/wince_usb.c b/libusb/os/wince_usb.c index 90c129b..c7ab7f6 100644 --- a/libusb/os/wince_usb.c +++ b/libusb/os/wince_usb.c @@ -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); diff --git a/libusb/os/windows_usb.c b/libusb/os/windows_usb.c index 1a9dae1..fdc60c7 100644 --- a/libusb/os/windows_usb.c +++ b/libusb/os/windows_usb.c @@ -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; } } diff --git a/libusb/version_nano.h b/libusb/version_nano.h index d8a3c31..995c478 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10833 +#define LIBUSB_NANO 10834 -- 2.11.4.GIT