summaryrefslogtreecommitdiffstats
path: root/chrome/browser/printing/print_job.cc
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 00:33:17 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-07 00:33:17 +0000
commitd33951be72f0b9abaf58117c87817b31a48d58ac (patch)
tree78ac321f23ef6fbd4c3590288e76353af5a42fb6 /chrome/browser/printing/print_job.cc
parented14f9f4b6069495c55062eb68f87244b082b704 (diff)
downloadchromium_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.cc57
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;
}