From 449dde0f87ac33b516a1186398d17edbd75e4ee9 Mon Sep 17 00:00:00 2001 From: reillyg Date: Thu, 25 Feb 2016 21:42:46 -0800 Subject: Ensure libusb_close is called from the FILE thread. If libusb_close is called from the UsbEventHandler thread then it will deadlock trying to reacquire libusb's open_devs_lock. To avoid this and generally ensure that libusb calls happen on the FILE thread this patch posts a task if the UsbDeviceHandleImpl destructor is not already running on the FILE thread. BUG=589592 Review URL: https://codereview.chromium.org/1736703002 Cr-Commit-Position: refs/heads/master@{#377821} --- device/usb/usb_device_handle_impl.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'device') diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index 716c6c1..cf6ebfb 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc @@ -782,8 +782,14 @@ UsbDeviceHandleImpl::UsbDeviceHandleImpl( UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { // This class is RefCountedThreadSafe and so the destructor may be called on - // any thread. - libusb_close(handle_); + // any thread. libusb is not safe to reentrancy so be sure not to try to close + // the device from inside a transfer completion callback. + if (blocking_task_runner_->RunsTasksOnCurrentThread()) { + libusb_close(handle_); + } else { + blocking_task_runner_->PostTask(FROM_HERE, + base::Bind(&libusb_close, handle_)); + } } void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread( -- cgit v1.1