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 |