Commit 80da60ef authored by fdoray's avatar fdoray Committed by Commit bot

Use FileDescriptorWatcher in UsbDeviceHandleUsbfs.

This allows UsbDeviceHandleUsbfs to be used from any thread that
instantiates a FileDescriptorWatcher (not just threads that run
a MessageLoopForIO). This will facilitate the migration of
BrowserThreads to base/task_scheduler.

BUG=645114

Review-Url: https://codereview.chromium.org/2391633002
Cr-Commit-Position: refs/heads/master@{#422859}
parent 1c81ee4b
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/cancelable_callback.h" #include "base/cancelable_callback.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/message_loop/message_pump_libevent.h"
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
...@@ -135,8 +135,7 @@ UsbTransferStatus ConvertTransferResult(int rc) { ...@@ -135,8 +135,7 @@ UsbTransferStatus ConvertTransferResult(int rc) {
} // namespace } // namespace
class UsbDeviceHandleUsbfs::FileThreadHelper class UsbDeviceHandleUsbfs::FileThreadHelper
: public base::MessagePumpLibevent::Watcher, : public base::MessageLoop::DestructionObserver {
public base::MessageLoop::DestructionObserver {
public: public:
FileThreadHelper(int fd, FileThreadHelper(int fd,
scoped_refptr<UsbDeviceHandleUsbfs> device_handle, scoped_refptr<UsbDeviceHandleUsbfs> device_handle,
...@@ -145,18 +144,17 @@ class UsbDeviceHandleUsbfs::FileThreadHelper ...@@ -145,18 +144,17 @@ class UsbDeviceHandleUsbfs::FileThreadHelper
static void Start(std::unique_ptr<FileThreadHelper> self); static void Start(std::unique_ptr<FileThreadHelper> self);
// base::MessagePumpLibevent::Watcher overrides.
void OnFileCanReadWithoutBlocking(int fd) override;
void OnFileCanWriteWithoutBlocking(int fd) override;
// base::MessageLoop::DestructionObserver overrides. // base::MessageLoop::DestructionObserver overrides.
void WillDestroyCurrentMessageLoop() override; void WillDestroyCurrentMessageLoop() override;
private: private:
// Called when |fd_| is writable without blocking.
void OnFileCanWriteWithoutBlocking();
int fd_; int fd_;
scoped_refptr<UsbDeviceHandleUsbfs> device_handle_; scoped_refptr<UsbDeviceHandleUsbfs> device_handle_;
scoped_refptr<base::SequencedTaskRunner> task_runner_; scoped_refptr<base::SequencedTaskRunner> task_runner_;
base::MessagePumpLibevent::FileDescriptorWatcher file_watcher_; std::unique_ptr<base::FileDescriptorWatcher::Controller> watch_controller_;
base::ThreadChecker thread_checker_; base::ThreadChecker thread_checker_;
DISALLOW_COPY_AND_ASSIGN(FileThreadHelper); DISALLOW_COPY_AND_ASSIGN(FileThreadHelper);
...@@ -181,25 +179,21 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::Start( ...@@ -181,25 +179,21 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::Start(
// Linux indicates that URBs are available to reap by marking the file // Linux indicates that URBs are available to reap by marking the file
// descriptor writable. // descriptor writable.
if (!base::MessageLoopForIO::current()->WatchFileDescriptor( self->watch_controller_ = base::FileDescriptorWatcher::WatchWritable(
self->fd_, true, base::MessageLoopForIO::WATCH_WRITE, self->fd_, base::Bind(&FileThreadHelper::OnFileCanWriteWithoutBlocking,
&self->file_watcher_, self.get())) { base::Unretained(self.get())));
USB_LOG(ERROR) << "Failed to start watching device file descriptor.";
}
// |self| is now owned by the current message loop. // |self| is now owned by the current message loop.
base::MessageLoop::current()->AddDestructionObserver(self.release()); base::MessageLoop::current()->AddDestructionObserver(self.release());
} }
void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanReadWithoutBlocking( void UsbDeviceHandleUsbfs::FileThreadHelper::WillDestroyCurrentMessageLoop() {
int fd) { DCHECK(thread_checker_.CalledOnValidThread());
NOTREACHED(); // Only listening for writability. delete this;
} }
void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking( void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking() {
int fd) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_EQ(fd_, fd);
const size_t MAX_URBS_PER_EVENT = 10; const size_t MAX_URBS_PER_EVENT = 10;
std::vector<usbdevfs_urb*> urbs; std::vector<usbdevfs_urb*> urbs;
...@@ -214,7 +208,7 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking( ...@@ -214,7 +208,7 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking(
if (errno == ENODEV) { if (errno == ENODEV) {
// Device has disconnected. Stop watching the file descriptor to avoid // Device has disconnected. Stop watching the file descriptor to avoid
// looping until |device_handle_| is closed. // looping until |device_handle_| is closed.
file_watcher_.StopWatchingFileDescriptor(); watch_controller_.reset();
break; break;
} }
} else { } else {
...@@ -227,11 +221,6 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking( ...@@ -227,11 +221,6 @@ void UsbDeviceHandleUsbfs::FileThreadHelper::OnFileCanWriteWithoutBlocking(
base::Bind(&UsbDeviceHandleUsbfs::ReapedUrbs, device_handle_, urbs)); base::Bind(&UsbDeviceHandleUsbfs::ReapedUrbs, device_handle_, urbs));
} }
void UsbDeviceHandleUsbfs::FileThreadHelper::WillDestroyCurrentMessageLoop() {
DCHECK(thread_checker_.CalledOnValidThread());
delete this;
}
struct UsbDeviceHandleUsbfs::Transfer { struct UsbDeviceHandleUsbfs::Transfer {
Transfer() = delete; Transfer() = delete;
Transfer(scoped_refptr<net::IOBuffer> buffer, Transfer(scoped_refptr<net::IOBuffer> buffer,
......
...@@ -27,8 +27,8 @@ namespace device { ...@@ -27,8 +27,8 @@ namespace device {
class UsbDeviceHandleUsbfs : public UsbDeviceHandle { class UsbDeviceHandleUsbfs : public UsbDeviceHandle {
public: public:
// Constructs a new device handle from an existing |device| and open file // Constructs a new device handle from an existing |device| and open file
// descriptor to that device. |blocking_task_runner| must have a // descriptor to that device. |blocking_task_runner| must run tasks on a
// MessageLoopForIO. // thread that supports FileDescriptorWatcher.
UsbDeviceHandleUsbfs( UsbDeviceHandleUsbfs(
scoped_refptr<UsbDevice> device, scoped_refptr<UsbDevice> device,
base::ScopedFD fd, base::ScopedFD fd,
......
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