diff options
author | parafin <parafin@paraf.in> | 2015-02-10 00:28:43 +0300 |
---|---|---|
committer | Nathan Hjelm <hjelmn@lanl.gov> | 2015-02-12 11:50:27 -0700 |
commit | d26cc697ccaba5496b56903eac12dc2b5838af04 (patch) | |
tree | 2b750b8169f31af0010c6a99c8e27fcb80fc7b2e | |
parent | d68750a7ac65e29b41cadacd4231cc68af8a79bd (diff) | |
download | libusb-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.c | 12 | ||||
-rw-r--r-- | libusb/version_nano.h | 2 |
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 |