hotplug: Fix usb_device memleak with hotunplug events pending on libusb_exit
authorHans de Goede <hdegoede@redhat.com>
Tue, 15 Oct 2013 13:30:02 +0000 (15:30 +0200)
committerHans de Goede <hdegoede@redhat.com>
Wed, 20 Nov 2013 12:21:37 +0000 (13:21 +0100)
Closes #150

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
libusb/core.c
libusb/version_nano.h

index 72faac4..a87cf96 100644 (file)
@@ -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);
index d5afb48..7deeae0 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 10848
+#define LIBUSB_NANO 10849