diff options
author | dgozman <dgozman@chromium.org> | 2015-09-17 19:04:48 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-18 02:05:35 +0000 |
commit | 2cafe6bd94e15c9bc172c2ed8d1b1481ef5a2d9a (patch) | |
tree | 3b7f5efdae0756cc9ab525f19718f8875bb951e1 /device | |
parent | eb774ca399d680db7885a01ce5cf48eb1260f57b (diff) | |
download | chromium_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.cc | 54 |
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); } } |