Commit ce48c8a3 authored by reillyg's avatar reillyg Committed by Commit bot

Avoid a race between libusb_submit_transfer and libusb_free_transfer.

The tail end of libusb_submit_transfer assumes that the transfer object
is still valid. It may in fact have already been freed by the transfer
completion callback if that call occurs on a different thread. As a
simply workaround (since the libusb code will be going away soon) this
patch simply posts the transfer deletion back to the thread where
libusb_submit_transfer is called so that they are serialized.

BUG=487712

Review URL: https://codereview.chromium.org/1126203008

Cr-Commit-Position: refs/heads/master@{#329953}
parent 50f82a6f
...@@ -485,7 +485,7 @@ void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status, ...@@ -485,7 +485,7 @@ void UsbDeviceHandleImpl::Transfer::TransferComplete(UsbTransferStatus status,
task_runner_->PostTask( task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_, base::Bind(&UsbDeviceHandleImpl::TransferComplete, device_handle_,
base::Owned(this), base::Unretained(this),
base::Bind(callback_, status, buffer_, bytes_transferred))); base::Bind(callback_, status, buffer_, bytes_transferred)));
} }
...@@ -970,6 +970,10 @@ void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer, ...@@ -970,6 +970,10 @@ void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer,
} else { } else {
transfer->callback_task_runner()->PostTask(FROM_HERE, callback); transfer->callback_task_runner()->PostTask(FROM_HERE, callback);
} }
// libusb_free_transfer races with libusb_submit_transfer and only work-
// around is to make sure to call them on the same thread.
blocking_task_runner_->DeleteSoon(FROM_HERE, transfer);
} }
void UsbDeviceHandleImpl::InternalClose() { void UsbDeviceHandleImpl::InternalClose() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment