summaryrefslogtreecommitdiff
path: root/libusb/sync.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2013-06-20 12:52:25 +0200
committerHans de Goede <hdegoede@redhat.com>2013-06-20 12:52:25 +0200
commitedcb3829a869f3d6781d5239de035fb12e3a95c9 (patch)
tree2e4a20863a4e56da21b36c7475853f5198c8eee4 /libusb/sync.c
parentcb96ec5b4728a2d1cfc9bdf2c32e9e8c98ed074e (diff)
downloadlibusb-edcb3829a869f3d6781d5239de035fb12e3a95c9.tar.gz
sync.c: Do not free an incompleted transfer
Before this patch the code in sync.c would free an incomplete transfer when libusb_handle_events_completed exits with an error twice in a row. But we should never free an incomplete transfer, otherwise we may end up referencing free-ed memory later on. This patch simply logs an error and keeps on trying until the transfer completes. Note that if libusb_handle_events_completed keeps throwing an error the entire time, without ever completing the transfer, this patch effectively replaces a potential crash / unspecified behavior, with an endless loop and logging a ton of errors making clear what is going on. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'libusb/sync.c')
-rw-r--r--libusb/sync.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/libusb/sync.c b/libusb/sync.c
index e115099..81c13a2 100644
--- a/libusb/sync.c
+++ b/libusb/sync.c
@@ -106,12 +106,11 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
+ usbi_err(HANDLE_CTX(dev_handle),
+ "libusb_handle_events failed: %s, cancelling transfer and retrying",
+ libusb_error_name(r));
libusb_cancel_transfer(transfer);
- while (!completed)
- if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
- break;
- libusb_free_transfer(transfer);
- return r;
+ continue;
}
}
@@ -183,12 +182,11 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle,
if (r < 0) {
if (r == LIBUSB_ERROR_INTERRUPTED)
continue;
+ usbi_err(HANDLE_CTX(dev_handle),
+ "libusb_handle_events failed: %s, cancelling transfer and retrying",
+ libusb_error_name(r));
libusb_cancel_transfer(transfer);
- while (!completed)
- if (libusb_handle_events_completed(HANDLE_CTX(dev_handle), &completed) < 0)
- break;
- libusb_free_transfer(transfer);
- return r;
+ continue;
}
}