| Index: chrome/browser/chromeos/cros/login_library.cc
|
| diff --git a/chrome/browser/chromeos/cros/login_library.cc b/chrome/browser/chromeos/cros/login_library.cc
|
| index 026757f3b92226b9bdf99ae76e2eb3993e401f2f..f8c58296aeaff14b6c455966e93efcb7c0b0c10d 100644
|
| --- a/chrome/browser/chromeos/cros/login_library.cc
|
| +++ b/chrome/browser/chromeos/cros/login_library.cc
|
| @@ -5,6 +5,8 @@
|
| #include "chrome/browser/chromeos/cros/login_library.h"
|
|
|
| #include "base/message_loop.h"
|
| +#include "base/task.h"
|
| +#include "base/timer.h"
|
| #include "chrome/browser/browser_process.h"
|
| #include "chrome/browser/chromeos/cros/cros_library.h"
|
| #include "chrome/browser/chromeos/login/signed_settings_temp_storage.h"
|
| @@ -18,12 +20,14 @@ namespace chromeos {
|
| class LoginLibraryImpl : public LoginLibrary {
|
| public:
|
| LoginLibraryImpl()
|
| - : set_owner_key_callback_(NULL),
|
| + : job_restart_request_(NULL),
|
| + set_owner_key_callback_(NULL),
|
| whitelist_op_callback_(NULL),
|
| property_op_callback_(NULL) {
|
| if (CrosLibrary::Get()->EnsureLoaded())
|
| Init();
|
| }
|
| +
|
| virtual ~LoginLibraryImpl() {
|
| if (session_connection_) {
|
| chromeos::DisconnectSession(session_connection_);
|
| @@ -131,16 +135,59 @@ class LoginLibraryImpl : public LoginLibrary {
|
| }
|
|
|
| bool RestartJob(int pid, const std::string& command_line) {
|
| - if (g_browser_process && g_browser_process->local_state()) {
|
| - // XXX: normally this call must not be needed, however it turned out that
|
| - // without this explicit call to SavePersistentPrefs it is possible for
|
| - // preferences to be lost. See http://crosbug.com/13102
|
| - g_browser_process->local_state()->SavePersistentPrefs();
|
| + if (job_restart_request_) {
|
| + NOTREACHED();
|
| + return false;
|
| }
|
| - return chromeos::RestartJob(pid, command_line.c_str());
|
| + job_restart_request_ = new JobRestartRequest(pid, command_line);
|
| + return true;
|
| }
|
|
|
| private:
|
| + class JobRestartRequest
|
| + : public base::RefCountedThreadSafe<JobRestartRequest> {
|
| + public:
|
| + JobRestartRequest(int pid, const std::string& command_line)
|
| + : pid_(pid),
|
| + command_line_(command_line),
|
| + local_state_(g_browser_process->local_state()) {
|
| + AddRef();
|
| + if (local_state_) {
|
| + // XXX: normally this call must not be needed, however RestartJob
|
| + // just kills us so settings may be lost. See http://crosbug.com/13102
|
| + local_state_->CommitPendingWrite();
|
| + timer_.Start(
|
| + base::TimeDelta::FromSeconds(3), this,
|
| + &JobRestartRequest::RestartJob);
|
| + // Post task on file thread thus it occurs last on task queue, so it
|
| + // would be executed after committing pending write on file thread.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::FILE, FROM_HERE,
|
| + NewRunnableMethod(this, &JobRestartRequest::RestartJob));
|
| + } else {
|
| + RestartJob();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + void RestartJob() {
|
| + if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
|
| + if (!chromeos::RestartJob(pid_, command_line_.c_str()))
|
| + NOTREACHED();
|
| + } else {
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + NewRunnableMethod(this, &JobRestartRequest::RestartJob));
|
| + MessageLoop::current()->AssertIdle();
|
| + }
|
| + }
|
| +
|
| + int pid_;
|
| + std::string command_line_;
|
| + PrefService* local_state_;
|
| + base::OneShotTimer<JobRestartRequest> timer_;
|
| + };
|
| +
|
| static void Handler(void* object, const OwnershipEvent& event) {
|
| LoginLibraryImpl* self = static_cast<LoginLibraryImpl*>(object);
|
| switch (event) {
|
| @@ -208,6 +255,7 @@ class LoginLibraryImpl : public LoginLibrary {
|
| }
|
|
|
| chromeos::SessionConnection session_connection_;
|
| + JobRestartRequest* job_restart_request_;
|
|
|
| Delegate* set_owner_key_callback_;
|
| Delegate* whitelist_op_callback_;
|
|
|