aboutsummaryrefslogtreecommitdiffstats
path: root/brillo/asynchronous_signal_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'brillo/asynchronous_signal_handler.cc')
-rw-r--r--brillo/asynchronous_signal_handler.cc90
1 files changed, 44 insertions, 46 deletions
diff --git a/brillo/asynchronous_signal_handler.cc b/brillo/asynchronous_signal_handler.cc
index b8ec529..38b1787 100644
--- a/brillo/asynchronous_signal_handler.cc
+++ b/brillo/asynchronous_signal_handler.cc
@@ -11,49 +11,41 @@
#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;
-} // namespace
namespace brillo {
-AsynchronousSignalHandler::AsynchronousSignalHandler()
- : descriptor_(kInvalidDescriptor) {
+AsynchronousSignalHandler::AsynchronousSignalHandler() {
CHECK_EQ(sigemptyset(&signal_mask_), 0) << "Failed to initialize signal mask";
CHECK_EQ(sigemptyset(&saved_signal_mask_), 0)
<< "Failed to initialize signal mask";
}
AsynchronousSignalHandler::~AsynchronousSignalHandler() {
- if (descriptor_ != kInvalidDescriptor) {
- MessageLoop::current()->CancelTask(fd_watcher_task_);
+ fd_watcher_ = nullptr;
- if (IGNORE_EINTR(close(descriptor_)) != 0)
- PLOG(WARNING) << "Failed to close file descriptor";
+ if (!descriptor_.is_valid())
+ return;
- descriptor_ = kInvalidDescriptor;
- CHECK_EQ(0, sigprocmask(SIG_SETMASK, &saved_signal_mask_, nullptr));
- }
+ // Close FD before restoring sigprocmask.
+ descriptor_.reset();
+ CHECK_EQ(0, sigprocmask(SIG_SETMASK, &saved_signal_mask_, nullptr));
}
void AsynchronousSignalHandler::Init() {
- CHECK_EQ(kInvalidDescriptor, descriptor_);
+ // Making sure it is not yet initialized.
+ CHECK(!descriptor_.is_valid());
+
+ // Set sigprocmask before creating signalfd.
CHECK_EQ(0, sigprocmask(SIG_BLOCK, &signal_mask_, &saved_signal_mask_));
- descriptor_ =
- signalfd(descriptor_, &signal_mask_, SFD_CLOEXEC | SFD_NONBLOCK);
- CHECK_NE(kInvalidDescriptor, descriptor_);
- fd_watcher_task_ = MessageLoop::current()->WatchFileDescriptor(
- FROM_HERE,
- descriptor_,
- MessageLoop::WatchMode::kWatchRead,
- true,
- base::Bind(&AsynchronousSignalHandler::OnFileCanReadWithoutBlocking,
- base::Unretained(this)));
- CHECK(fd_watcher_task_ != MessageLoop::kTaskIdNull)
- << "Watching shutdown pipe failed.";
+
+ // Creating signalfd, and start watching it.
+ descriptor_.reset(signalfd(-1, &signal_mask_, SFD_CLOEXEC | SFD_NONBLOCK));
+ CHECK(descriptor_.is_valid());
+ fd_watcher_ = base::FileDescriptorWatcher::WatchReadable(
+ descriptor_.get(),
+ base::BindRepeating(&AsynchronousSignalHandler::OnReadable,
+ base::Unretained(this)));
+ CHECK(fd_watcher_) << "Watching signalfd failed.";
}
void AsynchronousSignalHandler::RegisterHandler(int signal,
@@ -65,15 +57,16 @@ void AsynchronousSignalHandler::RegisterHandler(int signal,
void AsynchronousSignalHandler::UnregisterHandler(int signal) {
Callbacks::iterator callback_it = registered_callbacks_.find(signal);
- if (callback_it != registered_callbacks_.end()) {
- registered_callbacks_.erase(callback_it);
- ResetSignal(signal);
- }
+ if (callback_it == registered_callbacks_.end())
+ return;
+ registered_callbacks_.erase(callback_it);
+ CHECK_EQ(0, sigdelset(&signal_mask_, signal));
+ UpdateSignals();
}
-void AsynchronousSignalHandler::OnFileCanReadWithoutBlocking() {
+void AsynchronousSignalHandler::OnReadable() {
struct signalfd_siginfo info;
- while (base::ReadFromFD(descriptor_,
+ while (base::ReadFromFD(descriptor_.get(),
reinterpret_cast<char*>(&info), sizeof(info))) {
int signal = info.ssi_signo;
Callbacks::iterator callback_it = registered_callbacks_.find(signal);
@@ -85,24 +78,29 @@ void AsynchronousSignalHandler::OnFileCanReadWithoutBlocking() {
}
const SignalHandler& callback = callback_it->second;
bool must_unregister = callback.Run(info);
- if (must_unregister) {
+ if (must_unregister)
UnregisterHandler(signal);
- }
}
}
-void AsynchronousSignalHandler::ResetSignal(int signal) {
- CHECK_EQ(0, sigdelset(&signal_mask_, signal));
- UpdateSignals();
-}
-
void AsynchronousSignalHandler::UpdateSignals() {
- if (descriptor_ != kInvalidDescriptor) {
- CHECK_EQ(0, sigprocmask(SIG_SETMASK, &saved_signal_mask_, nullptr));
- CHECK_EQ(0, sigprocmask(SIG_BLOCK, &signal_mask_, nullptr));
- CHECK_EQ(descriptor_,
- signalfd(descriptor_, &signal_mask_, SFD_CLOEXEC | SFD_NONBLOCK));
+ if (!descriptor_.is_valid())
+ return;
+ sigset_t mask;
+#ifdef __ANDROID__
+ CHECK_EQ(0, sigemptyset(&mask));
+ for (size_t i = 0; i < NSIG; ++i) {
+ if (sigismember(&signal_mask_, i) == 1 || sigismember(&saved_signal_mask_, i) == 1) {
+ CHECK_EQ(0, sigaddset(&mask, i));
+ }
}
+#else
+ CHECK_EQ(0, sigorset(&mask, &signal_mask_, &saved_signal_mask_));
+#endif
+ CHECK_EQ(0, sigprocmask(SIG_SETMASK, &mask, nullptr));
+ CHECK_EQ(
+ descriptor_.get(),
+ signalfd(descriptor_.get(), &signal_mask_, SFD_CLOEXEC | SFD_NONBLOCK));
}
} // namespace brillo