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

Unified Diff: device/usb/usb_device_handle_usbfs.cc

Issue 2797433005: Remove MessageLoop destruction observer from //device/usb (Closed)
Patch Set: Add test for shutdown Created 3 years, 8 months 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
« no previous file with comments | « device/usb/usb_device_handle_usbfs.h ('k') | device/usb/usb_service.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/usb/usb_device_handle_usbfs.cc
diff --git a/device/usb/usb_device_handle_usbfs.cc b/device/usb/usb_device_handle_usbfs.cc
index 791666605d4d11416d3dabacaa783e5cc7eda386..e347fe4dd228092425df7f26e6b823c0630e001a 100644
--- a/device/usb/usb_device_handle_usbfs.cc
+++ b/device/usb/usb_device_handle_usbfs.cc
@@ -19,7 +19,6 @@
#include "base/cancelable_callback.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
#include "base/posix/eintr_wrapper.h"
#include "base/stl_util.h"
#include "base/threading/thread_restrictions.h"
@@ -134,18 +133,24 @@ UsbTransferStatus ConvertTransferResult(int rc) {
} // namespace
-class UsbDeviceHandleUsbfs::FileThreadHelper
- : public base::MessageLoop::DestructionObserver {
+class UsbDeviceHandleUsbfs::FileThreadHelper {
public:
FileThreadHelper(int fd,
scoped_refptr<UsbDeviceHandleUsbfs> device_handle,
scoped_refptr<base::SequencedTaskRunner> task_runner);
- ~FileThreadHelper() override;
+ ~FileThreadHelper();
- static void Start(std::unique_ptr<FileThreadHelper> self);
+ void Start();
- // base::MessageLoop::DestructionObserver overrides.
- void WillDestroyCurrentMessageLoop() override;
+ void SetConfiguration(int configuration_value,
+ const ResultCallback& callback);
+ void ReleaseInterface(int interface_number, const ResultCallback& callback);
+ void SetInterface(int interface_number,
+ int alternate_setting,
+ const ResultCallback& callback);
+ void ResetDevice(const ResultCallback& callback);
+ void ClearHalt(uint8_t endpoint_address, const ResultCallback& callback);
+ void DiscardUrb(Transfer* transfer);
private:
// Called when |fd_| is writable without blocking.
@@ -160,6 +165,44 @@ class UsbDeviceHandleUsbfs::FileThreadHelper
DISALLOW_COPY_AND_ASSIGN(FileThreadHelper);
};
+struct UsbDeviceHandleUsbfs::Transfer {
+ Transfer() = delete;
+ Transfer(scoped_refptr<net::IOBuffer> buffer,
+ const TransferCallback& callback,
+ scoped_refptr<base::SingleThreadTaskRunner> callback_runner);
+ Transfer(scoped_refptr<net::IOBuffer> buffer,
+ const IsochronousTransferCallback& callback);
+ ~Transfer();
+
+ void* operator new(std::size_t size, size_t number_of_iso_packets);
+ void RunCallback(UsbTransferStatus status, size_t bytes_transferred);
+ void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets);
+
+ scoped_refptr<net::IOBuffer> control_transfer_buffer;
+ scoped_refptr<net::IOBuffer> buffer;
+ base::CancelableClosure timeout_closure;
+ bool cancelled = false;
+
+ // When the URB is |cancelled| these two flags track whether the URB has both
+ // been |discarded| and |reaped| since the possiblity of last-minute
+ // completion makes these two conditions race.
+ bool discarded = false;
+ bool reaped = false;
+
+ private:
+ TransferCallback callback;
+ IsochronousTransferCallback isoc_callback;
+ scoped_refptr<base::SingleThreadTaskRunner> callback_runner;
+
+ DISALLOW_COPY_AND_ASSIGN(Transfer);
+
+ public:
+ // The |urb| field must be the last in the struct so that the extra space
+ // allocated by the overridden new function above extends the length of its
+ // |iso_frame_desc| field.
+ usbdevfs_urb urb;
+};
+
UsbDeviceHandleUsbfs::FileThreadHelper::FileThreadHelper(
int fd,
scoped_refptr<UsbDeviceHandleUsbfs> device_handle,
@@ -168,28 +211,98 @@ UsbDeviceHandleUsbfs::FileThreadHelper::FileThreadHelper(
UsbDeviceHandleUsbfs::FileThreadHelper::~FileThreadHelper() {
DCHECK(thread_checker_.CalledOnValidThread());
- base::MessageLoop::current()->RemoveDestructionObserver(this);
}
-// static
-void UsbDeviceHandleUsbfs::FileThreadHelper::Start(
- std::unique_ptr<FileThreadHelper> self) {
+void UsbDeviceHandleUsbfs::FileThreadHelper::Start() {
base::ThreadRestrictions::AssertIOAllowed();
- self->thread_checker_.DetachFromThread();
+ thread_checker_.DetachFromThread();
+ DCHECK(thread_checker_.CalledOnValidThread());
// Linux indicates that URBs are available to reap by marking the file
// descriptor writable.
- self->watch_controller_ = base::FileDescriptorWatcher::WatchWritable(
- self->fd_, base::Bind(&FileThreadHelper::OnFileCanWriteWithoutBlocking,
- base::Unretained(self.get())));
+ watch_controller_ = base::FileDescriptorWatcher::WatchWritable(
+ fd_, base::Bind(&FileThreadHelper::OnFileCanWriteWithoutBlocking,
+ base::Unretained(this)));
+}
- // |self| is now owned by the current message loop.
- base::MessageLoop::current()->AddDestructionObserver(self.release());
+void UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration(
+ int configuration_value,
+ const ResultCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ int rc =
+ HANDLE_EINTR(ioctl(fd_, USBDEVFS_SETCONFIGURATION, &configuration_value));
+ if (rc)
+ USB_PLOG(DEBUG) << "Failed to set configuration " << configuration_value;
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleUsbfs::SetConfigurationComplete,
+ device_handle_, configuration_value, rc == 0, callback));
}
-void UsbDeviceHandleUsbfs::FileThreadHelper::WillDestroyCurrentMessageLoop() {
+void UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface(
+ int interface_number,
+ const ResultCallback& callback) {
DCHECK(thread_checker_.CalledOnValidThread());
- delete this;
+ int rc =
+ HANDLE_EINTR(ioctl(fd_, USBDEVFS_RELEASEINTERFACE, &interface_number));
+ if (rc) {
+ USB_PLOG(DEBUG) << "Failed to release interface " << interface_number;
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ } else {
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::ReleaseInterfaceComplete,
+ device_handle_, interface_number, callback));
+ }
+}
+
+void UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface(
+ int interface_number,
+ int alternate_setting,
+ const ResultCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ usbdevfs_setinterface cmd = {0};
+ cmd.interface = interface_number;
+ cmd.altsetting = alternate_setting;
+ int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_SETINTERFACE, &cmd));
+ if (rc) {
+ USB_PLOG(DEBUG) << "Failed to set interface " << interface_number
+ << " to alternate setting " << alternate_setting;
+ }
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
+}
+
+void UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice(
+ const ResultCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(reillyg): libusb releases interfaces before and then reclaims
+ // interfaces after a reset. We should probably do this too or document that
+ // callers have to call ClaimInterface as well.
+ int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_RESET, nullptr));
+ if (rc)
+ USB_PLOG(DEBUG) << "Failed to reset the device";
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
+}
+
+void UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt(
+ uint8_t endpoint_address,
+ const ResultCallback& callback) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ int tmp_endpoint = endpoint_address;
+ int rc = HANDLE_EINTR(ioctl(fd_, USBDEVFS_CLEAR_HALT, &tmp_endpoint));
+ if (rc) {
+ USB_PLOG(DEBUG) << "Failed to clear the stall condition on endpoint "
+ << static_cast<int>(endpoint_address);
+ }
+ task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
+}
+
+void UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb(Transfer* transfer) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ HANDLE_EINTR(ioctl(fd_, USBDEVFS_DISCARDURB, &transfer->urb));
+
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, device_handle_,
+ transfer));
}
void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking() {
@@ -221,44 +334,6 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking() {
base::Bind(&UsbDeviceHandleUsbfs::ReapedUrbs, device_handle_, urbs));
}
-struct UsbDeviceHandleUsbfs::Transfer {
- Transfer() = delete;
- Transfer(scoped_refptr<net::IOBuffer> buffer,
- const TransferCallback& callback,
- scoped_refptr<base::SingleThreadTaskRunner> callback_runner);
- Transfer(scoped_refptr<net::IOBuffer> buffer,
- const IsochronousTransferCallback& callback);
- ~Transfer();
-
- void* operator new(std::size_t size, size_t number_of_iso_packets);
- void RunCallback(UsbTransferStatus status, size_t bytes_transferred);
- void RunIsochronousCallback(const std::vector<IsochronousPacket>& packets);
-
- scoped_refptr<net::IOBuffer> control_transfer_buffer;
- scoped_refptr<net::IOBuffer> buffer;
- base::CancelableClosure timeout_closure;
- bool cancelled = false;
-
- // When the URB is |cancelled| these two flags track whether the URB has both
- // been |discarded| and |reaped| since the possiblity of last-minute
- // completion makes these two conditions race.
- bool discarded = false;
- bool reaped = false;
-
- private:
- TransferCallback callback;
- IsochronousTransferCallback isoc_callback;
- scoped_refptr<base::SingleThreadTaskRunner> callback_runner;
-
- DISALLOW_COPY_AND_ASSIGN(Transfer);
-
- public:
- // The |urb| field must be the last in the struct so that the extra space
- // allocated by the overridden new function above extends the length of its
- // |iso_frame_desc| field.
- usbdevfs_urb urb;
-};
-
UsbDeviceHandleUsbfs::Transfer::Transfer(
scoped_refptr<net::IOBuffer> buffer,
const TransferCallback& callback,
@@ -325,11 +400,10 @@ UsbDeviceHandleUsbfs::UsbDeviceHandleUsbfs(
task_runner_ = base::ThreadTaskRunnerHandle::Get();
- std::unique_ptr<FileThreadHelper> helper(
- new FileThreadHelper(fd_.get(), this, task_runner_));
- helper_ = helper.get();
+ helper_.reset(new FileThreadHelper(fd_.get(), this, task_runner_));
blocking_task_runner_->PostTask(
- FROM_HERE, base::Bind(&FileThreadHelper::Start, base::Passed(&helper)));
+ FROM_HERE,
+ base::Bind(&FileThreadHelper::Start, base::Unretained(helper_.get())));
scheib 2017/04/04 20:17:15 blocking_task_runner is ref counted. And helper_ i
Reilly Grant (use Gerrit) 2017/04/04 20:31:40 helper_ can only be destroyed on the FILE thread a
}
scoped_refptr<UsbDevice> UsbDeviceHandleUsbfs::GetDevice() const {
@@ -359,8 +433,10 @@ void UsbDeviceHandleUsbfs::SetConfiguration(int configuration_value,
// to the device so it must be performed on a thread where it is okay to
// block.
blocking_task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::SetConfigurationBlocking,
- this, configuration_value, callback));
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetConfiguration,
+ base::Unretained(helper_.get()), configuration_value,
+ callback));
}
void UsbDeviceHandleUsbfs::ClaimInterface(int interface_number,
@@ -394,8 +470,9 @@ void UsbDeviceHandleUsbfs::ReleaseInterface(int interface_number,
// device to restore alternate setting 0 so it must be performed on a thread
// where it is okay to block.
blocking_task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::ReleaseInterfaceBlocking,
- this, interface_number, callback));
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ReleaseInterface,
+ base::Unretained(helper_.get()), interface_number, callback));
}
void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting(
@@ -406,8 +483,10 @@ void UsbDeviceHandleUsbfs::SetInterfaceAlternateSetting(
// request to the device so it must be performed on a thread where it is okay
// to block.
blocking_task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::SetInterfaceBlocking, this,
- interface_number, alternate_setting, callback));
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::SetInterface,
+ base::Unretained(helper_.get()), interface_number,
+ alternate_setting, callback));
}
void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) {
@@ -416,7 +495,8 @@ void UsbDeviceHandleUsbfs::ResetDevice(const ResultCallback& callback) {
// is okay to block.
blocking_task_runner_->PostTask(
FROM_HERE,
- base::Bind(&UsbDeviceHandleUsbfs::ResetDeviceBlocking, this, callback));
+ base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ResetDevice,
+ base::Unretained(helper_.get()), callback));
}
void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address,
@@ -425,8 +505,9 @@ void UsbDeviceHandleUsbfs::ClearHalt(uint8_t endpoint_address,
// request to the device so it must be performed on a thread where it is okay
// to block.
blocking_task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::ClearHaltBlocking, this,
- endpoint_address, callback));
+ FROM_HERE,
+ base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::ClearHalt,
+ base::Unretained(helper_.get()), endpoint_address, callback));
}
void UsbDeviceHandleUsbfs::ControlTransfer(UsbEndpointDirection direction,
@@ -527,29 +608,13 @@ UsbDeviceHandleUsbfs::~UsbDeviceHandleUsbfs() {
void UsbDeviceHandleUsbfs::ReleaseFileDescriptor() {
ignore_result(fd_.release());
- delete helper_;
+ helper_.reset();
}
void UsbDeviceHandleUsbfs::CloseBlocking() {
fd_.reset(-1);
- delete helper_;
-}
-
-void UsbDeviceHandleUsbfs::SetConfigurationBlocking(
- int configuration_value,
- const ResultCallback& callback) {
- if (!fd_.is_valid()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- return;
- }
-
- int rc = HANDLE_EINTR(
- ioctl(fd_.get(), USBDEVFS_SETCONFIGURATION, &configuration_value));
- if (rc)
- USB_PLOG(DEBUG) << "Failed to set configuration " << configuration_value;
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::SetConfigurationComplete,
- this, configuration_value, rc == 0, callback));
+ helper_.reset();
+ ;
scheib 2017/04/04 20:17:15 ;
Reilly Grant (use Gerrit) 2017/04/04 20:31:40 Done.
}
void UsbDeviceHandleUsbfs::SetConfigurationComplete(
@@ -565,26 +630,6 @@ void UsbDeviceHandleUsbfs::SetConfigurationComplete(
callback.Run(success);
}
-void UsbDeviceHandleUsbfs::ReleaseInterfaceBlocking(
- int interface_number,
- const ResultCallback& callback) {
- if (!fd_.is_valid()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- return;
- }
-
- int rc = HANDLE_EINTR(
- ioctl(fd_.get(), USBDEVFS_RELEASEINTERFACE, &interface_number));
- if (rc) {
- USB_PLOG(DEBUG) << "Failed to release interface " << interface_number;
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- } else {
- task_runner_->PostTask(
- FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::ReleaseInterfaceComplete,
- this, interface_number, callback));
- }
-}
-
void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete(
int interface_number,
const ResultCallback& callback) {
@@ -595,57 +640,6 @@ void UsbDeviceHandleUsbfs::ReleaseInterfaceComplete(
callback.Run(true);
}
-void UsbDeviceHandleUsbfs::SetInterfaceBlocking(
- int interface_number,
- int alternate_setting,
- const ResultCallback& callback) {
- if (!fd_.is_valid()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- return;
- }
-
- usbdevfs_setinterface cmd = {0};
- cmd.interface = interface_number;
- cmd.altsetting = alternate_setting;
- int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_SETINTERFACE, &cmd));
- if (rc) {
- USB_PLOG(DEBUG) << "Failed to set interface " << interface_number
- << " to alternate setting " << alternate_setting;
- }
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
-}
-
-void UsbDeviceHandleUsbfs::ResetDeviceBlocking(const ResultCallback& callback) {
- if (!fd_.is_valid()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- return;
- }
-
- // TODO(reillyg): libusb releases interfaces before and then reclaims
- // interfaces after a reset. We should probably do this too or document that
- // callers have to call ClaimInterface as well.
- int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_RESET, nullptr));
- if (rc)
- USB_PLOG(DEBUG) << "Failed to reset the device";
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
-}
-
-void UsbDeviceHandleUsbfs::ClearHaltBlocking(uint8_t endpoint_address,
- const ResultCallback& callback) {
- if (!fd_.is_valid()) {
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
- return;
- }
-
- int tmp_endpoint = endpoint_address;
- int rc = HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_CLEAR_HALT, &tmp_endpoint));
- if (rc) {
- USB_PLOG(DEBUG) << "Failed to clear the stall condition on endpoint "
- << static_cast<int>(endpoint_address);
- }
- task_runner_->PostTask(FROM_HERE, base::Bind(callback, rc == 0));
-}
-
void UsbDeviceHandleUsbfs::IsochronousTransferInternal(
uint8_t endpoint_address,
scoped_refptr<net::IOBuffer> buffer,
@@ -875,18 +869,10 @@ void UsbDeviceHandleUsbfs::CancelTransfer(Transfer* transfer,
}
blocking_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&UsbDeviceHandleUsbfs::DiscardUrbBlocking, this, transfer));
+ FROM_HERE, base::Bind(&UsbDeviceHandleUsbfs::FileThreadHelper::DiscardUrb,
+ base::Unretained(helper_.get()), transfer));
}
-void UsbDeviceHandleUsbfs::DiscardUrbBlocking(Transfer* transfer) {
- if (fd_.is_valid())
- HANDLE_EINTR(ioctl(fd_.get(), USBDEVFS_DISCARDURB, &transfer->urb));
-
- task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&UsbDeviceHandleUsbfs::UrbDiscarded, this, transfer));
-}
void UsbDeviceHandleUsbfs::UrbDiscarded(Transfer* transfer) {
transfer->discarded = true;
« no previous file with comments | « device/usb/usb_device_handle_usbfs.h ('k') | device/usb/usb_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698