diff options
author | reillyg <reillyg@chromium.org> | 2016-02-11 14:19:53 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-11 22:20:53 +0000 |
commit | a429a07842244fdb70a17352da186fc0d65985fb (patch) | |
tree | b981597f230aa757e42bddbe2420a18e56a0fc5f /device | |
parent | eac6998792e0478a7b095d1db6294c36ad917cd9 (diff) | |
download | chromium_src-a429a07842244fdb70a17352da186fc0d65985fb.zip chromium_src-a429a07842244fdb70a17352da186fc0d65985fb.tar.gz chromium_src-a429a07842244fdb70a17352da186fc0d65985fb.tar.bz2 |
usb: Make sure remaining interfaces are released on the right thread.
When a USB device handle is closed any remaining claimed interfaces are
automatically released. This function needs the same thread hopping
logic used in ReleaseInterface to make sure that if there are no other
references to the InterfaceClaimer object (such as ones held by pending
transfers) it is released on the blocking thread.
BUG=None
Review URL: https://codereview.chromium.org/1695513002
Cr-Commit-Position: refs/heads/master@{#375019}
Diffstat (limited to 'device')
-rw-r--r-- | device/usb/usb_device_handle_impl.cc | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index 16f343e..716c6c1 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc @@ -1111,13 +1111,19 @@ void UsbDeviceHandleImpl::InternalClose() { transfer->Cancel(); } - // Attempt-release all the interfaces. - // It will be retained until the transfer cancellation is finished. - claimed_interfaces_.clear(); + // Release all remaining interfaces once their transfers have completed. + // This loop must ensure that what may be the final reference is released on + // the right thread. + for (auto& map_entry : claimed_interfaces_) { + InterfaceClaimer* interface_claimer = map_entry.second.get(); + interface_claimer->AddRef(); + map_entry.second = nullptr; + blocking_task_runner_->ReleaseSoon(FROM_HERE, interface_claimer); + } // Cannot close device handle here. Need to wait for libusb_cancel_transfer to // finish. - device_ = NULL; + device_ = nullptr; } } // namespace device |