aboutsummaryrefslogtreecommitdiffstats
path: root/brillo
diff options
context:
space:
mode:
authorPaul Stewart <pstew@google.com>2015-11-18 11:32:22 -0800
committerPaul Stewart <pstew@google.com>2015-11-18 14:39:47 -0800
commitb6a5c6113b0b7ae947c5a1729d4b9d08287a83e2 (patch)
treeb6be9e99eddf13e562fc619cf89892ae9a3dbc48 /brillo
parent94afaa4bf4e5266fe057664238e241d4b638d5ff (diff)
downloadplatform_external_libbrillo-b6a5c6113b0b7ae947c5a1729d4b9d08287a83e2.tar.gz
platform_external_libbrillo-b6a5c6113b0b7ae947c5a1729d4b9d08287a83e2.tar.bz2
platform_external_libbrillo-b6a5c6113b0b7ae947c5a1729d4b9d08287a83e2.zip
Add a method to ProcessReaper to forget a tracked pid
Allow callers to remove a tracked pid if tracking is no longer desired (e.g., if the caller has reaped the process themselves.) BUG=chromium:535910 Change-Id: Ie056c54a66c5aed539d2a77a41135f9b2da66582
Diffstat (limited to 'brillo')
-rw-r--r--brillo/process_reaper.cc4
-rw-r--r--brillo/process_reaper.h7
-rw-r--r--brillo/process_reaper_unittest.cc20
3 files changed, 31 insertions, 0 deletions
diff --git a/brillo/process_reaper.cc b/brillo/process_reaper.cc
index 5ee1195..c2f81b2 100644
--- a/brillo/process_reaper.cc
+++ b/brillo/process_reaper.cc
@@ -45,6 +45,10 @@ bool ProcessReaper::WatchForChild(const tracked_objects::Location& from_here,
return true;
}
+bool ProcessReaper::ForgetChild(pid_t pid) {
+ return watched_processes_.erase(pid) != 0;
+}
+
bool ProcessReaper::HandleSIGCHLD(const struct signalfd_siginfo& sigfd_info) {
// One SIGCHLD may correspond to multiple terminated children, so ignore
// sigfd_info and reap any available children.
diff --git a/brillo/process_reaper.h b/brillo/process_reaper.h
index d88f572..937c88c 100644
--- a/brillo/process_reaper.h
+++ b/brillo/process_reaper.h
@@ -44,6 +44,13 @@ class BRILLO_EXPORT ProcessReaper final {
pid_t pid,
const ChildCallback& callback);
+ // Stop watching child process |pid|. This is useful in situations
+ // where the child process may have been reaped outside of the signal
+ // handler, or the caller is no longer interested in being notified about
+ // this child process anymore. Returns true if a child was removed from
+ // the watchlist.
+ bool ForgetChild(pid_t pid);
+
private:
// SIGCHLD handler for the AsynchronousSignalHandler. Always returns false
// (meaning that the signal handler should not be unregistered).
diff --git a/brillo/process_reaper_unittest.cc b/brillo/process_reaper_unittest.cc
index 499b908..ae888d2 100644
--- a/brillo/process_reaper_unittest.cc
+++ b/brillo/process_reaper_unittest.cc
@@ -118,4 +118,24 @@ TEST_F(ProcessReaperTest, ReapKilledChild) {
brillo_loop_.Run();
}
+TEST_F(ProcessReaperTest, ReapKilledAndForgottenChild) {
+ pid_t pid = ForkChildAndExit(0);
+ EXPECT_TRUE(process_reaper_.WatchForChild(FROM_HERE, pid, base::Bind(
+ [this](const siginfo_t& info) {
+ ADD_FAILURE() << "Child process was still tracked.";
+ this->brillo_loop_.BreakLoop();
+ })));
+ EXPECT_TRUE(process_reaper_.ForgetChild(pid));
+
+ // A second call should return failure.
+ EXPECT_FALSE(process_reaper_.ForgetChild(pid));
+
+ // Run the loop with a timeout, as the BreakLoop() above is not expected.
+ brillo_loop_.PostDelayedTask(FROM_HERE,
+ base::Bind(&MessageLoop::BreakLoop,
+ base::Unretained(&brillo_loop_)),
+ base::TimeDelta::FromMilliseconds(100));
+ brillo_loop_.Run();
+}
+
} // namespace brillo