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

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: rebase again Created 7 years, 6 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
« no previous file with comments | « chrome/browser/printing/print_job.h ('k') | chrome/browser/printing/print_job_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 13 matching lines...) Expand all
24 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner, 24 void HoldRefCallback(const scoped_refptr<printing::PrintJobWorkerOwner>& owner,
25 const base::Closure& callback) { 25 const base::Closure& callback) {
26 callback.Run(); 26 callback.Run();
27 } 27 }
28 28
29 } // namespace 29 } // namespace
30 30
31 namespace printing { 31 namespace printing {
32 32
33 PrintJob::PrintJob() 33 PrintJob::PrintJob()
34 : ui_message_loop_(MessageLoop::current()), 34 : ui_message_loop_(base::MessageLoop::current()),
35 source_(NULL), 35 source_(NULL),
36 worker_(), 36 worker_(),
37 settings_(), 37 settings_(),
38 is_job_pending_(false), 38 is_job_pending_(false),
39 is_canceling_(false), 39 is_canceling_(false),
40 is_stopping_(false), 40 is_stopping_(false),
41 is_stopped_(false), 41 is_stopped_(false),
42 quit_factory_(this), 42 quit_factory_(this),
43 weak_ptr_factory_(this) { 43 weak_ptr_factory_(this) {
44 DCHECK(ui_message_loop_); 44 DCHECK(ui_message_loop_);
45 // This is normally a UI message loop, but in unit tests, the message loop is 45 // This is normally a UI message loop, but in unit tests, the message loop is
46 // of the 'default' type. 46 // of the 'default' type.
47 DCHECK(ui_message_loop_->type() == MessageLoop::TYPE_UI || 47 DCHECK(ui_message_loop_->type() == base::MessageLoop::TYPE_UI ||
48 ui_message_loop_->type() == MessageLoop::TYPE_DEFAULT); 48 ui_message_loop_->type() == base::MessageLoop::TYPE_DEFAULT);
49 ui_message_loop_->AddDestructionObserver(this); 49 ui_message_loop_->AddDestructionObserver(this);
50 } 50 }
51 51
52 PrintJob::~PrintJob() { 52 PrintJob::~PrintJob() {
53 ui_message_loop_->RemoveDestructionObserver(this); 53 ui_message_loop_->RemoveDestructionObserver(this);
54 // The job should be finished (or at least canceled) when it is destroyed. 54 // The job should be finished (or at least canceled) when it is destroyed.
55 DCHECK(!is_job_pending_); 55 DCHECK(!is_job_pending_);
56 DCHECK(!is_canceling_); 56 DCHECK(!is_canceling_);
57 if (worker_.get()) 57 if (worker_.get())
58 DCHECK(worker_->message_loop() == NULL); 58 DCHECK(worker_->message_loop() == NULL);
59 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 59 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
60 } 60 }
61 61
62 void PrintJob::Initialize(PrintJobWorkerOwner* job, 62 void PrintJob::Initialize(PrintJobWorkerOwner* job,
63 PrintedPagesSource* source, 63 PrintedPagesSource* source,
64 int page_count) { 64 int page_count) {
65 DCHECK(!source_); 65 DCHECK(!source_);
66 DCHECK(!worker_.get()); 66 DCHECK(!worker_.get());
67 DCHECK(!is_job_pending_); 67 DCHECK(!is_job_pending_);
68 DCHECK(!is_canceling_); 68 DCHECK(!is_canceling_);
69 DCHECK(!document_.get()); 69 DCHECK(!document_.get());
70 source_ = source; 70 source_ = source;
71 worker_.reset(job->DetachWorker(this)); 71 worker_.reset(job->DetachWorker(this));
72 settings_ = job->settings(); 72 settings_ = job->settings();
73 73
74 PrintedDocument* new_doc = 74 PrintedDocument* new_doc =
75 new PrintedDocument(settings_, source_, job->cookie()); 75 new PrintedDocument(settings_, source_, job->cookie());
76 new_doc->set_page_count(page_count); 76 new_doc->set_page_count(page_count);
77 UpdatePrintedDocument(new_doc); 77 UpdatePrintedDocument(new_doc);
78 78
79 // Don't forget to register to our own messages. 79 // Don't forget to register to our own messages.
80 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 80 registrar_.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
81 content::Source<PrintJob>(this)); 81 content::Source<PrintJob>(this));
82 } 82 }
83 83
84 void PrintJob::Observe(int type, 84 void PrintJob::Observe(int type,
85 const content::NotificationSource& source, 85 const content::NotificationSource& source,
86 const content::NotificationDetails& details) { 86 const content::NotificationDetails& details) {
87 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 87 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
88 switch (type) { 88 switch (type) {
89 case chrome::NOTIFICATION_PRINT_JOB_EVENT: { 89 case chrome::NOTIFICATION_PRINT_JOB_EVENT: {
90 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr()); 90 OnNotifyPrintJobEvent(*content::Details<JobEventDetails>(details).ptr());
91 break; 91 break;
92 } 92 }
93 default: { 93 default: {
94 break; 94 break;
95 } 95 }
96 } 96 }
97 } 97 }
(...skipping 21 matching lines...) Expand all
119 // Always use an invalid cookie in this case. 119 // Always use an invalid cookie in this case.
120 return 0; 120 return 0;
121 return document_->cookie(); 121 return document_->cookie();
122 } 122 }
123 123
124 void PrintJob::WillDestroyCurrentMessageLoop() { 124 void PrintJob::WillDestroyCurrentMessageLoop() {
125 NOTREACHED(); 125 NOTREACHED();
126 } 126 }
127 127
128 void PrintJob::StartPrinting() { 128 void PrintJob::StartPrinting() {
129 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 129 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
130 DCHECK(worker_->message_loop()); 130 DCHECK(worker_->message_loop());
131 DCHECK(!is_job_pending_); 131 DCHECK(!is_job_pending_);
132 if (!worker_->message_loop() || is_job_pending_) 132 if (!worker_->message_loop() || is_job_pending_)
133 return; 133 return;
134 134
135 // Real work is done in PrintJobWorker::StartPrinting(). 135 // Real work is done in PrintJobWorker::StartPrinting().
136 worker_->message_loop()->PostTask( 136 worker_->message_loop()->PostTask(
137 FROM_HERE, 137 FROM_HERE,
138 base::Bind(&HoldRefCallback, make_scoped_refptr(this), 138 base::Bind(&HoldRefCallback, make_scoped_refptr(this),
139 base::Bind(&PrintJobWorker::StartPrinting, 139 base::Bind(&PrintJobWorker::StartPrinting,
140 base::Unretained(worker_.get()), document_))); 140 base::Unretained(worker_.get()), document_)));
141 // Set the flag right now. 141 // Set the flag right now.
142 is_job_pending_ = true; 142 is_job_pending_ = true;
143 143
144 // Tell everyone! 144 // Tell everyone!
145 scoped_refptr<JobEventDetails> details( 145 scoped_refptr<JobEventDetails> details(
146 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL)); 146 new JobEventDetails(JobEventDetails::NEW_DOC, document_.get(), NULL));
147 content::NotificationService::current()->Notify( 147 content::NotificationService::current()->Notify(
148 chrome::NOTIFICATION_PRINT_JOB_EVENT, 148 chrome::NOTIFICATION_PRINT_JOB_EVENT,
149 content::Source<PrintJob>(this), 149 content::Source<PrintJob>(this),
150 content::Details<JobEventDetails>(details.get())); 150 content::Details<JobEventDetails>(details.get()));
151 } 151 }
152 152
153 void PrintJob::Stop() { 153 void PrintJob::Stop() {
154 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 154 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
155 155
156 if (quit_factory_.HasWeakPtrs()) { 156 if (quit_factory_.HasWeakPtrs()) {
157 // In case we're running a nested message loop to wait for a job to finish, 157 // In case we're running a nested message loop to wait for a job to finish,
158 // and we finished before the timeout, quit the nested loop right away. 158 // and we finished before the timeout, quit the nested loop right away.
159 Quit(); 159 Quit();
160 quit_factory_.InvalidateWeakPtrs(); 160 quit_factory_.InvalidateWeakPtrs();
161 } 161 }
162 162
163 // Be sure to live long enough. 163 // Be sure to live long enough.
164 scoped_refptr<PrintJob> handle(this); 164 scoped_refptr<PrintJob> handle(this);
165 165
166 MessageLoop* worker_loop = worker_->message_loop(); 166 base::MessageLoop* worker_loop = worker_->message_loop();
167 if (worker_loop) { 167 if (worker_loop) {
168 ControlledWorkerShutdown(); 168 ControlledWorkerShutdown();
169 169
170 is_job_pending_ = false; 170 is_job_pending_ = false;
171 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, 171 registrar_.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT,
172 content::Source<PrintJob>(this)); 172 content::Source<PrintJob>(this));
173 } 173 }
174 // Flush the cached document. 174 // Flush the cached document.
175 UpdatePrintedDocument(NULL); 175 UpdatePrintedDocument(NULL);
176 } 176 }
177 177
178 void PrintJob::Cancel() { 178 void PrintJob::Cancel() {
179 if (is_canceling_) 179 if (is_canceling_)
180 return; 180 return;
181 is_canceling_ = true; 181 is_canceling_ = true;
182 182
183 // Be sure to live long enough. 183 // Be sure to live long enough.
184 scoped_refptr<PrintJob> handle(this); 184 scoped_refptr<PrintJob> handle(this);
185 185
186 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 186 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
187 MessageLoop* worker_loop = worker_.get() ? worker_->message_loop() : NULL; 187 base::MessageLoop* worker_loop =
188 worker_.get() ? worker_->message_loop() : NULL;
188 if (worker_loop) { 189 if (worker_loop) {
189 // Call this right now so it renders the context invalid. Do not use 190 // Call this right now so it renders the context invalid. Do not use
190 // InvokeLater since it would take too much time. 191 // InvokeLater since it would take too much time.
191 worker_->Cancel(); 192 worker_->Cancel();
192 } 193 }
193 // Make sure a Cancel() is broadcast. 194 // Make sure a Cancel() is broadcast.
194 scoped_refptr<JobEventDetails> details( 195 scoped_refptr<JobEventDetails> details(
195 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL)); 196 new JobEventDetails(JobEventDetails::FAILED, NULL, NULL));
196 content::NotificationService::current()->Notify( 197 content::NotificationService::current()->Notify(
197 chrome::NOTIFICATION_PRINT_JOB_EVENT, 198 chrome::NOTIFICATION_PRINT_JOB_EVENT,
198 content::Source<PrintJob>(this), 199 content::Source<PrintJob>(this),
199 content::Details<JobEventDetails>(details.get())); 200 content::Details<JobEventDetails>(details.get()));
200 Stop(); 201 Stop();
201 is_canceling_ = false; 202 is_canceling_ = false;
202 } 203 }
203 204
204 bool PrintJob::FlushJob(base::TimeDelta timeout) { 205 bool PrintJob::FlushJob(base::TimeDelta timeout) {
205 // Make sure the object outlive this message loop. 206 // Make sure the object outlive this message loop.
206 scoped_refptr<PrintJob> handle(this); 207 scoped_refptr<PrintJob> handle(this);
207 208
208 MessageLoop::current()->PostDelayedTask(FROM_HERE, 209 base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
209 base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()), timeout); 210 base::Bind(&PrintJob::Quit, quit_factory_.GetWeakPtr()), timeout);
210 211
211 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current()); 212 base::MessageLoop::ScopedNestableTaskAllower allow(
212 MessageLoop::current()->Run(); 213 base::MessageLoop::current());
214 base::MessageLoop::current()->Run();
213 215
214 return true; 216 return true;
215 } 217 }
216 218
217 void PrintJob::DisconnectSource() { 219 void PrintJob::DisconnectSource() {
218 source_ = NULL; 220 source_ = NULL;
219 if (document_.get()) 221 if (document_.get())
220 document_->DisconnectSource(); 222 document_->DisconnectSource();
221 } 223 }
222 224
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 case JobEventDetails::NEW_DOC: 276 case JobEventDetails::NEW_DOC:
275 case JobEventDetails::NEW_PAGE: 277 case JobEventDetails::NEW_PAGE:
276 case JobEventDetails::PAGE_DONE: 278 case JobEventDetails::PAGE_DONE:
277 case JobEventDetails::JOB_DONE: 279 case JobEventDetails::JOB_DONE:
278 case JobEventDetails::ALL_PAGES_REQUESTED: { 280 case JobEventDetails::ALL_PAGES_REQUESTED: {
279 // Don't care. 281 // Don't care.
280 break; 282 break;
281 } 283 }
282 case JobEventDetails::DOC_DONE: { 284 case JobEventDetails::DOC_DONE: {
283 // This will call Stop() and broadcast a JOB_DONE message. 285 // This will call Stop() and broadcast a JOB_DONE message.
284 MessageLoop::current()->PostTask( 286 base::MessageLoop::current()->PostTask(
285 FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this)); 287 FROM_HERE, base::Bind(&PrintJob::OnDocumentDone, this));
286 break; 288 break;
287 } 289 }
288 default: { 290 default: {
289 NOTREACHED(); 291 NOTREACHED();
290 break; 292 break;
291 } 293 }
292 } 294 }
293 } 295 }
294 296
295 void PrintJob::OnDocumentDone() { 297 void PrintJob::OnDocumentDone() {
296 // Be sure to live long enough. The instance could be destroyed by the 298 // Be sure to live long enough. The instance could be destroyed by the
297 // JOB_DONE broadcast. 299 // JOB_DONE broadcast.
298 scoped_refptr<PrintJob> handle(this); 300 scoped_refptr<PrintJob> handle(this);
299 301
300 // Stop the worker thread. 302 // Stop the worker thread.
301 Stop(); 303 Stop();
302 304
303 scoped_refptr<JobEventDetails> details( 305 scoped_refptr<JobEventDetails> details(
304 new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL)); 306 new JobEventDetails(JobEventDetails::JOB_DONE, document_.get(), NULL));
305 content::NotificationService::current()->Notify( 307 content::NotificationService::current()->Notify(
306 chrome::NOTIFICATION_PRINT_JOB_EVENT, 308 chrome::NOTIFICATION_PRINT_JOB_EVENT,
307 content::Source<PrintJob>(this), 309 content::Source<PrintJob>(this),
308 content::Details<JobEventDetails>(details.get())); 310 content::Details<JobEventDetails>(details.get()));
309 } 311 }
310 312
311 void PrintJob::ControlledWorkerShutdown() { 313 void PrintJob::ControlledWorkerShutdown() {
312 DCHECK_EQ(ui_message_loop_, MessageLoop::current()); 314 DCHECK_EQ(ui_message_loop_, base::MessageLoop::current());
313 315
314 // The deadlock this code works around is specific to window messaging on 316 // The deadlock this code works around is specific to window messaging on
315 // Windows, so we aren't likely to need it on any other platforms. 317 // Windows, so we aren't likely to need it on any other platforms.
316 #if defined(OS_WIN) 318 #if defined(OS_WIN)
317 // We could easily get into a deadlock case if worker_->Stop() is used; the 319 // We could easily get into a deadlock case if worker_->Stop() is used; the
318 // printer driver created a window as a child of the browser window. By 320 // printer driver created a window as a child of the browser window. By
319 // canceling the job, the printer driver initiated dialog box is destroyed, 321 // canceling the job, the printer driver initiated dialog box is destroyed,
320 // which sends a blocking message to its parent window. If the browser window 322 // which sends a blocking message to its parent window. If the browser window
321 // thread is not processing messages, a deadlock occurs. 323 // thread is not processing messages, a deadlock occurs.
322 // 324 //
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 scoped_refptr<PrintJob>(this)), 370 scoped_refptr<PrintJob>(this)),
369 false); 371 false);
370 } 372 }
371 373
372 void PrintJob::HoldUntilStopIsCalled(const scoped_refptr<PrintJob>&) { 374 void PrintJob::HoldUntilStopIsCalled(const scoped_refptr<PrintJob>&) {
373 is_stopped_ = true; 375 is_stopped_ = true;
374 is_stopping_ = false; 376 is_stopping_ = false;
375 } 377 }
376 378
377 void PrintJob::Quit() { 379 void PrintJob::Quit() {
378 MessageLoop::current()->Quit(); 380 base::MessageLoop::current()->Quit();
379 } 381 }
380 382
381 // Takes settings_ ownership and will be deleted in the receiving thread. 383 // Takes settings_ ownership and will be deleted in the receiving thread.
382 JobEventDetails::JobEventDetails(Type type, 384 JobEventDetails::JobEventDetails(Type type,
383 PrintedDocument* document, 385 PrintedDocument* document,
384 PrintedPage* page) 386 PrintedPage* page)
385 : document_(document), 387 : document_(document),
386 page_(page), 388 page_(page),
387 type_(type) { 389 type_(type) {
388 } 390 }
389 391
390 JobEventDetails::~JobEventDetails() { 392 JobEventDetails::~JobEventDetails() {
391 } 393 }
392 394
393 PrintedDocument* JobEventDetails::document() const { 395 PrintedDocument* JobEventDetails::document() const {
394 return document_; 396 return document_;
395 } 397 }
396 398
397 PrintedPage* JobEventDetails::page() const { 399 PrintedPage* JobEventDetails::page() const {
398 return page_; 400 return page_;
399 } 401 }
400 402
401 } // namespace printing 403 } // namespace printing
OLDNEW
« no previous file with comments | « chrome/browser/printing/print_job.h ('k') | chrome/browser/printing/print_job_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698