libchromeos: use chromeos::MessageLoop in AsynchronousSignalHandler.

This patch makes AsynchronousSignalHandler use the chromeos::MessageLoop
interface instead of rely on the message loop being the
base::MessageLoopForIO.

BUG=chromium:499886
TEST=FEATURES=test emerge-link libchromeos

Change-Id: Ib206e99ca48098d1998725c8103c271e7b808a6d
Reviewed-on: https://chromium-review.googlesource.com/287001
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Trybot-Ready: Alex Deymo <deymo@chromium.org>
Tested-by: Alex Deymo <deymo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/chromeos/asynchronous_signal_handler.cc b/chromeos/asynchronous_signal_handler.cc
index 5bb430d..4d188c7 100644
--- a/chromeos/asynchronous_signal_handler.cc
+++ b/chromeos/asynchronous_signal_handler.cc
@@ -8,9 +8,11 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <base/bind.h>
 #include <base/files/file_util.h>
 #include <base/logging.h>
 #include <base/message_loop/message_loop.h>
+#include <base/posix/eintr_wrapper.h>
 
 namespace {
 const int kInvalidDescriptor = -1;
@@ -19,8 +21,7 @@
 namespace chromeos {
 
 AsynchronousSignalHandler::AsynchronousSignalHandler()
-    : fd_watcher_(new base::MessageLoopForIO::FileDescriptorWatcher),
-      descriptor_(kInvalidDescriptor) {
+    : descriptor_(kInvalidDescriptor) {
   CHECK_EQ(sigemptyset(&signal_mask_), 0) << "Failed to initialize signal mask";
   CHECK_EQ(sigemptyset(&saved_signal_mask_), 0)
       << "Failed to initialize signal mask";
@@ -28,9 +29,9 @@
 
 AsynchronousSignalHandler::~AsynchronousSignalHandler() {
   if (descriptor_ != kInvalidDescriptor) {
-    fd_watcher_->StopWatchingFileDescriptor();
+    MessageLoop::current()->CancelTask(fd_watcher_task_);
 
-    if (close(descriptor_) != 0)
+    if (IGNORE_EINTR(close(descriptor_)) != 0)
       PLOG(WARNING) << "Failed to close file descriptor";
 
     descriptor_ = kInvalidDescriptor;
@@ -44,12 +45,14 @@
   descriptor_ =
       signalfd(descriptor_, &signal_mask_, SFD_CLOEXEC | SFD_NONBLOCK);
   CHECK_NE(kInvalidDescriptor, descriptor_);
-  CHECK(base::MessageLoopForIO::current()->WatchFileDescriptor(
+  fd_watcher_task_ = MessageLoop::current()->WatchFileDescriptor(
+      FROM_HERE,
       descriptor_,
+      MessageLoop::WatchMode::kWatchRead,
       true,
-      base::MessageLoopForIO::WATCH_READ,
-      fd_watcher_.get(),
-      this))
+      base::Bind(&AsynchronousSignalHandler::OnFileCanReadWithoutBlocking,
+                 base::Unretained(this)));
+  CHECK(fd_watcher_task_ != MessageLoop::kTaskIdNull)
       << "Watching shutdown pipe failed.";
 }
 
@@ -68,9 +71,10 @@
   }
 }
 
-void AsynchronousSignalHandler::OnFileCanReadWithoutBlocking(int fd) {
+void AsynchronousSignalHandler::OnFileCanReadWithoutBlocking() {
   struct signalfd_siginfo info;
-  while (base::ReadFromFD(fd, reinterpret_cast<char*>(&info), sizeof(info))) {
+  while (base::ReadFromFD(descriptor_,
+                          reinterpret_cast<char*>(&info), sizeof(info))) {
     int signal = info.ssi_signo;
     Callbacks::iterator callback_it = registered_callbacks_.find(signal);
     if (callback_it == registered_callbacks_.end()) {
@@ -87,10 +91,6 @@
   }
 }
 
-void AsynchronousSignalHandler::OnFileCanWriteWithoutBlocking(int fd) {
-  NOTREACHED();
-}
-
 void AsynchronousSignalHandler::ResetSignal(int signal) {
   CHECK_EQ(0, sigdelset(&signal_mask_, signal));
   UpdateSignals();
diff --git a/chromeos/asynchronous_signal_handler.h b/chromeos/asynchronous_signal_handler.h
index 8da4a99..407a7ed 100644
--- a/chromeos/asynchronous_signal_handler.h
+++ b/chromeos/asynchronous_signal_handler.h
@@ -16,16 +16,16 @@
 #include <base/memory/scoped_ptr.h>
 #include <base/message_loop/message_loop.h>
 #include <chromeos/chromeos_export.h>
+#include <chromeos/message_loops/message_loop.h>
 
 namespace chromeos {
 // Sets up signal handlers for registered signals, and converts signal receipt
 // into a write on a pipe. Watches that pipe for data and, when some appears,
 // execute the associated callback.
-class CHROMEOS_EXPORT AsynchronousSignalHandler
-    : public base::MessageLoopForIO::Watcher {
+class CHROMEOS_EXPORT AsynchronousSignalHandler final {
  public:
   AsynchronousSignalHandler();
-  ~AsynchronousSignalHandler() override;
+  ~AsynchronousSignalHandler();
 
   // The callback called when a signal is received.
   typedef base::Callback<bool(const struct signalfd_siginfo&)> SignalHandler;
@@ -47,13 +47,13 @@
   // Unregister a previously registered handler for the given |signal|.
   void UnregisterHandler(int signal);
 
-  // Implementation of base::MessageLoopForIO::Watcher
-  void OnFileCanReadWithoutBlocking(int fd) override;
-  void OnFileCanWriteWithoutBlocking(int fd) override;
+  // Called from the main loop when we can read from |descriptor_|, indicated
+  // that a signal was processed.
+  void OnFileCanReadWithoutBlocking();
 
  private:
   // Controller used to manage watching of signalling pipe.
-  scoped_ptr<base::MessageLoopForIO::FileDescriptorWatcher> fd_watcher_;
+  MessageLoop::TaskId fd_watcher_task_{MessageLoop::kTaskIdNull};
 
   // The registered callbacks.
   typedef std::map<int, SignalHandler> Callbacks;
diff --git a/chromeos/asynchronous_signal_handler_unittest.cc b/chromeos/asynchronous_signal_handler_unittest.cc
index 44895aa..949b02a 100644
--- a/chromeos/asynchronous_signal_handler_unittest.cc
+++ b/chromeos/asynchronous_signal_handler_unittest.cc
@@ -14,6 +14,7 @@
 #include <base/macros.h>
 #include <base/message_loop/message_loop.h>
 #include <base/run_loop.h>
+#include <chromeos/message_loops/base_message_loop.h>
 #include <gtest/gtest.h>
 
 namespace chromeos {
@@ -23,23 +24,22 @@
   AsynchronousSignalHandlerTest() {}
   virtual ~AsynchronousSignalHandlerTest() {}
 
-  virtual void SetUp() { handler_.Init(); }
+  virtual void SetUp() {
+    chromeos_loop_.SetAsCurrent();
+    handler_.Init();
+  }
 
   virtual void TearDown() {}
 
   bool RecordInfoAndQuit(bool response, const struct signalfd_siginfo& info) {
     infos_.push_back(info);
-    loop_.PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
+    chromeos_loop_.PostTask(FROM_HERE, chromeos_loop_.QuitClosure());
     return response;
   }
 
-  void Run() {
-    base::RunLoop run_loop;
-    run_loop.Run();
-  }
-
  protected:
-  base::MessageLoopForIO loop_;
+  base::MessageLoopForIO base_loop_;
+  BaseMessageLoop chromeos_loop_{&base_loop_};
   std::vector<struct signalfd_siginfo> infos_;
   AsynchronousSignalHandler handler_;
 
@@ -57,7 +57,7 @@
   EXPECT_EQ(0, kill(getpid(), SIGTERM));
 
   // Spin the message loop.
-  Run();
+  MessageLoop::current()->Run();
 
   ASSERT_EQ(1, infos_.size());
   EXPECT_EQ(SIGTERM, infos_[0].ssi_signo);
@@ -73,7 +73,7 @@
   EXPECT_EQ(0, kill(getpid(), SIGCHLD));
 
   // Spin the message loop.
-  Run();
+  MessageLoop::current()->Run();
 
   ASSERT_EQ(1, infos_.size());
   EXPECT_EQ(SIGCHLD, infos_[0].ssi_signo);
@@ -81,10 +81,11 @@
   EXPECT_EQ(0, kill(getpid(), SIGCHLD));
 
   // Run the loop with a timeout, as no message are expected.
-  loop_.PostDelayedTask(FROM_HERE,
-                        base::MessageLoop::QuitClosure(),
-                        base::TimeDelta::FromMilliseconds(10));
-  Run();
+  chromeos_loop_.PostDelayedTask(FROM_HERE,
+                                 base::Bind(&MessageLoop::BreakLoop,
+                                            base::Unretained(&chromeos_loop_)),
+                                 base::TimeDelta::FromMilliseconds(10));
+  MessageLoop::current()->Run();
 
   // The signal handle should have been unregistered. No new message are
   // expected.
@@ -103,7 +104,7 @@
     EXPECT_EQ(0, kill(getpid(), SIGCHLD));
 
     // Spin the message loop.
-    Run();
+    MessageLoop::current()->Run();
   }
 
   ASSERT_EQ(NB_SIGNALS, infos_.size());
@@ -125,7 +126,7 @@
 
   EXPECT_EQ(0, infos_.size());
   // Spin the message loop.
-  Run();
+  MessageLoop::current()->Run();
 
   ASSERT_EQ(1, infos_.size());
   EXPECT_EQ(SIGCHLD, infos_[0].ssi_signo);
diff --git a/chromeos/daemons/daemon.h b/chromeos/daemons/daemon.h
index 639037b..f36ca7b 100644
--- a/chromeos/daemons/daemon.h
+++ b/chromeos/daemons/daemon.h
@@ -96,13 +96,13 @@
   // |at_exit_manager_| must be first to make sure it is initialized before
   // other members, especially the |message_loop_|.
   base::AtExitManager at_exit_manager_;
-  // A helper to dispatch signal handlers asynchronously, so that the main
-  // system signal handler returns as soon as possible.
-  AsynchronousSignalHandler async_signal_handler_;
   // The main message loop for the daemon.
   base::MessageLoopForIO message_loop_;
   // The chromeos wrapper for the main message loop.
   BaseMessageLoop chromeos_message_loop_{&message_loop_};
+  // A helper to dispatch signal handlers asynchronously, so that the main
+  // system signal handler returns as soon as possible.
+  AsynchronousSignalHandler async_signal_handler_;
   // Process exit code specified in QuitWithExitCode() method call.
   int exit_code_;