diff options
author | Alex Deymo <deymo@chromium.org> | 2015-07-20 17:27:51 -0700 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-07-24 21:53:52 +0000 |
commit | fd626d7e3f116f9a159ea82b3789795296adac91 (patch) | |
tree | bc1e716da18965fe880fddb05b3fd3539d57cfef | |
parent | 30ef318cd1d94e896a277324c68b89798e3dbbdd (diff) | |
download | libbrillo-fd626d7e3f116f9a159ea82b3789795296adac91.tar.gz |
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>
-rw-r--r-- | chromeos/asynchronous_signal_handler.cc | 28 | ||||
-rw-r--r-- | chromeos/asynchronous_signal_handler.h | 14 | ||||
-rw-r--r-- | chromeos/asynchronous_signal_handler_unittest.cc | 33 | ||||
-rw-r--r-- | chromeos/daemons/daemon.h | 6 |
4 files changed, 41 insertions, 40 deletions
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 @@ const int kInvalidDescriptor = -1; 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() 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 @@ void AsynchronousSignalHandler::Init() { 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::UnregisterHandler(int signal) { } } -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::OnFileCanReadWithoutBlocking(int fd) { } } -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 @@ class CHROMEOS_EXPORT AsynchronousSignalHandler // 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 @@ class AsynchronousSignalHandlerTest : public ::testing::Test { 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 @@ TEST_F(AsynchronousSignalHandlerTest, CheckTerm) { 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 @@ TEST_F(AsynchronousSignalHandlerTest, CheckSignalUnregistration) { 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 @@ TEST_F(AsynchronousSignalHandlerTest, CheckSignalUnregistration) { 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 @@ TEST_F(AsynchronousSignalHandlerTest, CheckMultipleSignal) { EXPECT_EQ(0, kill(getpid(), SIGCHLD)); // Spin the message loop. - Run(); + MessageLoop::current()->Run(); } ASSERT_EQ(NB_SIGNALS, infos_.size()); @@ -125,7 +126,7 @@ TEST_F(AsynchronousSignalHandlerTest, CheckChld) { 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 @@ class CHROMEOS_EXPORT Daemon { // |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_; |