| Index: chrome/browser/chromeos/login/chrome_restart_request.cc
|
| diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc
|
| index 1f41ae1ef49ea62f462c593934b99f34484e0229..e895462a7f5cd35a1b3dbcc8aa70508558135b88 100644
|
| --- a/chrome/browser/chromeos/login/chrome_restart_request.cc
|
| +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
|
| @@ -4,6 +4,7 @@
|
|
|
| #include "chrome/browser/chromeos/login/chrome_restart_request.h"
|
|
|
| +#include <sys/socket.h>
|
| #include <vector>
|
|
|
| #include "ash/common/ash_switches.h"
|
| @@ -270,6 +271,9 @@ class ChromeRestartRequest
|
| // Fires job restart request to session manager.
|
| void RestartJob();
|
|
|
| + // Called when RestartJob D-Bus method call is complete.
|
| + void OnRestartJob(base::ScopedFD local_auth_fd, DBusMethodCallStatus status);
|
| +
|
| const std::vector<std::string> argv_;
|
| base::OneShotTimer timer_;
|
|
|
| @@ -319,8 +323,34 @@ void ChromeRestartRequest::RestartJob() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| VLOG(1) << "ChromeRestartRequest::RestartJob";
|
|
|
| - DBusThreadManager::Get()->GetSessionManagerClient()->RestartJob(argv_);
|
| + // The session manager requires a RestartJob caller to open a socket pair and
|
| + // pass one end over D-Bus while holding the local end open for the duration
|
| + // of the call.
|
| + int sockets[2] = {-1, -1};
|
| + // socketpair() doesn't cause disk IO so it's OK to call it on the UI thread.
|
| + // Also, the current chrome process is going to die soon so it doesn't matter
|
| + // anyways.
|
| + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) {
|
| + PLOG(ERROR) << "Failed to create a unix domain socketpair";
|
| + delete this;
|
| + return;
|
| + }
|
| + base::ScopedFD local_auth_fd(sockets[0]);
|
| + base::ScopedFD remote_auth_fd(sockets[1]);
|
| + // Ownership of local_auth_fd is passed to the callback that is to be
|
| + // called on completion of this method call. This keeps the browser end
|
| + // of the socket-pair alive for the duration of the RPC.
|
| + DBusThreadManager::Get()->GetSessionManagerClient()->RestartJob(
|
| + remote_auth_fd.get(), argv_,
|
| + base::Bind(&ChromeRestartRequest::OnRestartJob, AsWeakPtr(),
|
| + base::Passed(&local_auth_fd)));
|
| +}
|
|
|
| +void ChromeRestartRequest::OnRestartJob(base::ScopedFD local_auth_fd,
|
| + DBusMethodCallStatus status) {
|
| + // Now that the call is complete, local_auth_fd can be closed and discarded,
|
| + // which will happen automatically when it goes out of scope.
|
| + VLOG(1) << "OnRestartJob";
|
| delete this;
|
| }
|
|
|
|
|