Commit 03d7f183 authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

Revert "Attach UsbContext to libusb_device(_handle) pointers"

This reverts commit daa348fa.

Reason for revert: https://crbug.com/866782

Original change's description:
> Attach UsbContext to libusb_device(_handle) pointers
> 
> This change modifies ScopedLibusbDeviceRef and adds a new class
> ScopedLibusbDeviceHandle. This now explicitly own a reference to the
> UsbContext object (which reference counts a libusb_context) in addition
> to the libusb_device or libusb_device_handle they are wrapping.
> 
> This resolves potential use-after-frees possible when posting tasks
> with a ScopedLibusbDeviceRef since the UsbService the task is being
> posted to could be destroyed before the task is executed. The
> libusb_device would then be released after its libusb_context has been
> destroyed.
> 
> This is based on https://crrev.com/c/1131949 after I realized there
> where additional issues that needed to be addressed.
> 
> Bug: 838947
> Change-Id: Idee02828bf615bd477033e585fffe03cf4d20595
> Reviewed-on: https://chromium-review.googlesource.com/1145910
> Reviewed-by: Ken Rockot <rockot@chromium.org>
> Commit-Queue: Reilly Grant <reillyg@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#577329}

TBR=rockot@chromium.org,reillyg@chromium.org

Change-Id: I4146987c84b34e1d3625e7e91cfc672afe98054c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: 838947
Reviewed-on: https://chromium-review.googlesource.com/1147950Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577525}
parent f4a2efba
...@@ -81,9 +81,6 @@ static_library("usb") { ...@@ -81,9 +81,6 @@ static_library("usb") {
if (is_win || is_mac) { if (is_win || is_mac) {
sources += [ sources += [
"scoped_libusb_device_handle.cc",
"scoped_libusb_device_handle.h",
"scoped_libusb_device_ref.cc",
"scoped_libusb_device_ref.h", "scoped_libusb_device_ref.h",
"usb_context.cc", "usb_context.cc",
"usb_context.h", "usb_context.h",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/usb/scoped_libusb_device_handle.h"
#include "device/usb/usb_context.h"
#include "third_party/libusb/src/libusb/libusb.h"
namespace device {
ScopedLibusbDeviceHandle::ScopedLibusbDeviceHandle(
libusb_device_handle* handle,
scoped_refptr<UsbContext> context)
: handle_(handle), context_(std::move(context)) {}
ScopedLibusbDeviceHandle::ScopedLibusbDeviceHandle(
ScopedLibusbDeviceHandle&& other)
: handle_(other.handle_), context_(std::move(other.context_)) {
other.handle_ = nullptr;
}
ScopedLibusbDeviceHandle::~ScopedLibusbDeviceHandle() {
Reset();
}
void ScopedLibusbDeviceHandle::Reset() {
libusb_close(handle_);
handle_ = nullptr;
context_.reset();
}
bool ScopedLibusbDeviceHandle::IsValid() const {
return handle_ != nullptr;
}
} // namespace device
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_
#define DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
struct libusb_device_handle;
namespace device {
class UsbContext;
// This class owns a reference to a libusb_device_handle as well as a reference
// to the libusb_context. The libusb_context must outlive any
// libusb_device_handle instances created from it.
class ScopedLibusbDeviceHandle {
public:
ScopedLibusbDeviceHandle(libusb_device_handle* handle,
scoped_refptr<UsbContext> context);
ScopedLibusbDeviceHandle(ScopedLibusbDeviceHandle&& other);
~ScopedLibusbDeviceHandle();
libusb_device_handle* get() const { return handle_; }
void Reset();
bool IsValid() const;
private:
libusb_device_handle* handle_;
scoped_refptr<UsbContext> context_;
DISALLOW_COPY_AND_ASSIGN(ScopedLibusbDeviceHandle);
};
} // namespace device
#endif // DEVICE_USB_SCOPED_LIBUSB_DEVICE_HANDLE_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/usb/scoped_libusb_device_ref.h"
#include "device/usb/usb_context.h"
#include "third_party/libusb/src/libusb/libusb.h"
namespace device {
ScopedLibusbDeviceRef::ScopedLibusbDeviceRef(libusb_device* device,
scoped_refptr<UsbContext> context)
: device_(device), context_(std::move(context)) {}
ScopedLibusbDeviceRef::ScopedLibusbDeviceRef(ScopedLibusbDeviceRef&& other)
: device_(other.device_), context_(std::move(other.context_)) {
other.device_ = nullptr;
}
ScopedLibusbDeviceRef::~ScopedLibusbDeviceRef() {
Reset();
}
void ScopedLibusbDeviceRef::Reset() {
libusb_unref_device(device_);
device_ = nullptr;
context_.reset();
}
bool ScopedLibusbDeviceRef::IsValid() const {
return device_ != nullptr;
}
bool operator==(const ScopedLibusbDeviceRef& ref, libusb_device* device) {
return ref.get() == device;
}
} // namespace device
...@@ -5,40 +5,19 @@ ...@@ -5,40 +5,19 @@
#ifndef DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_ #ifndef DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_
#define DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_ #define DEVICE_USB_SCOPED_LIBUSB_DEVICE_REF_H_
#include "base/macros.h" #include "base/scoped_generic.h"
#include "base/memory/scoped_refptr.h" #include "third_party/libusb/src/libusb/libusb.h"
struct libusb_device;
namespace device { namespace device {
class UsbContext; struct LibusbDeviceRefTraits {
static libusb_device* InvalidValue() { return nullptr; }
// This class owns a reference to a libusb_device as well as a reference to
// the libusb_context. The libusb_context must outlive any libusb_device
// instances created from it.
class ScopedLibusbDeviceRef {
public:
ScopedLibusbDeviceRef(libusb_device* device,
scoped_refptr<UsbContext> context);
ScopedLibusbDeviceRef(ScopedLibusbDeviceRef&& other);
~ScopedLibusbDeviceRef();
libusb_device* get() const { return device_; }
scoped_refptr<UsbContext> GetContext() const { return context_; }
void Reset();
bool IsValid() const;
private:
libusb_device* device_;
scoped_refptr<UsbContext> context_;
DISALLOW_COPY_AND_ASSIGN(ScopedLibusbDeviceRef); static void Free(libusb_device* device) { libusb_unref_device(device); }
}; };
bool operator==(const ScopedLibusbDeviceRef& ref, libusb_device* device); using ScopedLibusbDeviceRef =
base::ScopedGeneric<libusb_device*, LibusbDeviceRefTraits>;
} // namespace device } // namespace device
......
...@@ -311,7 +311,7 @@ UsbDeviceHandleImpl::Transfer::CreateControlTransfer( ...@@ -311,7 +311,7 @@ UsbDeviceHandleImpl::Transfer::CreateControlTransfer(
libusb_fill_control_setup(buffer->front(), type, request, value, index, libusb_fill_control_setup(buffer->front(), type, request, value, index,
length); length);
libusb_fill_control_transfer(transfer->platform_transfer_, libusb_fill_control_transfer(transfer->platform_transfer_,
device_handle->handle(), buffer->front(), device_handle->handle_, buffer->front(),
&UsbDeviceHandleImpl::Transfer::PlatformCallback, &UsbDeviceHandleImpl::Transfer::PlatformCallback,
transfer.get(), timeout); transfer.get(), timeout);
...@@ -341,7 +341,7 @@ UsbDeviceHandleImpl::Transfer::CreateBulkTransfer( ...@@ -341,7 +341,7 @@ UsbDeviceHandleImpl::Transfer::CreateBulkTransfer(
} }
libusb_fill_bulk_transfer( libusb_fill_bulk_transfer(
transfer->platform_transfer_, device_handle->handle(), endpoint, transfer->platform_transfer_, device_handle->handle_, endpoint,
buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback, buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback,
transfer.get(), timeout); transfer.get(), timeout);
...@@ -371,7 +371,7 @@ UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer( ...@@ -371,7 +371,7 @@ UsbDeviceHandleImpl::Transfer::CreateInterruptTransfer(
} }
libusb_fill_interrupt_transfer( libusb_fill_interrupt_transfer(
transfer->platform_transfer_, device_handle->handle(), endpoint, transfer->platform_transfer_, device_handle->handle_, endpoint,
buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback, buffer->front(), length, &UsbDeviceHandleImpl::Transfer::PlatformCallback,
transfer.get(), timeout); transfer.get(), timeout);
...@@ -401,10 +401,10 @@ UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer( ...@@ -401,10 +401,10 @@ UsbDeviceHandleImpl::Transfer::CreateIsochronousTransfer(
return nullptr; return nullptr;
} }
libusb_fill_iso_transfer( libusb_fill_iso_transfer(transfer->platform_transfer_, device_handle->handle_,
transfer->platform_transfer_, device_handle->handle(), endpoint, endpoint, buffer->front(), static_cast<int>(length),
buffer->front(), static_cast<int>(length), num_packets, num_packets, &Transfer::PlatformCallback,
&Transfer::PlatformCallback, transfer.get(), timeout); transfer.get(), timeout);
for (size_t i = 0; i < packet_lengths.size(); ++i) for (size_t i = 0; i < packet_lengths.size(); ++i)
transfer->platform_transfer_->iso_packet_desc[i].length = packet_lengths[i]; transfer->platform_transfer_->iso_packet_desc[i].length = packet_lengths[i];
...@@ -798,14 +798,16 @@ const UsbInterfaceDescriptor* UsbDeviceHandleImpl::FindInterfaceByEndpoint( ...@@ -798,14 +798,16 @@ const UsbInterfaceDescriptor* UsbDeviceHandleImpl::FindInterfaceByEndpoint(
} }
UsbDeviceHandleImpl::UsbDeviceHandleImpl( UsbDeviceHandleImpl::UsbDeviceHandleImpl(
scoped_refptr<UsbContext> context,
scoped_refptr<UsbDeviceImpl> device, scoped_refptr<UsbDeviceImpl> device,
ScopedLibusbDeviceHandle handle, PlatformUsbDeviceHandle handle,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
: device_(std::move(device)), : device_(device),
handle_(std::move(handle)), handle_(handle),
context_(context),
task_runner_(base::ThreadTaskRunnerHandle::Get()), task_runner_(base::ThreadTaskRunnerHandle::Get()),
blocking_task_runner_(blocking_task_runner) { blocking_task_runner_(blocking_task_runner) {
DCHECK(handle_.IsValid()) << "Cannot create device with an invalid handle."; DCHECK(handle) << "Cannot create device with NULL handle.";
} }
UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { UsbDeviceHandleImpl::~UsbDeviceHandleImpl() {
...@@ -815,19 +817,17 @@ UsbDeviceHandleImpl::~UsbDeviceHandleImpl() { ...@@ -815,19 +817,17 @@ UsbDeviceHandleImpl::~UsbDeviceHandleImpl() {
// any thread. libusb is not safe to reentrancy so be sure not to try to close // any thread. libusb is not safe to reentrancy so be sure not to try to close
// the device from inside a transfer completion callback. // the device from inside a transfer completion callback.
if (blocking_task_runner_->RunsTasksInCurrentSequence()) { if (blocking_task_runner_->RunsTasksInCurrentSequence()) {
handle_.Reset(); libusb_close(handle_);
} else { } else {
blocking_task_runner_->PostTask( blocking_task_runner_->PostTask(FROM_HERE,
FROM_HERE, base::BindOnce(&libusb_close, handle_));
base::BindOnce(base::DoNothing::Once<ScopedLibusbDeviceHandle>(),
std::move(handle_)));
} }
} }
void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread( void UsbDeviceHandleImpl::SetConfigurationOnBlockingThread(
int configuration_value, int configuration_value,
ResultCallback callback) { ResultCallback callback) {
int rv = libusb_set_configuration(handle(), configuration_value); int rv = libusb_set_configuration(handle_, configuration_value);
if (rv != LIBUSB_SUCCESS) { if (rv != LIBUSB_SUCCESS) {
USB_LOG(EVENT) << "Failed to set configuration " << configuration_value USB_LOG(EVENT) << "Failed to set configuration " << configuration_value
<< ": " << ConvertPlatformUsbErrorToString(rv); << ": " << ConvertPlatformUsbErrorToString(rv);
...@@ -855,7 +855,7 @@ void UsbDeviceHandleImpl::SetConfigurationComplete(bool success, ...@@ -855,7 +855,7 @@ void UsbDeviceHandleImpl::SetConfigurationComplete(bool success,
void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread( void UsbDeviceHandleImpl::ClaimInterfaceOnBlockingThread(
int interface_number, int interface_number,
ResultCallback callback) { ResultCallback callback) {
int rv = libusb_claim_interface(handle(), interface_number); int rv = libusb_claim_interface(handle_, interface_number);
scoped_refptr<InterfaceClaimer> interface_claimer; scoped_refptr<InterfaceClaimer> interface_claimer;
if (rv == LIBUSB_SUCCESS) { if (rv == LIBUSB_SUCCESS) {
interface_claimer = interface_claimer =
...@@ -897,7 +897,7 @@ void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread( ...@@ -897,7 +897,7 @@ void UsbDeviceHandleImpl::SetInterfaceAlternateSettingOnBlockingThread(
int interface_number, int interface_number,
int alternate_setting, int alternate_setting,
ResultCallback callback) { ResultCallback callback) {
int rv = libusb_set_interface_alt_setting(handle(), interface_number, int rv = libusb_set_interface_alt_setting(handle_, interface_number,
alternate_setting); alternate_setting);
if (rv != LIBUSB_SUCCESS) { if (rv != LIBUSB_SUCCESS) {
USB_LOG(EVENT) << "Failed to set interface " << interface_number USB_LOG(EVENT) << "Failed to set interface " << interface_number
...@@ -930,7 +930,7 @@ void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete( ...@@ -930,7 +930,7 @@ void UsbDeviceHandleImpl::SetInterfaceAlternateSettingComplete(
} }
void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(ResultCallback callback) { void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(ResultCallback callback) {
int rv = libusb_reset_device(handle()); int rv = libusb_reset_device(handle_);
if (rv != LIBUSB_SUCCESS) { if (rv != LIBUSB_SUCCESS) {
USB_LOG(EVENT) << "Failed to reset device: " USB_LOG(EVENT) << "Failed to reset device: "
<< ConvertPlatformUsbErrorToString(rv); << ConvertPlatformUsbErrorToString(rv);
...@@ -941,7 +941,7 @@ void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(ResultCallback callback) { ...@@ -941,7 +941,7 @@ void UsbDeviceHandleImpl::ResetDeviceOnBlockingThread(ResultCallback callback) {
void UsbDeviceHandleImpl::ClearHaltOnBlockingThread(uint8_t endpoint, void UsbDeviceHandleImpl::ClearHaltOnBlockingThread(uint8_t endpoint,
ResultCallback callback) { ResultCallback callback) {
int rv = libusb_clear_halt(handle(), endpoint); int rv = libusb_clear_halt(handle_, endpoint);
if (rv != LIBUSB_SUCCESS) { if (rv != LIBUSB_SUCCESS) {
USB_LOG(EVENT) << "Failed to clear halt: " USB_LOG(EVENT) << "Failed to clear halt: "
<< ConvertPlatformUsbErrorToString(rv); << ConvertPlatformUsbErrorToString(rv);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/threading/thread_checker.h" #include "base/threading/thread_checker.h"
#include "device/usb/scoped_libusb_device_handle.h"
#include "device/usb/usb_device_handle.h" #include "device/usb/usb_device_handle.h"
#include "third_party/libusb/src/libusb/libusb.h" #include "third_party/libusb/src/libusb/libusb.h"
...@@ -35,8 +34,10 @@ struct EndpointMapValue { ...@@ -35,8 +34,10 @@ struct EndpointMapValue {
const UsbEndpointDescriptor* endpoint; const UsbEndpointDescriptor* endpoint;
}; };
class UsbContext;
class UsbDeviceImpl; class UsbDeviceImpl;
typedef libusb_device_handle* PlatformUsbDeviceHandle;
typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor; typedef libusb_iso_packet_descriptor* PlatformUsbIsoPacketDescriptor;
typedef libusb_transfer* PlatformUsbTransferHandle; typedef libusb_transfer* PlatformUsbTransferHandle;
...@@ -89,13 +90,14 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { ...@@ -89,13 +90,14 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle {
// This constructor is called by UsbDeviceImpl. // This constructor is called by UsbDeviceImpl.
UsbDeviceHandleImpl( UsbDeviceHandleImpl(
scoped_refptr<UsbContext> context,
scoped_refptr<UsbDeviceImpl> device, scoped_refptr<UsbDeviceImpl> device,
ScopedLibusbDeviceHandle handle, PlatformUsbDeviceHandle handle,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
~UsbDeviceHandleImpl() override; ~UsbDeviceHandleImpl() override;
libusb_device_handle* handle() const { return handle_.get(); } PlatformUsbDeviceHandle handle() const { return handle_; }
private: private:
class InterfaceClaimer; class InterfaceClaimer;
...@@ -172,7 +174,7 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { ...@@ -172,7 +174,7 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle {
scoped_refptr<UsbDeviceImpl> device_; scoped_refptr<UsbDeviceImpl> device_;
ScopedLibusbDeviceHandle handle_; PlatformUsbDeviceHandle handle_;
typedef std::map<int, scoped_refptr<InterfaceClaimer>> ClaimedInterfaceMap; typedef std::map<int, scoped_refptr<InterfaceClaimer>> ClaimedInterfaceMap;
ClaimedInterfaceMap claimed_interfaces_; ClaimedInterfaceMap claimed_interfaces_;
...@@ -184,6 +186,10 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle { ...@@ -184,6 +186,10 @@ class UsbDeviceHandleImpl : public UsbDeviceHandle {
typedef std::map<int, EndpointMapValue> EndpointMap; typedef std::map<int, EndpointMapValue> EndpointMap;
EndpointMap endpoint_map_; EndpointMap endpoint_map_;
// Retain the UsbContext so that the platform context will not be destroyed
// before this handle.
scoped_refptr<UsbContext> context_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
namespace device { namespace device {
UsbDeviceImpl::UsbDeviceImpl(ScopedLibusbDeviceRef platform_device, UsbDeviceImpl::UsbDeviceImpl(scoped_refptr<UsbContext> context,
ScopedLibusbDeviceRef platform_device,
const libusb_device_descriptor& descriptor) const libusb_device_descriptor& descriptor)
: UsbDevice(descriptor.bcdUSB, : UsbDevice(descriptor.bcdUSB,
descriptor.bDeviceClass, descriptor.bDeviceClass,
...@@ -40,8 +41,9 @@ UsbDeviceImpl::UsbDeviceImpl(ScopedLibusbDeviceRef platform_device, ...@@ -40,8 +41,9 @@ UsbDeviceImpl::UsbDeviceImpl(ScopedLibusbDeviceRef platform_device,
base::string16(), base::string16(),
base::string16(), base::string16(),
base::string16()), base::string16()),
context_(std::move(context)),
platform_device_(std::move(platform_device)) { platform_device_(std::move(platform_device)) {
CHECK(platform_device_.IsValid()) << "platform_device must be valid"; CHECK(platform_device_.is_valid()) << "platform_device must be valid";
ReadAllConfigurations(); ReadAllConfigurations();
RefreshActiveConfiguration(); RefreshActiveConfiguration();
} }
...@@ -102,14 +104,12 @@ void UsbDeviceImpl::OpenOnBlockingThread( ...@@ -102,14 +104,12 @@ void UsbDeviceImpl::OpenOnBlockingThread(
scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::TaskRunner> task_runner,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) {
base::AssertBlockingAllowed(); base::AssertBlockingAllowed();
libusb_device_handle* handle; PlatformUsbDeviceHandle handle;
const int rv = libusb_open(platform_device(), &handle); const int rv = libusb_open(platform_device(), &handle);
ScopedLibusbDeviceHandle scoped_handle(handle, platform_device_.GetContext());
if (LIBUSB_SUCCESS == rv) { if (LIBUSB_SUCCESS == rv) {
task_runner->PostTask( task_runner->PostTask(
FROM_HERE, FROM_HERE, base::BindOnce(&UsbDeviceImpl::Opened, this, handle,
base::BindOnce(&UsbDeviceImpl::Opened, this, std::move(scoped_handle), std::move(callback), blocking_task_runner));
std::move(callback), blocking_task_runner));
} else { } else {
USB_LOG(EVENT) << "Failed to open device: " USB_LOG(EVENT) << "Failed to open device: "
<< ConvertPlatformUsbErrorToString(rv); << ConvertPlatformUsbErrorToString(rv);
...@@ -119,12 +119,12 @@ void UsbDeviceImpl::OpenOnBlockingThread( ...@@ -119,12 +119,12 @@ void UsbDeviceImpl::OpenOnBlockingThread(
} }
void UsbDeviceImpl::Opened( void UsbDeviceImpl::Opened(
ScopedLibusbDeviceHandle platform_handle, PlatformUsbDeviceHandle platform_handle,
OpenCallback callback, OpenCallback callback,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) { scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
scoped_refptr<UsbDeviceHandle> device_handle = new UsbDeviceHandleImpl( scoped_refptr<UsbDeviceHandle> device_handle = new UsbDeviceHandleImpl(
this, std::move(platform_handle), blocking_task_runner); context_, this, platform_handle, blocking_task_runner);
handles().push_back(device_handle.get()); handles().push_back(device_handle.get());
std::move(callback).Run(device_handle); std::move(callback).Run(device_handle);
} }
......
...@@ -21,7 +21,9 @@ ...@@ -21,7 +21,9 @@
#include "device/usb/usb_descriptors.h" #include "device/usb/usb_descriptors.h"
#include "device/usb/usb_device.h" #include "device/usb/usb_device.h"
struct libusb_device;
struct libusb_device_descriptor; struct libusb_device_descriptor;
struct libusb_device_handle;
namespace base { namespace base {
class SequencedTaskRunner; class SequencedTaskRunner;
...@@ -29,12 +31,15 @@ class SequencedTaskRunner; ...@@ -29,12 +31,15 @@ class SequencedTaskRunner;
namespace device { namespace device {
class ScopedLibusbDeviceHandle;
class UsbDeviceHandleImpl; class UsbDeviceHandleImpl;
class UsbContext;
typedef struct libusb_device_handle* PlatformUsbDeviceHandle;
class UsbDeviceImpl : public UsbDevice { class UsbDeviceImpl : public UsbDevice {
public: public:
UsbDeviceImpl(ScopedLibusbDeviceRef platform_device, UsbDeviceImpl(scoped_refptr<UsbContext> context,
ScopedLibusbDeviceRef platform_device,
const libusb_device_descriptor& descriptor); const libusb_device_descriptor& descriptor);
// UsbDevice implementation: // UsbDevice implementation:
...@@ -74,13 +79,15 @@ class UsbDeviceImpl : public UsbDevice { ...@@ -74,13 +79,15 @@ class UsbDeviceImpl : public UsbDevice {
OpenCallback callback, OpenCallback callback,
scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::TaskRunner> task_runner,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
void Opened(ScopedLibusbDeviceHandle platform_handle, void Opened(PlatformUsbDeviceHandle platform_handle,
OpenCallback callback, OpenCallback callback,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); scoped_refptr<base::SequencedTaskRunner> blocking_task_runner);
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
bool visited_ = false; bool visited_ = false;
// The libusb_context must not be released before the libusb_device.
const scoped_refptr<UsbContext> context_;
const ScopedLibusbDeviceRef platform_device_; const ScopedLibusbDeviceRef platform_device_;
DISALLOW_COPY_AND_ASSIGN(UsbDeviceImpl); DISALLOW_COPY_AND_ASSIGN(UsbDeviceImpl);
......
...@@ -131,7 +131,7 @@ void GetDeviceListOnBlockingThread( ...@@ -131,7 +131,7 @@ void GetDeviceListOnBlockingThread(
std::vector<ScopedLibusbDeviceRef> scoped_devices; std::vector<ScopedLibusbDeviceRef> scoped_devices;
scoped_devices.reserve(device_count); scoped_devices.reserve(device_count);
for (ssize_t i = 0; i < device_count; ++i) for (ssize_t i = 0; i < device_count; ++i)
scoped_devices.emplace_back(platform_devices[i], usb_context); scoped_devices.emplace_back(platform_devices[i]);
// Free the list but don't unref the devices because ownership has been // Free the list but don't unref the devices because ownership has been
// been transfered to the elements of |scoped_devices|. // been transfered to the elements of |scoped_devices|.
...@@ -231,7 +231,6 @@ UsbServiceImpl::UsbServiceImpl() ...@@ -231,7 +231,6 @@ UsbServiceImpl::UsbServiceImpl()
device_observer_(this), device_observer_(this),
#endif #endif
weak_factory_(this) { weak_factory_(this) {
weak_self_ = weak_factory_.GetWeakPtr();
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, kBlockingTaskTraits, FROM_HERE, kBlockingTaskTraits,
base::Bind(&InitializeUsbContextOnBlockingThread, task_runner(), base::Bind(&InitializeUsbContextOnBlockingThread, task_runner(),
...@@ -362,7 +361,7 @@ void UsbServiceImpl::OnDeviceList( ...@@ -362,7 +361,7 @@ void UsbServiceImpl::OnDeviceList(
// Mark the existing device object visited and remove it from the list so // Mark the existing device object visited and remove it from the list so
// it will not be ignored. // it will not be ignored.
it->second->set_visited(true); it->second->set_visited(true);
device.Reset(); device.reset();
} }
} }
...@@ -383,7 +382,7 @@ void UsbServiceImpl::OnDeviceList( ...@@ -383,7 +382,7 @@ void UsbServiceImpl::OnDeviceList(
// that have been removed don't remain in |ignored_devices_| indefinitely. // that have been removed don't remain in |ignored_devices_| indefinitely.
ignored_devices_.clear(); ignored_devices_.clear();
for (auto& device : *devices) { for (auto& device : *devices) {
if (device.IsValid()) if (device.is_valid())
ignored_devices_.push_back(std::move(device)); ignored_devices_.push_back(std::move(device));
} }
...@@ -442,8 +441,8 @@ void UsbServiceImpl::EnumerateDevice(ScopedLibusbDeviceRef platform_device, ...@@ -442,8 +441,8 @@ void UsbServiceImpl::EnumerateDevice(ScopedLibusbDeviceRef platform_device,
devices_being_enumerated_.insert(platform_device.get()); devices_being_enumerated_.insert(platform_device.get());
auto device = base::MakeRefCounted<UsbDeviceImpl>(std::move(platform_device), auto device = base::MakeRefCounted<UsbDeviceImpl>(
descriptor); context_, std::move(platform_device), descriptor);
base::OnceClosure add_device = base::OnceClosure add_device =
base::BindOnce(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(), base::BindOnce(&UsbServiceImpl::AddDevice, weak_factory_.GetWeakPtr(),
refresh_complete, device); refresh_complete, device);
...@@ -459,8 +458,7 @@ void UsbServiceImpl::EnumerateDevice(ScopedLibusbDeviceRef platform_device, ...@@ -459,8 +458,7 @@ void UsbServiceImpl::EnumerateDevice(ScopedLibusbDeviceRef platform_device,
libusb_ref_device(device->platform_device()); libusb_ref_device(device->platform_device());
base::OnceClosure enumeration_failed = base::BindOnce( base::OnceClosure enumeration_failed = base::BindOnce(
&UsbServiceImpl::EnumerationFailed, weak_factory_.GetWeakPtr(), &UsbServiceImpl::EnumerationFailed, weak_factory_.GetWeakPtr(),
ScopedLibusbDeviceRef(device->platform_device(), context_), ScopedLibusbDeviceRef(device->platform_device()), refresh_complete);
refresh_complete);
device->Open(base::BindOnce( device->Open(base::BindOnce(
&OnDeviceOpenedReadDescriptors, descriptor.iManufacturer, &OnDeviceOpenedReadDescriptors, descriptor.iManufacturer,
...@@ -520,18 +518,18 @@ int LIBUSB_CALL UsbServiceImpl::HotplugCallback(libusb_context* context, ...@@ -520,18 +518,18 @@ int LIBUSB_CALL UsbServiceImpl::HotplugCallback(libusb_context* context,
// libusb does not transfer ownership of |device_raw| to this function so a // libusb does not transfer ownership of |device_raw| to this function so a
// reference must be taken here. // reference must be taken here.
libusb_ref_device(device_raw); libusb_ref_device(device_raw);
ScopedLibusbDeviceRef device(device_raw, self->context_); ScopedLibusbDeviceRef device(device_raw);
switch (event) { switch (event) {
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED: case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
self->task_runner()->PostTask( self->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceAdded, FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceAdded,
self->weak_self_, std::move(device))); base::Unretained(self), std::move(device)));
break; break;
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT: case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
self->task_runner()->PostTask( self->task_runner()->PostTask(
FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceRemoved, FROM_HERE, base::BindOnce(&UsbServiceImpl::OnPlatformDeviceRemoved,
self->weak_self_, std::move(device))); base::Unretained(self), std::move(device)));
break; break;
default: default:
NOTREACHED(); NOTREACHED();
......
...@@ -122,10 +122,6 @@ class UsbServiceImpl : ...@@ -122,10 +122,6 @@ class UsbServiceImpl :
ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_; ScopedObserver<DeviceMonitorWin, DeviceMonitorWin::Observer> device_observer_;
#endif // OS_WIN #endif // OS_WIN
// This WeakPtr is used to safely post hotplug events back to the thread this
// object lives on.
base::WeakPtr<UsbServiceImpl> weak_self_;
base::WeakPtrFactory<UsbServiceImpl> weak_factory_; base::WeakPtrFactory<UsbServiceImpl> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl); DISALLOW_COPY_AND_ASSIGN(UsbServiceImpl);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment