diff options
author | Hans de Goede <hdegoede@redhat.com> | 2013-06-20 12:52:25 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2013-06-20 12:52:25 +0200 |
commit | edcb3829a869f3d6781d5239de035fb12e3a95c9 (patch) | |
tree | 2e4a20863a4e56da21b36c7475853f5198c8eee4 /libusb/sync.c | |
parent | cb96ec5b4728a2d1cfc9bdf2c32e9e8c98ed074e (diff) | |
download | libusb-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.c | 18 |
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; } } |