summaryrefslogtreecommitdiff
path: root/libusb/core.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-10-15 15:30:02 +0200
committerHans de Goede <hdegoede@redhat.com>2013-11-20 13:21:37 +0100
commit15ee9598454f0c3b6221f45d36c38fb474af74df (patch)
tree4c166b2cfc8414a7bae83d9435f5de46caf60f50 /libusb/core.c
parent359a273b36d810e0fda4117a3131116350db822b (diff)
downloadlibusb-15ee9598454f0c3b6221f45d36c38fb474af74df.tar.gz
hotplug: Fix usb_device memleak with hotunplug events pending on libusb_exit
Closes #150 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'libusb/core.c')
-rw-r--r--libusb/core.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/libusb/core.c b/libusb/core.c
index 72faac4..a87cf96 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -1907,6 +1907,7 @@ err_unlock:
void API_EXPORTED libusb_exit(struct libusb_context *ctx)
{
struct libusb_device *dev, *next;
+ struct timeval tv = { 0, };
usbi_dbg("");
USBI_GET_CONTEXT(ctx);
@@ -1931,6 +1932,19 @@ void API_EXPORTED libusb_exit(struct libusb_context *ctx)
if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
usbi_hotplug_deregister_all(ctx);
+
+ /*
+ * Ensure any pending unplug events are read from the hotplug
+ * pipe. The usb_device-s hold in the events are no longer part
+ * of usb_devs, but the events still hold a reference!
+ *
+ * Note we don't do this if the application has left devices
+ * open (which implies a buggy app) to avoid packet completion
+ * handlers running when the app does not expect them to run.
+ */
+ if (list_empty(&ctx->open_devs))
+ libusb_handle_events_timeout(ctx, &tv);
+
usbi_mutex_lock(&ctx->usb_devs_lock);
list_for_each_entry_safe(dev, next, &ctx->usb_devs, list, struct libusb_device) {
list_del(&dev->list);