summaryrefslogtreecommitdiffstats
path: root/chrome/common/process_watcher_posix.cc
diff options
context:
space:
mode:
authorthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-20 19:49:33 +0000
committerthestig@chromium.org <thestig@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-20 19:49:33 +0000
commitd0533cb650b6fb7e088a831e6d8cfa11aabbe474 (patch)
tree880298931c4ee970a0c0da4c5f1b5bdf37d88e87 /chrome/common/process_watcher_posix.cc
parent6c64c1c297b0f21c202522ae21a7c3d5d9f52cac (diff)
downloadchromium_src-d0533cb650b6fb7e088a831e6d8cfa11aabbe474.zip
chromium_src-d0533cb650b6fb7e088a831e6d8cfa11aabbe474.tar.gz
chromium_src-d0533cb650b6fb7e088a831e6d8cfa11aabbe474.tar.bz2
Add ProcessWatcher::EnsureProcessGetsReaped() for zombie reaping. First target: xdg-open.
BUG=15342 TEST=Click show in folder for a download, close the file manager that opens up, make sure the xdg-open process eventually gets reaped. Review URL: http://codereview.chromium.org/149057 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21087 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common/process_watcher_posix.cc')
-rw-r--r--chrome/common/process_watcher_posix.cc35
1 files changed, 30 insertions, 5 deletions
diff --git a/chrome/common/process_watcher_posix.cc b/chrome/common/process_watcher_posix.cc
index f1ae4f4..0991f0cb 100644
--- a/chrome/common/process_watcher_posix.cc
+++ b/chrome/common/process_watcher_posix.cc
@@ -30,8 +30,9 @@ static bool IsChildDead(pid_t child) {
// If the child doesn't exit within a couple of seconds, kill it.
class BackgroundReaper : public PlatformThread::Delegate {
public:
- explicit BackgroundReaper(pid_t child)
- : child_(child) {
+ explicit BackgroundReaper(pid_t child, unsigned timeout)
+ : child_(child),
+ timeout_(timeout) {
}
void ThreadMain() {
@@ -40,11 +41,21 @@ class BackgroundReaper : public PlatformThread::Delegate {
}
void WaitForChildToDie() {
+ // Wait forever case.
+ if (timeout_ == 0) {
+ pid_t r = waitpid(child_, NULL, 0);
+ if (r != child_) {
+ LOG(ERROR) << "While waiting for " << child_
+ << " to terminate, we got the following result: " << r;
+ }
+ return;
+ }
+
// There's no good way to wait for a specific child to exit in a timed
// fashion. (No kqueue on Linux), so we just loop and sleep.
- // Waits 0.5 * 4 = 2 seconds.
- for (unsigned i = 0; i < 4; ++i) {
+ // Wait for 2 * timeout_ 500 milliseconds intervals.
+ for (unsigned i = 0; i < 2 * timeout_; ++i) {
PlatformThread::Sleep(500); // 0.5 seconds
if (IsChildDead(child_))
return;
@@ -62,6 +73,9 @@ class BackgroundReaper : public PlatformThread::Delegate {
private:
const pid_t child_;
+ // Number of seconds to wait, if 0 then wait forever and do not attempt to
+ // kill |child_|.
+ const unsigned timeout_;
DISALLOW_COPY_AND_ASSIGN(BackgroundReaper);
};
@@ -72,6 +86,17 @@ void ProcessWatcher::EnsureProcessTerminated(base::ProcessHandle process) {
if (IsChildDead(process))
return;
- BackgroundReaper* reaper = new BackgroundReaper(process);
+ const unsigned timeout = 2; // seconds
+ BackgroundReaper* reaper = new BackgroundReaper(process, timeout);
+ PlatformThread::CreateNonJoinable(0, reaper);
+}
+
+// static
+void ProcessWatcher::EnsureProcessGetsReaped(base::ProcessHandle process) {
+ // If the child is already dead, then there's nothing to do
+ if (IsChildDead(process))
+ return;
+
+ BackgroundReaper* reaper = new BackgroundReaper(process, 0);
PlatformThread::CreateNonJoinable(0, reaper);
}