diff options
author | Paul Stewart <pstew@google.com> | 2015-11-18 11:32:22 -0800 |
---|---|---|
committer | Paul Stewart <pstew@google.com> | 2015-11-18 14:39:47 -0800 |
commit | b6a5c6113b0b7ae947c5a1729d4b9d08287a83e2 (patch) | |
tree | b6be9e99eddf13e562fc619cf89892ae9a3dbc48 /brillo | |
parent | 94afaa4bf4e5266fe057664238e241d4b638d5ff (diff) | |
download | platform_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.cc | 4 | ||||
-rw-r--r-- | brillo/process_reaper.h | 7 | ||||
-rw-r--r-- | brillo/process_reaper_unittest.cc | 20 |
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 |