summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2016-02-11 14:19:53 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-11 22:20:53 +0000
commita429a07842244fdb70a17352da186fc0d65985fb (patch)
treeb981597f230aa757e42bddbe2420a18e56a0fc5f /device
parenteac6998792e0478a7b095d1db6294c36ad917cd9 (diff)
downloadchromium_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.cc14
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