summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Hjelm <hjelmn@me.com>2013-07-23 20:56:37 -0600
committerhjelmn <Nathan Hjelm hjelmn@cs.unm.edu>2013-07-30 09:08:39 -0600
commit707d500b9fea002f075cf30458a602f28dbd1348 (patch)
tree8cd9ad3ad15d2dd9ca610347c08f4115f3deedc3
parent97958ba756b2f90aa9f65cc7674bc558768dde9f (diff)
downloadlibusb-707d500b9fea002f075cf30458a602f28dbd1348.tar.gz
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.
-rw-r--r--libusb/hotplug.c13
-rw-r--r--libusb/io.c3
-rw-r--r--libusb/version_nano.h2
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