| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/usb/usb_device_handle_usbfs.h" | 5 #include "device/usb/usb_device_handle_usbfs.h" |
| 6 | 6 |
| 7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21 | 7 #if defined(OS_ANDROID) && __ANDROID_API__ < 21 |
| 8 #include <linux/usb_ch9.h> | 8 #include <linux/usb_ch9.h> |
| 9 #else | 9 #else |
| 10 #include <linux/usb/ch9.h> | 10 #include <linux/usb/ch9.h> |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets); | 246 void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets); |
| 247 | 247 |
| 248 scoped_refptr<net::IOBuffer> control_transfer_buffer; | 248 scoped_refptr<net::IOBuffer> control_transfer_buffer; |
| 249 scoped_refptr<net::IOBuffer> buffer; | 249 scoped_refptr<net::IOBuffer> buffer; |
| 250 TransferCallback callback; | 250 TransferCallback callback; |
| 251 IsochronousTransferCallback isoc_callback; | 251 IsochronousTransferCallback isoc_callback; |
| 252 scoped_refptr<base::SingleThreadTaskRunner> callback_runner; | 252 scoped_refptr<base::SingleThreadTaskRunner> callback_runner; |
| 253 base::CancelableClosure timeout_closure; | 253 base::CancelableClosure timeout_closure; |
| 254 bool cancelled = false; | 254 bool cancelled = false; |
| 255 | 255 |
| 256 // When the URB is |cancelled| these two flags track whether the URB has both |
| 257 // been |discarded| and |reaped| since the possiblity of last-minute |
| 258 // completion makes these two conditions race. |
| 259 bool discarded = false; |
| 260 bool reaped = false; |
| 261 |
| 256 // The |urb| field must be the last in the struct so that the extra space | 262 // The |urb| field must be the last in the struct so that the extra space |
| 257 // allocated by the overridden new function above extends the length of its | 263 // allocated by the overridden new function above extends the length of its |
| 258 // |iso_frame_desc| field. | 264 // |iso_frame_desc| field. |
| 259 usbdevfs_urb urb; | 265 usbdevfs_urb urb; |
| 260 | 266 |
| 261 private: | 267 private: |
| 262 DISALLOW_COPY_AND_ASSIGN(Transfer); | 268 DISALLOW_COPY_AND_ASSIGN(Transfer); |
| 263 }; | 269 }; |
| 264 | 270 |
| 265 UsbDeviceHandleUsbfs::Transfer::Transfer( | 271 UsbDeviceHandleUsbfs::Transfer::Transfer( |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 callback_runner->PostTask( | 737 callback_runner->PostTask( |
| 732 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0)); | 738 FROM_HERE, base::Bind(callback, ConvertTransferResult(rc), nullptr, 0)); |
| 733 } else { | 739 } else { |
| 734 SetUpTimeoutCallback(transfer.get(), timeout); | 740 SetUpTimeoutCallback(transfer.get(), timeout); |
| 735 transfers_.push_back(std::move(transfer)); | 741 transfers_.push_back(std::move(transfer)); |
| 736 } | 742 } |
| 737 } | 743 } |
| 738 | 744 |
| 739 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { | 745 void UsbDeviceHandleUsbfs::ReapedUrbs(const std::vector<usbdevfs_urb*>& urbs) { |
| 740 for (auto* urb : urbs) { | 746 for (auto* urb : urbs) { |
| 741 Transfer* this_transfer = static_cast<Transfer*>(urb->usercontext); | 747 Transfer* transfer = static_cast<Transfer*>(urb->usercontext); |
| 742 DCHECK_EQ(urb, &this_transfer->urb); | 748 DCHECK_EQ(urb, &transfer->urb); |
| 743 auto it = std::find_if( | 749 |
| 744 transfers_.begin(), transfers_.end(), | 750 if (transfer->cancelled) { |
| 745 [this_transfer](const std::unique_ptr<Transfer>& transfer) -> bool { | 751 transfer->reaped = true; |
| 746 return transfer.get() == this_transfer; | 752 if (transfer->discarded) |
| 747 }); | 753 RemoveFromTransferList(transfer); |
| 748 DCHECK(it != transfers_.end()); | 754 } else { |
| 749 std::unique_ptr<Transfer> transfer = std::move(*it); | 755 TransferComplete(RemoveFromTransferList(transfer)); |
| 750 transfers_.erase(it); | 756 } |
| 751 TransferComplete(std::move(transfer)); | |
| 752 } | 757 } |
| 753 } | 758 } |
| 754 | 759 |
| 755 void UsbDeviceHandleUsbfs::TransferComplete( | 760 void UsbDeviceHandleUsbfs::TransferComplete( |
| 756 std::unique_ptr<Transfer> transfer) { | 761 std::unique_ptr<Transfer> transfer) { |
| 757 if (transfer->cancelled) | 762 if (transfer->cancelled) |
| 758 return; | 763 return; |
| 759 | 764 |
| 760 // The transfer will soon be freed. Cancel the timeout callback so that the | 765 // The transfer will soon be freed. Cancel the timeout callback so that the |
| 761 // raw pointer it holds to |transfer| is not used. | 766 // raw pointer it holds to |transfer| is not used. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 823 packets[i].length = packet_lengths[i]; | 828 packets[i].length = packet_lengths[i]; |
| 824 packets[i].transferred_length = 0; | 829 packets[i].transferred_length = 0; |
| 825 packets[i].status = status; | 830 packets[i].status = status; |
| 826 } | 831 } |
| 827 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets)); | 832 task_runner_->PostTask(FROM_HERE, base::Bind(callback, nullptr, packets)); |
| 828 } | 833 } |
| 829 | 834 |
| 830 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer, | 835 void UsbDeviceHandleUsbfs::SetUpTimeoutCallback(Transfer* transfer, |
| 831 unsigned int timeout) { | 836 unsigned int timeout) { |
| 832 if (timeout > 0) { | 837 if (timeout > 0) { |
| 833 transfer->timeout_closure.Reset(base::Bind( | 838 transfer->timeout_closure.Reset( |
| 834 &UsbDeviceHandleUsbfs::CancelTransfer, transfer, USB_TRANSFER_TIMEOUT)); | 839 base::Bind(&UsbDeviceHandleUsbfs::CancelTransfer, this, transfer, |
| 840 USB_TRANSFER_TIMEOUT)); |
| 835 task_runner_->PostDelayedTask(FROM_HERE, | 841 task_runner_->PostDelayedTask(FROM_HERE, |
| 836 transfer->timeout_closure.callback(), | 842 transfer->timeout_closure.callback(), |
| 837 base::TimeDelta::FromMilliseconds(timeout)); | 843 base::TimeDelta::FromMilliseconds(timeout)); |
| 838 } | 844 } |
| 839 } | 845 } |
| 840 | 846 |
| 841 // static | 847 std::unique_ptr<UsbDeviceHandleUsbfs::Transfer> |
| 848 UsbDeviceHandleUsbfs::RemoveFromTransferList(Transfer* transfer_ptr) { |
| 849 auto it = std::find_if( |
| 850 transfers_.begin(), transfers_.end(), |
| 851 [transfer_ptr](const std::unique_ptr<Transfer>& transfer) -> bool { |
| 852 return transfer.get() == transfer_ptr; |
| 853 }); |
| 854 DCHECK(it != transfers_.end()); |
| 855 std::unique_ptr<Transfer> transfer = std::move(*it); |
| 856 transfers_.erase(it); |
| 857 return transfer; |
| 858 } |
| 859 |
| 842 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, | 860 void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer, |
| 843 UsbTransferStatus status) { | 861 UsbTransferStatus status) { |
| 844 // |transfer| must stay in |transfers_| as it is still being processed by the | 862 // |transfer| must stay in |transfers_| as it is still being processed by the |
| 845 // kernel and may be reaped later. | 863 // kernel and will be reaped later. |
| 846 transfer->cancelled = true; | 864 transfer->cancelled = true; |
| 847 transfer->timeout_closure.Cancel(); | 865 transfer->timeout_closure.Cancel(); |
| 866 |
| 848 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { | 867 if (transfer->urb.type == USBDEVFS_URB_TYPE_ISO) { |
| 849 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); | 868 std::vector<IsochronousPacket> packets(transfer->urb.number_of_packets); |
| 850 for (size_t i = 0; i < packets.size(); ++i) { | 869 for (size_t i = 0; i < packets.size(); ++i) { |
| 851 packets[i].length = transfer->urb.iso_frame_desc[i].length; | 870 packets[i].length = transfer->urb.iso_frame_desc[i].length; |
| 852 packets[i].transferred_length = 0; | 871 packets[i].transferred_length = 0; |
| 853 packets[i].status = status; | 872 packets[i].status = status; |
| 854 } | 873 } |
| 855 transfer->RunIsochronousCallback(packets); | 874 transfer->RunIsochronousCallback(packets); |
| 856 } else { | 875 } else { |
| 857 transfer->RunCallback(status, 0); | 876 transfer->RunCallback(status, 0); |
| 858 } | 877 } |
| 878 |
| 879 blocking_task_runner_->PostTask( |
| 880 FROM_HERE, |
| 881 base::Bind(&UsbDeviceHandleUsbfs::DiscardUrbBlocking, this, transfer)); |
| 882 } |
| 883 |
| 884 void UsbDeviceHandleUsbfs::DiscardUrbBlocking(Transfer* transfer) { |
| 885 if (fd_.is_valid()) |
| 886 HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_DISCARDURB, &transfer->urb)); |
| 887 |
| 888 task_runner_->PostTask( |
| 889 FROM_HERE, |
| 890 base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, this, transfer)); |
| 891 } |
| 892 |
| 893 void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) { |
| 894 transfer->discarded = true; |
| 895 if (transfer->reaped) |
| 896 RemoveFromTransferList(transfer); |
| 859 } | 897 } |
| 860 | 898 |
| 861 } // namespace device | 899 } // namespace device |
| OLD | NEW |