Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: chrome/browser/printing/print_job.cc

Issue 14113053: chrome: Use base::MessageLoop. (Part 3) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/printing/print_job.h" 5 #include "chrome/browser/printing/print_job.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/threading/thread_restrictions.h" 10 #include "base/threading/thread_restrictions.h"
(...skipping 12 matching lines...) Expand all
23 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner, 23 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
24 const base::Closure& callback) { 24 const base::Closure& callback) {
25 callback.Run(); 25 callback.Run();
26 } 26 }
27 27
28 } // namespace 28 } // namespace
29 29
30 namespace printing { 30 namespace printing {
31 31
32 PrintJob::PrintJob() 32 PrintJob::PrintJob()
33 : ui_message_loop_(MessageLoop::current()), 33 : ui_message_loop_(base::MessageLoop::current()),
34 source_(NULL), 34 source_(NULL),
35 worker_(), 35 worker_(),
36 settings_(), 36 settings_(),
37 is_job_pending_(false), 37 is_job_pending_(false),
38 is_canceling_(false), 38 is_canceling_(false),
39 ALLOW_THIS_IN_INITIALIZER_LIST(quit_factory_(this)) { 39 ALLOW_THIS_IN_INITIALIZER_LIST(quit_factory_(this)) {
40 DCHECK(ui_message_loop_); 40 DCHECK(ui_message_loop_);
41 // This is normally a UI message loop, but in unit tests, the message loop is 41 // This is normally a UI message loop, but in unit tests, the message loop is
42 // of the 'default' type. 42 // of the 'default' type.
43 DCHECK(ui_message_loop_->type() == MessageLoop::TYPE_UI || 43 DCHECK(ui_message_loop_->type() == base::MessageLoop::TYPE_UI ||
44 ui_message_loop_->type() == MessageLoop::TYPE_DEFAULT); 44 ui_message_loop_->type() == base::MessageLoop::TYPE_DEFAULT);
45 ui_message_loop_->AddDestructionObserver(this); 45 ui_message_loop_->AddDestructionObserver(this);
46 } 46 }
47 47
48 PrintJob::~PrintJob() { 48 PrintJob::~PrintJob() {
49 ui_message_loop_->RemoveDestructionObserver(this); 49 ui_message_loop_->RemoveDestructionObserver(this);
50 // The job should be finished (or at least canceled) when it is destroyed. 50 // The job should be finished (or at least canceled) when it is destroyed.
51 DCHECK(!is_job_pending_); 51 DCHECK(!is_job_pending_);
52 DCHECK(!is_canceling_); 52 DCHECK(!is_canceling_);
53 if (worker_.get()) 53 if (worker_.get())
54 DCHECK(worker_->message_loop() == NULL); 54 DCHECK(worker_->message_loop() == NULL);
55 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 55 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
56 } 56 }
57 57
58 void PrintJob::Initialize(PrintJobWorkerOwner* job, 58 void PrintJob::Initialize(PrintJobWorkerOwner* job,
59 PrintedPagesSource* source, 59 PrintedPagesSource* source,
60 int page_count) { 60 int page_count) {
61 DCHECK(!source_); 61 DCHECK(!source_);
62 DCHECK(!worker_.get()); 62 DCHECK(!worker_.get());
63 DCHECK(!is_job_pending_); 63 DCHECK(!is_job_pending_);
64 DCHECK(!is_canceling_); 64 DCHECK(!is_canceling_);
65 DCHECK(!document_.get()); 65 DCHECK(!document_.get());
66 source_ = source; 66 source_ = source;
67 worker_.reset(job->DetachWorker(this)); 67 worker_.reset(job->DetachWorker(this));
68 settings_ = job->settings(); 68 settings_ = job->settings();
69 69
70 PrintedDocument* new_doc = 70 PrintedDocument* new_doc =
71 new PrintedDocument(settings_, source_, job->cookie()); 71 new PrintedDocument(settings_, source_, job->cookie());
72 new_doc->set_page_count(page_count); 72 new_doc->set_page_count(page_count);
73 UpdatePrintedDocument(new_doc); 73 UpdatePrintedDocument(new_doc);
74 74
75 // Don't forget to register to our own messages. 75 // Don't forget to register to our own messages.
76 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 76 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
77 content::Source<PrintJob>(this)); 77 content::Source<PrintJob>(this));
78 } 78 }
79 79
80 void PrintJob::Observe(int type, 80 void PrintJob::Observe(int type,
81 const content::NotificationSource& source, 81 const content::NotificationSource& source,
82 const content::NotificationDetails& details) { 82 const content::NotificationDetails& details) {
83 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 83 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
84 switch (type) { 84 switch (type) {
85 case chrome::NOTIFICATION_PRINT_JOB_EVENT: { 85 case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
86 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); 86 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
87 break; 87 break;
88 } 88 }
89 default: { 89 default: {
90 break; 90 break;
91 } 91 }
92 } 92 }
93 } 93 }
(...skipping 21 matching lines...) Expand all
115 // Always use an invalid cookie in this case. 115 // Always use an invalid cookie in this case.
116 return 0; 116 return 0;
117 return document_->cookie(); 117 return document_->cookie();
118 } 118 }
119 119
120 void PrintJob::WillDestroyCurrentMessageLoop() { 120 void PrintJob::WillDestroyCurrentMessageLoop() {
121 NOTREACHED(); 121 NOTREACHED();
122 } 122 }
123 123
124 void PrintJob::StartPrinting() { 124 void PrintJob::StartPrinting() {
125 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 125 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
126 DCHECK(worker_->message_loop()); 126 DCHECK(worker_->message_loop());
127 DCHECK(!is_job_pending_); 127 DCHECK(!is_job_pending_);
128 if (!worker_->message_loop() || is_job_pending_) 128 if (!worker_->message_loop() || is_job_pending_)
129 return; 129 return;
130 130
131 // Real work is done in PrintJobWorker::StartPrinting(). 131 // Real work is done in PrintJobWorker::StartPrinting().
132 worker_->message_loop()->PostTask( 132 worker_->message_loop()->PostTask(
133 FROM_HERE, 133 FROM_HERE,
134 base::Bind(&HoldRefCallback, make_scoped_refptr(this), 134 base::Bind(&HoldRefCallback, make_scoped_refptr(this),
135 base::Bind(&PrintJobWorker::StartPrinting, 135 base::Bind(&PrintJobWorker::StartPrinting,
136 base::Unretained(worker_.get()), document_))); 136 base::Unretained(worker_.get()), document_)));
137 // Set the flag right now. 137 // Set the flag right now.
138 is_job_pending_ = true; 138 is_job_pending_ = true;
139 139
140 // Tell everyone! 140 // Tell everyone!
141 scoped_refptr<JobEventDetails> details( 141 scoped_refptr<JobEventDetails> details(
142 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL)); 142 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL));
143 content::NotificationService::current()->Notify( 143 content::NotificationService::current()->Notify(
144 chrome::NOTIFICATION_PRINT_JOB_EVENT, 144 chrome::NOTIFICATION_PRINT_JOB_EVENT,
145 content::Source<PrintJob>(this), 145 content::Source<PrintJob>(this),
146 content::Details<JobEventDetails>(details.get())); 146 content::Details<JobEventDetails>(details.get()));
147 } 147 }
148 148
149 void PrintJob::Stop() { 149 void PrintJob::Stop() {
150 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 150 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
151 151
152 if (quit_factory_.HasWeakPtrs()) { 152 if (quit_factory_.HasWeakPtrs()) {
153 // In case we're running a nested message loop to wait for a job to finish, 153 // In case we're running a nested message loop to wait for a job to finish,
154 // and we finished before the timeout, quit the nested loop right away. 154 // and we finished before the timeout, quit the nested loop right away.
155 Quit(); 155 Quit();
156 quit_factory_.InvalidateWeakPtrs(); 156 quit_factory_.InvalidateWeakPtrs();
157 } 157 }
158 158
159 // Be sure to live long enough. 159 // Be sure to live long enough.
160 scoped_refptr<PrintJob> handle(this); 160 scoped_refptr<PrintJob> handle(this);
161 161
162 MessageLoop* worker_loop = worker_->message_loop(); 162 base::MessageLoop* worker_loop = worker_->message_loop();
163 if (worker_loop) { 163 if (worker_loop) {
164 ControlledWorkerShutdown(); 164 ControlledWorkerShutdown();
165 165
166 is_job_pending_ = false; 166 is_job_pending_ = false;
167 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 167 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
168 content::Source<PrintJob>(this)); 168 content::Source<PrintJob>(this));
169 } 169 }
170 // Flush the cached document. 170 // Flush the cached document.
171 UpdatePrintedDocument(NULL); 171 UpdatePrintedDocument(NULL);
172 } 172 }
173 173
174 void PrintJob::Cancel() { 174 void PrintJob::Cancel() {
175 if (is_canceling_) 175 if (is_canceling_)
176 return; 176 return;
177 is_canceling_ = true; 177 is_canceling_ = true;
178 178
179 // Be sure to live long enough. 179 // Be sure to live long enough.
180 scoped_refptr<PrintJob> handle(this); 180 scoped_refptr<PrintJob> handle(this);
181 181
182 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 182 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
183 MessageLoop* worker_loop = worker_.get() ? worker_->message_loop() : NULL; 183 base::MessageLoop* worker_loop =
184 worker_.get() ? worker_->message_loop() : NULL;
184 if (worker_loop) { 185 if (worker_loop) {
185 // Call this right now so it renders the context invalid. Do not use 186 // Call this right now so it renders the context invalid. Do not use
186 // InvokeLater since it would take too much time. 187 // InvokeLater since it would take too much time.
187 worker_->Cancel(); 188 worker_->Cancel();
188 } 189 }
189 // Make sure a Cancel() is broadcast. 190 // Make sure a Cancel() is broadcast.
190 scoped_refptr<JobEventDetails> details( 191 scoped_refptr<JobEventDetails> details(
191 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL)); 192 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL));
192 content::NotificationService::current()->Notify( 193 content::NotificationService::current()->Notify(
193 chrome::NOTIFICATION_PRINT_JOB_EVENT, 194 chrome::NOTIFICATION_PRINT_JOB_EVENT,
194 content::Source<PrintJob>(this), 195 content::Source<PrintJob>(this),
195 content::Details<JobEventDetails>(details.get())); 196 content::Details<JobEventDetails>(details.get()));
196 Stop(); 197 Stop();
197 is_canceling_ = false; 198 is_canceling_ = false;
198 } 199 }
199 200
200 bool PrintJob::FlushJob(base::TimeDelta timeout) { 201 bool PrintJob::FlushJob(base::TimeDelta timeout) {
201 // Make sure the object outlive this message loop. 202 // Make sure the object outlive this message loop.
202 scoped_refptr<PrintJob> handle(this); 203 scoped_refptr<PrintJob> handle(this);
203 204
204 MessageLoop::current()->PostDelayedTask(FROM_HERE, 205 base::MessageLoop::current()->PostDelayedTask(
205 base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()), timeout); 206 FROM_HERE,
207 base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()),
208 timeout);
206 209
207 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); 210 base::MessageLoop::ScopedNestableTaskAllower allow(
208 MessageLoop::current()->Run(); 211 base::MessageLoop::current());
212 base::MessageLoop::current()->Run();
209 213
210 return true; 214 return true;
211 } 215 }
212 216
213 void PrintJob::DisconnectSource() { 217 void PrintJob::DisconnectSource() {
214 source_ = NULL; 218 source_ = NULL;
215 if (document_.get()) 219 if (document_.get())
216 document_->DisconnectSource(); 220 document_->DisconnectSource();
217 } 221 }
218 222
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 case JobEventDetails::NEW_DOC: 266 case JobEventDetails::NEW_DOC:
263 case JobEventDetails::NEW_PAGE: 267 case JobEventDetails::NEW_PAGE:
264 case JobEventDetails::PAGE_DONE: 268 case JobEventDetails::PAGE_DONE:
265 case JobEventDetails::JOB_DONE: 269 case JobEventDetails::JOB_DONE:
266 case JobEventDetails::ALL_PAGES_REQUESTED: { 270 case JobEventDetails::ALL_PAGES_REQUESTED: {
267 // Don't care. 271 // Don't care.
268 break; 272 break;
269 } 273 }
270 case JobEventDetails::DOC_DONE: { 274 case JobEventDetails::DOC_DONE: {
271 // This will call Stop() and broadcast a JOB_DONE message. 275 // This will call Stop() and broadcast a JOB_DONE message.
272 MessageLoop::current()->PostTask( 276 base::MessageLoop::current()->PostTask(
273 FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this)); 277 FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
274 break; 278 break;
275 } 279 }
276 default: { 280 default: {
277 NOTREACHED(); 281 NOTREACHED();
278 break; 282 break;
279 } 283 }
280 } 284 }
281 } 285 }
282 286
283 void PrintJob::OnDocumentDone() { 287 void PrintJob::OnDocumentDone() {
284 // Be sure to live long enough. The instance could be destroyed by the 288 // Be sure to live long enough. The instance could be destroyed by the
285 // JOB_DONE broadcast. 289 // JOB_DONE broadcast.
286 scoped_refptr<PrintJob> handle(this); 290 scoped_refptr<PrintJob> handle(this);
287 291
288 // Stop the worker thread. 292 // Stop the worker thread.
289 Stop(); 293 Stop();
290 294
291 scoped_refptr<JobEventDetails> details( 295 scoped_refptr<JobEventDetails> details(
292 new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL)); 296 new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL));
293 content::NotificationService::current()->Notify( 297 content::NotificationService::current()->Notify(
294 chrome::NOTIFICATION_PRINT_JOB_EVENT, 298 chrome::NOTIFICATION_PRINT_JOB_EVENT,
295 content::Source<PrintJob>(this), 299 content::Source<PrintJob>(this),
296 content::Details<JobEventDetails>(details.get())); 300 content::Details<JobEventDetails>(details.get()));
297 } 301 }
298 302
299 void PrintJob::ControlledWorkerShutdown() { 303 void PrintJob::ControlledWorkerShutdown() {
300 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 304 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
301 305
302 // The deadlock this code works around is specific to window messaging on 306 // The deadlock this code works around is specific to window messaging on
303 // Windows, so we aren't likely to need it on any other platforms. 307 // Windows, so we aren't likely to need it on any other platforms.
304 #if defined(OS_WIN) 308 #if defined(OS_WIN)
305 // We could easily get into a deadlock case if worker_->Stop() is used; the 309 // We could easily get into a deadlock case if worker_->Stop() is used; the
306 // printer driver created a window as a child of the browser window. By 310 // printer driver created a window as a child of the browser window. By
307 // canceling the job, the printer driver initiated dialog box is destroyed, 311 // canceling the job, the printer driver initiated dialog box is destroyed,
308 // which sends a blocking message to its parent window. If the browser window 312 // which sends a blocking message to its parent window. If the browser window
309 // thread is not processing messages, a deadlock occurs. 313 // thread is not processing messages, a deadlock occurs.
310 // 314 //
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 348
345 // Temporarily allow it until we fix 349 // Temporarily allow it until we fix
346 // http://code.google.com/p/chromium/issues/detail?id=67044 350 // http://code.google.com/p/chromium/issues/detail?id=67044
347 base::ThreadRestrictions::ScopedAllowIO allow_io; 351 base::ThreadRestrictions::ScopedAllowIO allow_io;
348 352
349 // Now make sure the thread object is cleaned up. 353 // Now make sure the thread object is cleaned up.
350 worker_->Stop(); 354 worker_->Stop();
351 } 355 }
352 356
353 void PrintJob::Quit() { 357 void PrintJob::Quit() {
354 MessageLoop::current()->Quit(); 358 base::MessageLoop::current()->Quit();
355 } 359 }
356 360
357 // Takes settings_ ownership and will be deleted in the receiving thread. 361 // Takes settings_ ownership and will be deleted in the receiving thread.
358 JobEventDetails::JobEventDetails(Type type, 362 JobEventDetails::JobEventDetails(Type type,
359 PrintedDocument* document, 363 PrintedDocument* document,
360 PrintedPage* page) 364 PrintedPage* page)
361 : document_(document), 365 : document_(document),
362 page_(page), 366 page_(page),
363 type_(type) { 367 type_(type) {
364 } 368 }
365 369
366 JobEventDetails::~JobEventDetails() { 370 JobEventDetails::~JobEventDetails() {
367 } 371 }
368 372
369 PrintedDocument* JobEventDetails::document() const { 373 PrintedDocument* JobEventDetails::document() const {
370 return document_; 374 return document_;
371 } 375 }
372 376
373 PrintedPage* JobEventDetails::page() const { 377 PrintedPage* JobEventDetails::page() const {
374 return page_; 378 return page_;
375 } 379 }
376 380
377 } // namespace printing 381 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698