| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ, | 615 ml->WatchFileDescriptor(socket, true, base::MessageLoopForIO::WATCH_READ, |
| 616 &fd_watcher_, this); | 616 &fd_watcher_, this); |
| 617 } | 617 } |
| 618 | 618 |
| 619 void ProcessSingleton::LinuxWatcher::HandleMessage( | 619 void ProcessSingleton::LinuxWatcher::HandleMessage( |
| 620 const std::string& current_dir, const std::vector<std::string>& argv, | 620 const std::string& current_dir, const std::vector<std::string>& argv, |
| 621 SocketReader* reader) { | 621 SocketReader* reader) { |
| 622 DCHECK(ui_message_loop_ == base::MessageLoop::current()); | 622 DCHECK(ui_message_loop_ == base::MessageLoop::current()); |
| 623 DCHECK(reader); | 623 DCHECK(reader); |
| 624 | 624 |
| 625 if (parent_->notification_callback_.Run(CommandLine(argv), | 625 if (parent_->notification_callback_.Run(base::CommandLine(argv), |
| 626 base::FilePath(current_dir))) { | 626 base::FilePath(current_dir))) { |
| 627 // Send back "ACK" message to prevent the client process from starting up. | 627 // Send back "ACK" message to prevent the client process from starting up. |
| 628 reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1); | 628 reader->FinishWithACK(kACKToken, arraysize(kACKToken) - 1); |
| 629 } else { | 629 } else { |
| 630 LOG(WARNING) << "Not handling interprocess notification as browser" | 630 LOG(WARNING) << "Not handling interprocess notification as browser" |
| 631 " is shutting down"; | 631 " is shutting down"; |
| 632 // Send back "SHUTDOWN" message, so that the client process can start up | 632 // Send back "SHUTDOWN" message, so that the client process can start up |
| 633 // without killing this process. | 633 // without killing this process. |
| 634 reader->FinishWithACK(kShutdownToken, arraysize(kShutdownToken) - 1); | 634 reader->FinishWithACK(kShutdownToken, arraysize(kShutdownToken) - 1); |
| 635 return; | 635 return; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 | 748 |
| 749 kill_callback_ = base::Bind(&ProcessSingleton::KillProcess, | 749 kill_callback_ = base::Bind(&ProcessSingleton::KillProcess, |
| 750 base::Unretained(this)); | 750 base::Unretained(this)); |
| 751 } | 751 } |
| 752 | 752 |
| 753 ProcessSingleton::~ProcessSingleton() { | 753 ProcessSingleton::~ProcessSingleton() { |
| 754 } | 754 } |
| 755 | 755 |
| 756 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { | 756 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
| 757 return NotifyOtherProcessWithTimeout( | 757 return NotifyOtherProcessWithTimeout( |
| 758 *CommandLine::ForCurrentProcess(), | 758 *base::CommandLine::ForCurrentProcess(), kRetryAttempts, |
| 759 kRetryAttempts, | 759 base::TimeDelta::FromSeconds(kTimeoutInSeconds), true); |
| 760 base::TimeDelta::FromSeconds(kTimeoutInSeconds), | |
| 761 true); | |
| 762 } | 760 } |
| 763 | 761 |
| 764 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout( | 762 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout( |
| 765 const CommandLine& cmd_line, | 763 const base::CommandLine& cmd_line, |
| 766 int retry_attempts, | 764 int retry_attempts, |
| 767 const base::TimeDelta& timeout, | 765 const base::TimeDelta& timeout, |
| 768 bool kill_unresponsive) { | 766 bool kill_unresponsive) { |
| 769 DCHECK_GE(retry_attempts, 0); | 767 DCHECK_GE(retry_attempts, 0); |
| 770 DCHECK_GE(timeout.InMicroseconds(), 0); | 768 DCHECK_GE(timeout.InMicroseconds(), 0); |
| 771 | 769 |
| 772 base::TimeDelta sleep_interval = timeout / retry_attempts; | 770 base::TimeDelta sleep_interval = timeout / retry_attempts; |
| 773 | 771 |
| 774 ScopedSocket socket; | 772 ScopedSocket socket; |
| 775 for (int retries = 0; retries <= retry_attempts; ++retries) { | 773 for (int retries = 0; retries <= retry_attempts; ++retries) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 // Assume the other process is handling the request. | 888 // Assume the other process is handling the request. |
| 891 return PROCESS_NOTIFIED; | 889 return PROCESS_NOTIFIED; |
| 892 } | 890 } |
| 893 | 891 |
| 894 NOTREACHED() << "The other process returned unknown message: " << buf; | 892 NOTREACHED() << "The other process returned unknown message: " << buf; |
| 895 return PROCESS_NOTIFIED; | 893 return PROCESS_NOTIFIED; |
| 896 } | 894 } |
| 897 | 895 |
| 898 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { | 896 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { |
| 899 return NotifyOtherProcessWithTimeoutOrCreate( | 897 return NotifyOtherProcessWithTimeoutOrCreate( |
| 900 *CommandLine::ForCurrentProcess(), | 898 *base::CommandLine::ForCurrentProcess(), kRetryAttempts, |
| 901 kRetryAttempts, | |
| 902 base::TimeDelta::FromSeconds(kTimeoutInSeconds)); | 899 base::TimeDelta::FromSeconds(kTimeoutInSeconds)); |
| 903 } | 900 } |
| 904 | 901 |
| 905 ProcessSingleton::NotifyResult | 902 ProcessSingleton::NotifyResult |
| 906 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate( | 903 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate( |
| 907 const CommandLine& command_line, | 904 const base::CommandLine& command_line, |
| 908 int retry_attempts, | 905 int retry_attempts, |
| 909 const base::TimeDelta& timeout) { | 906 const base::TimeDelta& timeout) { |
| 910 NotifyResult result = NotifyOtherProcessWithTimeout( | 907 NotifyResult result = NotifyOtherProcessWithTimeout( |
| 911 command_line, retry_attempts, timeout, true); | 908 command_line, retry_attempts, timeout, true); |
| 912 if (result != PROCESS_NONE) | 909 if (result != PROCESS_NONE) |
| 913 return result; | 910 return result; |
| 914 if (Create()) | 911 if (Create()) |
| 915 return PROCESS_NONE; | 912 return PROCESS_NONE; |
| 916 // If the Create() failed, try again to notify. (It could be that another | 913 // If the Create() failed, try again to notify. (It could be that another |
| 917 // instance was starting at the same time and managed to grab the lock before | 914 // instance was starting at the same time and managed to grab the lock before |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1067 } | 1064 } |
| 1068 | 1065 |
| 1069 void ProcessSingleton::KillProcess(int pid) { | 1066 void ProcessSingleton::KillProcess(int pid) { |
| 1070 // TODO(james.su@gmail.com): Is SIGKILL ok? | 1067 // TODO(james.su@gmail.com): Is SIGKILL ok? |
| 1071 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); | 1068 int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL); |
| 1072 // ESRCH = No Such Process (can happen if the other process is already in | 1069 // ESRCH = No Such Process (can happen if the other process is already in |
| 1073 // progress of shutting down and finishes before we try to kill it). | 1070 // progress of shutting down and finishes before we try to kill it). |
| 1074 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " | 1071 DCHECK(rv == 0 || errno == ESRCH) << "Error killing process: " |
| 1075 << safe_strerror(errno); | 1072 << safe_strerror(errno); |
| 1076 } | 1073 } |
| OLD | NEW |