summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorparafin <parafin@paraf.in>2015-02-10 00:28:43 +0300
committerNathan Hjelm <hjelmn@lanl.gov>2015-02-12 11:50:27 -0700
commitd26cc697ccaba5496b56903eac12dc2b5838af04 (patch)
tree2b750b8169f31af0010c6a99c8e27fcb80fc7b2e
parentd68750a7ac65e29b41cadacd4231cc68af8a79bd (diff)
downloadlibusb-d26cc697ccaba5496b56903eac12dc2b5838af04.tar.gz
darwin: fix resource leak (cached devices are never freed)
For each new device (processed by hotplug code) darwin_ref_cached_device is called twice - in process_new_device and in darwin_get_cached_device (which is called from the first function). But when the device is detached only one darwin_deref_cached_device is done - in darwin_destroy_device. So there is inbalance between ref and deref which causes darwin_cached_devices list to monotonically grow and consume more and more resources over time. This commit fixes the problem by adding darwin_deref_cached_device call to darwin_devices_detached. Closes #52 Signed-off-by: Nathan Hjelm <hjelmn@mac.com>
-rw-r--r--libusb/os/darwin_usb.c12
-rw-r--r--libusb/version_nano.h2
2 files changed, 13 insertions, 1 deletions
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index e181ba8..9075de1 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -279,6 +279,7 @@ static void darwin_devices_attached (void *ptr, io_iterator_t add_devices) {
static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
struct libusb_device *dev = NULL;
struct libusb_context *ctx;
+ struct darwin_cached_device *old_device;
io_service_t device;
UInt64 session;
@@ -293,6 +294,17 @@ static void darwin_devices_detached (void *ptr, io_iterator_t rem_devices) {
if (!ret)
continue;
+ /* we need to match darwin_ref_cached_device call made in darwin_get_cached_device function
+ otherwise no cached device will ever get freed */
+ usbi_mutex_lock(&darwin_cached_devices_lock);
+ list_for_each_entry(old_device, &darwin_cached_devices, list, struct darwin_cached_device) {
+ if (old_device->session == session) {
+ darwin_deref_cached_device (old_device);
+ break;
+ }
+ }
+ usbi_mutex_unlock(&darwin_cached_devices_lock);
+
list_for_each_entry(ctx, &active_contexts_list, list, struct libusb_context) {
usbi_dbg ("notifying context %p of device disconnect", ctx);
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index bafad24..4849396 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10959
+#define LIBUSB_NANO 10960