summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authordgozman <dgozman@chromium.org>2015-09-17 19:04:48 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-18 02:05:35 +0000
commit2cafe6bd94e15c9bc172c2ed8d1b1481ef5a2d9a (patch)
tree3b7f5efdae0756cc9ab525f19718f8875bb951e1 /device
parenteb774ca399d680db7885a01ce5cf48eb1260f57b (diff)
downloadchromium_src-2cafe6bd94e15c9bc172c2ed8d1b1481ef5a2d9a.zip
chromium_src-2cafe6bd94e15c9bc172c2ed8d1b1481ef5a2d9a.tar.gz
chromium_src-2cafe6bd94e15c9bc172c2ed8d1b1481ef5a2d9a.tar.bz2
Fix threading issues in UsbDeviceHandleImpl.
Many of the error callbacks and GenericTransferImpl were using the wrong task runner. BUG=533068 Review URL: https://codereview.chromium.org/1347183004 Cr-Commit-Position: refs/heads/master@{#349582}
Diffstat (limited to 'device')
-rw-r--r--device/usb/usb_device_handle_impl.cc54
1 files changed, 40 insertions, 14 deletions
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc
index b1077d2..d523379 100644
--- a/device/usb/usb_device_handle_impl.cc
+++ b/device/usb/usb_device_handle_impl.cc
@@ -104,6 +104,20 @@ static UsbTransferStatus ConvertTransferStatus(
}
}
+static void RunTransferCallback(
+ scoped_refptr<base::TaskRunner> callback_task_runner,
+ const UsbDeviceHandle::TransferCallback& callback,
+ UsbTransferStatus status,
+ scoped_refptr<net::IOBuffer> buffer,
+ size_t result) {
+ if (callback_task_runner->RunsTasksOnCurrentThread()) {
+ callback.Run(status, buffer, result);
+ } else {
+ callback_task_runner->PostTask(
+ FROM_HERE, base::Bind(callback, status, buffer, result));
+ }
+}
+
} // namespace
class UsbDeviceHandleImpl::InterfaceClaimer
@@ -833,13 +847,15 @@ void UsbDeviceHandleImpl::ControlTransferInternal(
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_) {
- callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT,
+ buffer, 0);
return;
}
if (length > UINT16_MAX) {
USB_LOG(USER) << "Transfer too long.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
@@ -847,7 +863,8 @@ void UsbDeviceHandleImpl::ControlTransferInternal(
scoped_refptr<net::IOBuffer> resized_buffer(
new net::IOBufferWithSize(static_cast<int>(resized_length)));
if (!resized_buffer.get()) {
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
memcpy(resized_buffer->data() + LIBUSB_CONTROL_SETUP_SIZE, buffer->data(),
@@ -858,7 +875,8 @@ void UsbDeviceHandleImpl::ControlTransferInternal(
value, index, static_cast<uint16>(length), resized_buffer, timeout,
callback_task_runner, callback);
if (!transfer) {
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
@@ -876,13 +894,15 @@ void UsbDeviceHandleImpl::BulkTransferInternal(
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_) {
- callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT,
+ buffer, 0);
return;
}
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
@@ -904,13 +924,15 @@ void UsbDeviceHandleImpl::InterruptTransferInternal(
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_) {
- callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT,
+ buffer, 0);
return;
}
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
@@ -934,13 +956,15 @@ void UsbDeviceHandleImpl::IsochronousTransferInternal(
DCHECK(thread_checker_.CalledOnValidThread());
if (!device_) {
- callback.Run(USB_TRANSFER_DISCONNECT, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_DISCONNECT,
+ buffer, 0);
return;
}
if (length > INT_MAX) {
USB_LOG(USER) << "Transfer too long.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
@@ -963,22 +987,24 @@ void UsbDeviceHandleImpl::GenericTransferInternal(
if (!ContainsKey(endpoint_map_, endpoint)) {
USB_LOG(DEBUG)
<< "Failed to do generic transfer since endpoint not in endpoint_map_.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
return;
}
UsbTransferType transfer_type = endpoint_map_[endpoint].transfer_type;
if (transfer_type == USB_TRANSFER_BULK) {
BulkTransferInternal(direction, endpoint, buffer, length, timeout,
- task_runner_, callback);
+ callback_task_runner, callback);
} else if (transfer_type == USB_TRANSFER_INTERRUPT) {
InterruptTransferInternal(direction, endpoint, buffer, length, timeout,
- task_runner_, callback);
+ callback_task_runner, callback);
} else {
USB_LOG(DEBUG)
<< "Failed to do generic transfer since transfer_type is not "
"bulk or interrupt.";
- callback.Run(USB_TRANSFER_ERROR, buffer, 0);
+ RunTransferCallback(callback_task_runner, callback, USB_TRANSFER_ERROR,
+ buffer, 0);
}
}