Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(438)

Unified Diff: device/usb/usb_service_impl.cc

Issue 2557073004: Call libusb_init on the FILE thread. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« device/usb/usb_service_impl.h ('K') | « device/usb/usb_service_impl.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/usb/usb_service_impl.cc
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc
index 083298d354619dee0f93a59e33594cf8eea4a25f..2f5883b0678aababf05afc3b261d5111b8ae4546 100644
--- a/device/usb/usb_service_impl.cc
+++ b/device/usb/usb_service_impl.cc
@@ -80,11 +80,28 @@ bool IsWinUsbInterface(const std::string& device_path) {
#endif // OS_WIN
+void InitializeUsbContextOnBlockingThread(
+ scoped_refptr<base::SequencedTaskRunner> task_runner,
+ const base::Callback<void(scoped_refptr<UsbContext>)>& callback) {
+ scoped_refptr<UsbContext> context;
+ PlatformUsbContext platform_context = nullptr;
+ int rv = libusb_init(&platform_context);
+ if (rv == LIBUSB_SUCCESS && platform_context) {
+ context = new UsbContext(platform_context);
+ } else {
+ USB_LOG(DEBUG) << "Failed to initialize libusb: "
+ << ConvertPlatformUsbErrorToString(rv);
+ }
+
+ task_runner->PostTask(FROM_HERE,
+ base::Bind(callback, base::Passed(&context)));
+}
+
void GetDeviceListOnBlockingThread(
const std::string& new_device_path,
scoped_refptr<UsbContext> usb_context,
scoped_refptr<base::SequencedTaskRunner> task_runner,
- base::Callback<void(libusb_device**, size_t)> callback) {
+ const base::Callback<void(libusb_device**, size_t)>& callback) {
#if defined(OS_WIN)
if (!new_device_path.empty()) {
if (!IsWinUsbInterface(new_device_path)) {
@@ -204,33 +221,11 @@ UsbServiceImpl::UsbServiceImpl(
device_observer_(this),
#endif
weak_factory_(this) {
- PlatformUsbContext platform_context = nullptr;
- int rv = libusb_init(&platform_context);
- if (rv != LIBUSB_SUCCESS || !platform_context) {
- USB_LOG(DEBUG) << "Failed to initialize libusb: "
- << ConvertPlatformUsbErrorToString(rv);
- return;
- }
- context_ = new UsbContext(platform_context);
-
- rv = libusb_hotplug_register_callback(
- context_->context(),
- static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
- LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
- static_cast<libusb_hotplug_flag>(0), LIBUSB_HOTPLUG_MATCH_ANY,
- LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
- &UsbServiceImpl::HotplugCallback, this, &hotplug_handle_);
- if (rv == LIBUSB_SUCCESS) {
- hotplug_enabled_ = true;
- }
-
- RefreshDevices();
-#if defined(OS_WIN)
- DeviceMonitorWin* device_monitor = DeviceMonitorWin::GetForAllInterfaces();
- if (device_monitor) {
- device_observer_.Add(device_monitor);
- }
-#endif // OS_WIN
+ blocking_task_runner->PostTask(
+ FROM_HERE, base::Bind(&InitializeUsbContextOnBlockingThread,
+ base::ThreadTaskRunnerHandle::Get(),
+ base::Bind(&UsbServiceImpl::OnUsbContext,
+ weak_factory_.GetWeakPtr())));
}
UsbServiceImpl::~UsbServiceImpl() {
@@ -243,7 +238,7 @@ UsbServiceImpl::~UsbServiceImpl() {
void UsbServiceImpl::GetDevices(const GetDevicesCallback& callback) {
DCHECK(CalledOnValidThread());
- if (!context_) {
+ if (usb_unavailable_) {
task_runner()->PostTask(
FROM_HERE,
base::Bind(callback, std::vector<scoped_refptr<UsbDevice>>()));
@@ -284,13 +279,39 @@ void UsbServiceImpl::OnDeviceRemoved(const GUID& class_guid,
#endif // OS_WIN
+void UsbServiceImpl::OnUsbContext(scoped_refptr<UsbContext> context) {
+ if (!context) {
+ usb_unavailable_ = true;
+ return;
+ }
+
+ context_ = std::move(context);
+
+ int rv = libusb_hotplug_register_callback(
+ context_->context(),
+ static_cast<libusb_hotplug_event>(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
+ LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
+ static_cast<libusb_hotplug_flag>(0), LIBUSB_HOTPLUG_MATCH_ANY,
+ LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
+ &UsbServiceImpl::HotplugCallback, this, &hotplug_handle_);
+ if (rv == LIBUSB_SUCCESS)
+ hotplug_enabled_ = true;
+
+ // This will call any enumeration callbacks queued while initializing.
+ RefreshDevices();
+
+#if defined(OS_WIN)
+ DeviceMonitorWin* device_monitor = DeviceMonitorWin::GetForAllInterfaces();
+ if (device_monitor)
+ device_observer_.Add(device_monitor);
+#endif // OS_WIN
+}
+
void UsbServiceImpl::RefreshDevices() {
DCHECK(CalledOnValidThread());
- DCHECK(context_);
- if (enumeration_in_progress_) {
+ if (!context_ || enumeration_in_progress_)
return;
- }
enumeration_in_progress_ = true;
DCHECK(devices_being_enumerated_.empty());
@@ -487,26 +508,19 @@ int LIBUSB_CALL UsbServiceImpl::HotplugCallback(libusb_context* context,
// and so guarantees that this function will not be called by the event
// processing thread after it has been deregistered.
UsbServiceImpl* self = reinterpret_cast<UsbServiceImpl*>(user_data);
+ DCHECK(!self->task_runner()->BelongsToCurrentThread());
switch (event) {
case LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED:
libusb_ref_device(device); // Released in OnPlatformDeviceAdded.
- if (self->task_runner()->BelongsToCurrentThread()) {
- self->OnPlatformDeviceAdded(device);
- } else {
- self->task_runner()->PostTask(
- FROM_HERE, base::Bind(&UsbServiceImpl::OnPlatformDeviceAdded,
- base::Unretained(self), device));
- }
+ self->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&UsbServiceImpl::OnPlatformDeviceAdded,
+ base::Unretained(self), device));
break;
case LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT:
libusb_ref_device(device); // Released in OnPlatformDeviceRemoved.
- if (self->task_runner()->BelongsToCurrentThread()) {
- self->OnPlatformDeviceRemoved(device);
- } else {
- self->task_runner()->PostTask(
- FROM_HERE, base::Bind(&UsbServiceImpl::OnPlatformDeviceRemoved,
- base::Unretained(self), device));
- }
+ self->task_runner()->PostTask(
+ FROM_HERE, base::Bind(&UsbServiceImpl::OnPlatformDeviceRemoved,
+ base::Unretained(self), device));
break;
default:
NOTREACHED();
« device/usb/usb_service_impl.h ('K') | « device/usb/usb_service_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698