Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: chrome/browser/process_singleton_linux.cc

Issue 23506011: Improve the UI for handling profile lock contention. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix XML syntax errur?! Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/app/google_chrome_strings.grd ('k') | chrome/browser/ui/gtk/process_singleton_dialog.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // On Linux, when the user tries to launch a second copy of chrome, we check 5 // On Linux, when the user tries to launch a second copy of chrome, we check
6 // for a socket in the user's profile directory. If the socket file is open we 6 // for a socket in the user's profile directory. If the socket file is open we
7 // send a message to the first chrome browser process with the current 7 // send a message to the first chrome browser process with the current
8 // directory and second process command line flags. The second process then 8 // directory and second process command line flags. The second process then
9 // exits. 9 // exits.
10 // 10 //
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 287
288 *hostname = real_path.substr(0, pos); 288 *hostname = real_path.substr(0, pos);
289 289
290 const std::string& pid_str = real_path.substr(pos + 1); 290 const std::string& pid_str = real_path.substr(pos + 1);
291 if (!base::StringToInt(pid_str, pid)) 291 if (!base::StringToInt(pid_str, pid))
292 *pid = -1; 292 *pid = -1;
293 293
294 return true; 294 return true;
295 } 295 }
296 296
297 void DisplayProfileInUseError(const std::string& lock_path, 297 // Returns true if the user opted to unlock the profile.
298 bool DisplayProfileInUseError(const base::FilePath& lock_path,
298 const std::string& hostname, 299 const std::string& hostname,
299 int pid) { 300 int pid) {
300 string16 error = l10n_util::GetStringFUTF16( 301 string16 error = l10n_util::GetStringFUTF16(
301 IDS_PROFILE_IN_USE_LINUX, 302 IDS_PROFILE_IN_USE_LINUX,
302 base::IntToString16(pid), 303 base::IntToString16(pid),
303 ASCIIToUTF16(hostname), 304 ASCIIToUTF16(hostname),
304 WideToUTF16(base::SysNativeMBToWide(lock_path)),
305 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 305 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
306 string16 relaunch_button_text = l10n_util::GetStringFUTF16(
307 IDS_PROFILE_IN_USE_LINUX_RELAUNCH,
308 string16());
306 LOG(ERROR) << base::SysWideToNativeMB(UTF16ToWide(error)).c_str(); 309 LOG(ERROR) << base::SysWideToNativeMB(UTF16ToWide(error)).c_str();
307 if (!g_disable_prompt) { 310 if (!g_disable_prompt) {
308 #if defined(TOOLKIT_GTK) 311 #if defined(TOOLKIT_GTK)
309 ProcessSingletonDialog::ShowAndRun(UTF16ToUTF8(error)); 312 return ProcessSingletonDialog::ShowAndRun(
313 UTF16ToUTF8(error), UTF16ToUTF8(relaunch_button_text));
310 #else 314 #else
311 NOTIMPLEMENTED(); 315 NOTIMPLEMENTED();
312 #endif 316 #endif
313 } 317 }
318 return false;
314 } 319 }
315 320
316 bool IsChromeProcess(pid_t pid) { 321 bool IsChromeProcess(pid_t pid) {
317 base::FilePath other_chrome_path(base::GetProcessExecutablePath(pid)); 322 base::FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
318 return (!other_chrome_path.empty() && 323 return (!other_chrome_path.empty() &&
319 other_chrome_path.BaseName() == 324 other_chrome_path.BaseName() ==
320 base::FilePath(chrome::kBrowserProcessExecutableName)); 325 base::FilePath(chrome::kBrowserProcessExecutableName));
321 } 326 }
322 327
323 // A helper class to hold onto a socket. 328 // A helper class to hold onto a socket.
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // No lockfile exists. 732 // No lockfile exists.
728 return PROCESS_NONE; 733 return PROCESS_NONE;
729 } 734 }
730 735
731 if (hostname.empty()) { 736 if (hostname.empty()) {
732 // Invalid lockfile. 737 // Invalid lockfile.
733 UnlinkPath(lock_path_); 738 UnlinkPath(lock_path_);
734 return PROCESS_NONE; 739 return PROCESS_NONE;
735 } 740 }
736 741
737 if (hostname != net::GetHostName()) { 742 if (hostname != net::GetHostName() && !IsChromeProcess(pid)) {
738 // Locked by process on another host. 743 // Locked by process on another host. If the user selected to unlock
739 DisplayProfileInUseError(lock_path_.value(), hostname, pid); 744 // the profile, try to continue; otherwise quit.
745 if (DisplayProfileInUseError(lock_path_, hostname, pid)) {
746 UnlinkPath(lock_path_);
747 return PROCESS_NONE;
748 }
740 return PROFILE_IN_USE; 749 return PROFILE_IN_USE;
741 } 750 }
742 751
743 if (!IsChromeProcess(pid)) { 752 if (!IsChromeProcess(pid)) {
744 // Orphaned lockfile (no process with pid, or non-chrome process.) 753 // Orphaned lockfile (no process with pid, or non-chrome process.)
745 UnlinkPath(lock_path_); 754 UnlinkPath(lock_path_);
746 return PROCESS_NONE; 755 return PROCESS_NONE;
747 } 756 }
748 757
749 if (IsSameChromeInstance(pid)) { 758 if (IsSameChromeInstance(pid)) {
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 } 960 }
952 return true; 961 return true;
953 } 962 }
954 963
955 bool ProcessSingleton::KillProcessByLockPath() { 964 bool ProcessSingleton::KillProcessByLockPath() {
956 std::string hostname; 965 std::string hostname;
957 int pid; 966 int pid;
958 ParseLockPath(lock_path_, &hostname, &pid); 967 ParseLockPath(lock_path_, &hostname, &pid);
959 968
960 if (!hostname.empty() && hostname != net::GetHostName()) { 969 if (!hostname.empty() && hostname != net::GetHostName()) {
961 DisplayProfileInUseError(lock_path_.value(), hostname, pid); 970 return DisplayProfileInUseError(lock_path_, hostname, pid);
962 return false;
963 } 971 }
964 UnlinkPath(lock_path_); 972 UnlinkPath(lock_path_);
965 973
966 if (IsSameChromeInstance(pid)) 974 if (IsSameChromeInstance(pid))
967 return true; 975 return true;
968 976
969 if (pid > 0) { 977 if (pid > 0) {
970 kill_callback_.Run(pid); 978 kill_callback_.Run(pid);
971 return true; 979 return true;
972 } 980 }
973 981
974 LOG(ERROR) << "Failed to extract pid from path: " << lock_path_.value(); 982 LOG(ERROR) << "Failed to extract pid from path: " << lock_path_.value();
975 return true; 983 return true;
976 } 984 }
977 985
978 void ProcessSingleton::KillProcess(int pid) { 986 void ProcessSingleton::KillProcess(int pid) {
979 // TODO(james.su@gmail.com): Is SIGKILL ok? 987 // TODO(james.su@gmail.com): Is SIGKILL ok?
980 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); 988 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL);
981 // ESRCH = No Such Process (can happen if the other process is already in 989 // ESRCH = No Such Process (can happen if the other process is already in
982 // progress of shutting down and finishes before we try to kill it). 990 // progress of shutting down and finishes before we try to kill it).
983 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " 991 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: "
984 << safe_strerror(errno); 992 << safe_strerror(errno);
985 } 993 }
OLDNEW
« no previous file with comments | « chrome/app/google_chrome_strings.grd ('k') | chrome/browser/ui/gtk/process_singleton_dialog.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698