summaryrefslogtreecommitdiffstats
path: root/chrome/browser/process_singleton_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/process_singleton_linux.cc')
-rw-r--r--chrome/browser/process_singleton_linux.cc42
1 files changed, 36 insertions, 6 deletions
diff --git a/chrome/browser/process_singleton_linux.cc b/chrome/browser/process_singleton_linux.cc
index 0a9a427..fdf4c2b 100644
--- a/chrome/browser/process_singleton_linux.cc
+++ b/chrome/browser/process_singleton_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -280,8 +280,31 @@ void DisplayProfileInUseError(const std::string& lock_path,
#endif
}
+bool IsChromeProcess(pid_t pid) {
+ FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
+ return (!other_chrome_path.empty() &&
+ other_chrome_path.BaseName() ==
+ FilePath::FromWStringHack(chrome::kBrowserProcessExecutableName));
+}
+
+// Return true if the given pid is one of our child processes.
+// Assumes that the current pid is the root of all pids of the current instance.
+bool IsSameChromeInstance(pid_t pid) {
+ pid_t cur_pid = base::GetCurrentProcId();
+ while (pid != cur_pid) {
+ pid = base::GetParentProcessId(pid);
+ if (pid < 0)
+ return false;
+ if (!IsChromeProcess(pid))
+ return false;
+ }
+ return true;
+}
+
// Extract the process's pid from a symbol link path and if it is on
// the same host, kill the process, unlink the lock file and return true.
+// If the process is part of the same chrome instance, unlink the lock file and
+// return true without killing it.
// If the process is on a different host, return false.
bool KillProcessByLockPath(const std::string& path) {
std::string hostname;
@@ -294,7 +317,10 @@ bool KillProcessByLockPath(const std::string& path) {
}
UnlinkPath(path);
- if (pid >= 0) {
+ if (IsSameChromeInstance(pid))
+ return true;
+
+ if (pid > 0) {
// TODO(james.su@gmail.com): Is SIGKILL ok?
int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL);
// ESRCH = No Such Process (can happen if the other process is already in
@@ -669,15 +695,19 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
return PROFILE_IN_USE;
}
- FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
- if (other_chrome_path.empty() ||
- other_chrome_path.BaseName() !=
- FilePath::FromWStringHack(chrome::kBrowserProcessExecutableName)) {
+ if (!IsChromeProcess(pid)) {
// Orphaned lockfile (no process with pid, or non-chrome process.)
UnlinkPath(lock_path_.value());
return PROCESS_NONE;
}
+ if (IsSameChromeInstance(pid)) {
+ // Orphaned lockfile (pid is part of same chrome instance we are, even
+ // though we haven't tried to create a lockfile yet).
+ UnlinkPath(lock_path_.value());
+ return PROCESS_NONE;
+ }
+
if (retries == timeout_seconds) {
// Retries failed. Kill the unresponsive chrome process and continue.
if (!KillProcessByLockPath(lock_path_.value()))