diff options
author | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 00:33:17 +0000 |
---|---|---|
committer | vitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-07 00:33:17 +0000 |
commit | d33951be72f0b9abaf58117c87817b31a48d58ac (patch) | |
tree | 78ac321f23ef6fbd4c3590288e76353af5a42fb6 /chrome/browser/printing/print_job.cc | |
parent | ed14f9f4b6069495c55062eb68f87244b082b704 (diff) | |
download | chromium_src-d33951be72f0b9abaf58117c87817b31a48d58ac.zip chromium_src-d33951be72f0b9abaf58117c87817b31a48d58ac.tar.gz chromium_src-d33951be72f0b9abaf58117c87817b31a48d58ac.tar.bz2 |
Don't run internal message loop from PrintJob::ControlledWorkerShutdown()
If loops is running, and render is closed, the RenderViewHostImpl that called ControlledWorkerShutdown is going to be destroyed. So RenderViewHostImpl crashes immediately after returning from ControlledWorkerShutdown.
Solution it to use delayed messages instead of nested loop.
BUG=313274
NOTRY=true
Review URL: https://codereview.chromium.org/136733005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@249561 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/printing/print_job.cc')
-rw-r--r-- | chrome/browser/printing/print_job.cc | 57 |
1 files changed, 19 insertions, 38 deletions
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index a899b17..206431b 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc @@ -163,16 +163,12 @@ void PrintJob::Stop() { // Be sure to live long enough. scoped_refptr<PrintJob> handle(this); - base::MessageLoop* worker_loop = worker_->message_loop(); - if (worker_loop) { + if (worker_->message_loop()) { ControlledWorkerShutdown(); - - is_job_pending_ = false; - registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, - content::Source<PrintJob>(this)); + } else { + // Flush the cached document. + UpdatePrintedDocument(NULL); } - // Flush the cached document. - UpdatePrintedDocument(NULL); } void PrintJob::Cancel() { @@ -327,32 +323,14 @@ void PrintJob::ControlledWorkerShutdown() { // deadlock is eliminated. worker_->StopSoon(); - // Run a tight message loop until the worker terminates. It may seems like a - // hack but I see no other way to get it to work flawlessly. The issues here - // are: - // - We don't want to run tasks while the thread is quitting. - // - We want this code path to wait on the thread to quit before continuing. - MSG msg; - HANDLE thread_handle = worker_->thread_handle().platform_handle(); - for (; thread_handle;) { - // Note that we don't do any kind of message prioritization since we don't - // execute any pending task or timer. - DWORD result = MsgWaitForMultipleObjects(1, &thread_handle, - FALSE, INFINITE, QS_ALLINPUT); - if (result == WAIT_OBJECT_0 + 1) { - while (PeekMessage(&msg, NULL, 0, 0, TRUE) > 0) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - // Continue looping. - } else if (result == WAIT_OBJECT_0) { - // The thread quit. - break; - } else { - // An error occurred. Assume the thread quit. - NOTREACHED(); - break; - } + // Delay shutdown until the worker terminates. We want this code path + // to wait on the thread to quit before continuing. + if (worker_->IsRunning()) { + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&PrintJob::ControlledWorkerShutdown, this), + base::TimeDelta::FromMilliseconds(100)); + return; } #endif @@ -365,13 +343,16 @@ void PrintJob::ControlledWorkerShutdown() { FROM_HERE, base::Bind(&PrintJobWorker::Stop, base::Unretained(worker_.get())), - base::Bind(&PrintJob::HoldUntilStopIsCalled, - weak_ptr_factory_.GetWeakPtr(), - scoped_refptr<PrintJob>(this)), + base::Bind(&PrintJob::HoldUntilStopIsCalled, this), false); + + is_job_pending_ = false; + registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, + content::Source<PrintJob>(this)); + UpdatePrintedDocument(NULL); } -void PrintJob::HoldUntilStopIsCalled(const scoped_refptr<PrintJob>&) { +void PrintJob::HoldUntilStopIsCalled() { is_stopped_ = true; is_stopping_ = false; } |