From 707d500b9fea002f075cf30458a602f28dbd1348 Mon Sep 17 00:00:00 2001 From: Nathan Hjelm Date: Tue, 23 Jul 2013 20:56:37 -0600 Subject: keep a reference to the device for each active transfer and let the backend handle cancelling active transfers when a device is disconnected This commit should fix issues with active transfers when a device is disconnected. The backend is responsible for making sure the completion callbacks are made, not the hotplug code. This should fix a number of issues including duplicate callbacks and segmentation faults. References #124. --- libusb/hotplug.c | 13 +------------ libusb/io.c | 3 +++ libusb/version_nano.h | 2 +- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/libusb/hotplug.c b/libusb/hotplug.c index 36a8f05..ec91162 100644 --- a/libusb/hotplug.c +++ b/libusb/hotplug.c @@ -191,18 +191,7 @@ void usbi_hotplug_match(struct libusb_context *ctx, struct libusb_device *dev, usbi_mutex_unlock(&ctx->hotplug_cbs_lock); - /* loop through and disconnect all open handles for this device */ - if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) { - struct libusb_device_handle *handle; - - usbi_mutex_lock(&ctx->open_devs_lock); - list_for_each_entry(handle, &ctx->open_devs, list, struct libusb_device_handle) { - if (dev == handle->dev) { - usbi_handle_disconnect (handle); - } - } - usbi_mutex_unlock(&ctx->open_devs_lock); - } + /* the backend is expected to call the callback for each active transfer */ } int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx, diff --git a/libusb/io.c b/libusb/io.c index 4368b99..8438e77 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1459,6 +1459,8 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer) } usbi_mutex_unlock(&ctx->flying_transfers_lock); + /* keep a reference to this device */ + libusb_ref_device(transfer->dev_handle->dev); out: updated_fds = (itransfer->flags & USBI_TRANSFER_UPDATED_FDS); usbi_mutex_unlock(&itransfer->lock); @@ -1562,6 +1564,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, usbi_mutex_lock(&ctx->event_waiters_lock); usbi_cond_broadcast(&ctx->event_waiters_cond); usbi_mutex_unlock(&ctx->event_waiters_lock); + libusb_unref_device(transfer->dev_handle->dev); return 0; } diff --git a/libusb/version_nano.h b/libusb/version_nano.h index f84521e..ebf41e1 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 10775 +#define LIBUSB_NANO 10776 -- cgit v1.2.3