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

Side by Side Diff: base/message_loop.cc

Issue 172101: Move MessageLoop TaskQueues to pointers.
Patch Set: scoped_ptr swap. Created 11 years, 3 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
« no previous file with comments | « base/message_loop.h ('k') | no next file » | 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "base/message_loop.h" 5 #include "base/message_loop.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 // static 71 // static
72 MessageLoop* MessageLoop::current() { 72 MessageLoop* MessageLoop::current() {
73 // TODO(darin): sadly, we cannot enable this yet since people call us even 73 // TODO(darin): sadly, we cannot enable this yet since people call us even
74 // when they have no intention of using us. 74 // when they have no intention of using us.
75 //DCHECK(loop) << "Ouch, did you forget to initialize me?"; 75 //DCHECK(loop) << "Ouch, did you forget to initialize me?";
76 return lazy_tls_ptr.Pointer()->Get(); 76 return lazy_tls_ptr.Pointer()->Get();
77 } 77 }
78 78
79 MessageLoop::MessageLoop(Type type) 79 MessageLoop::MessageLoop(Type type)
80 : type_(type), 80 : type_(type),
81 work_queue_(new TaskQueue),
81 nestable_tasks_allowed_(true), 82 nestable_tasks_allowed_(true),
82 exception_restoration_(false), 83 exception_restoration_(false),
84 incoming_queue_(new TaskQueue),
83 state_(NULL), 85 state_(NULL),
84 next_sequence_num_(0) { 86 next_sequence_num_(0) {
85 DCHECK(!current()) << "should only have one message loop per thread"; 87 DCHECK(!current()) << "should only have one message loop per thread";
86 lazy_tls_ptr.Pointer()->Set(this); 88 lazy_tls_ptr.Pointer()->Set(this);
87 89
88 #if defined(OS_WIN) 90 #if defined(OS_WIN)
89 // TODO(rvargas): Get rid of the OS guards. 91 // TODO(rvargas): Get rid of the OS guards.
90 if (type_ == TYPE_DEFAULT) { 92 if (type_ == TYPE_DEFAULT) {
91 pump_ = new base::MessagePumpDefault(); 93 pump_ = new base::MessagePumpDefault();
92 } else if (type_ == TYPE_IO) { 94 } else if (type_ == TYPE_IO) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 265 }
264 266
265 // Warning: Don't try to short-circuit, and handle this thread's tasks more 267 // Warning: Don't try to short-circuit, and handle this thread's tasks more
266 // directly, as it could starve handling of foreign threads. Put every task 268 // directly, as it could starve handling of foreign threads. Put every task
267 // into this queue. 269 // into this queue.
268 270
269 scoped_refptr<base::MessagePump> pump; 271 scoped_refptr<base::MessagePump> pump;
270 { 272 {
271 AutoLock locked(incoming_queue_lock_); 273 AutoLock locked(incoming_queue_lock_);
272 274
273 bool was_empty = incoming_queue_.empty(); 275 bool was_empty = incoming_queue_->empty();
274 incoming_queue_.push(pending_task); 276 incoming_queue_->push(pending_task);
275 if (!was_empty) 277 if (!was_empty)
276 return; // Someone else should have started the sub-pump. 278 return; // Someone else should have started the sub-pump.
277 279
278 pump = pump_; 280 pump = pump_;
279 } 281 }
280 // Since the incoming_queue_ may contain a task that destroys this message 282 // Since the incoming_queue_ may contain a task that destroys this message
281 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. 283 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|.
282 // We use a stack-based reference to the message pump so that we can call 284 // We use a stack-based reference to the message pump so that we can call
283 // ScheduleWork outside of incoming_queue_lock_. 285 // ScheduleWork outside of incoming_queue_lock_.
284 286
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 PendingTask new_pending_task(pending_task); 341 PendingTask new_pending_task(pending_task);
340 new_pending_task.sequence_num = next_sequence_num_++; 342 new_pending_task.sequence_num = next_sequence_num_++;
341 delayed_work_queue_.push(new_pending_task); 343 delayed_work_queue_.push(new_pending_task);
342 } 344 }
343 345
344 void MessageLoop::ReloadWorkQueue() { 346 void MessageLoop::ReloadWorkQueue() {
345 // We can improve performance of our loading tasks from incoming_queue_ to 347 // We can improve performance of our loading tasks from incoming_queue_ to
346 // work_queue_ by waiting until the last minute (work_queue_ is empty) to 348 // work_queue_ by waiting until the last minute (work_queue_ is empty) to
347 // load. That reduces the number of locks-per-task significantly when our 349 // load. That reduces the number of locks-per-task significantly when our
348 // queues get large. 350 // queues get large.
349 if (!work_queue_.empty()) 351 if (!work_queue_->empty())
350 return; // Wait till we *really* need to lock and load. 352 return; // Wait till we *really* need to lock and load.
351 353
352 // Acquire all we can from the inter-thread queue with one lock acquisition. 354 // Acquire all we can from the inter-thread queue with one lock acquisition.
353 { 355 {
354 AutoLock lock(incoming_queue_lock_); 356 AutoLock lock(incoming_queue_lock_);
355 if (incoming_queue_.empty()) 357 if (incoming_queue_->empty())
356 return; 358 return;
357 std::swap(incoming_queue_, work_queue_); 359 // std::queue does not define a swap specialization. Swap the pointers.
358 DCHECK(incoming_queue_.empty()); 360 incoming_queue_.swap(work_queue_);
361 DCHECK(incoming_queue_->empty());
359 } 362 }
360 } 363 }
361 364
362 bool MessageLoop::DeletePendingTasks() { 365 bool MessageLoop::DeletePendingTasks() {
363 bool did_work = !work_queue_.empty(); 366 bool did_work = !work_queue_->empty();
364 while (!work_queue_.empty()) { 367 while (!work_queue_->empty()) {
365 PendingTask pending_task = work_queue_.front(); 368 PendingTask pending_task = work_queue_->front();
366 work_queue_.pop(); 369 work_queue_->pop();
367 if (!pending_task.delayed_run_time.is_null()) { 370 if (!pending_task.delayed_run_time.is_null()) {
368 // We want to delete delayed tasks in the same order in which they would 371 // We want to delete delayed tasks in the same order in which they would
369 // normally be deleted in case of any funny dependencies between delayed 372 // normally be deleted in case of any funny dependencies between delayed
370 // tasks. 373 // tasks.
371 AddToDelayedWorkQueue(pending_task); 374 AddToDelayedWorkQueue(pending_task);
372 } else { 375 } else {
373 // TODO(darin): Delete all tasks once it is safe to do so. 376 // TODO(darin): Delete all tasks once it is safe to do so.
374 // Until it is totally safe, just do it when running Purify or 377 // Until it is totally safe, just do it when running Purify or
375 // Valgrind. 378 // Valgrind.
376 #if defined(PURIFY) 379 #if defined(PURIFY)
(...skipping 29 matching lines...) Expand all
406 } 409 }
407 410
408 bool MessageLoop::DoWork() { 411 bool MessageLoop::DoWork() {
409 if (!nestable_tasks_allowed_) { 412 if (!nestable_tasks_allowed_) {
410 // Task can't be executed right now. 413 // Task can't be executed right now.
411 return false; 414 return false;
412 } 415 }
413 416
414 for (;;) { 417 for (;;) {
415 ReloadWorkQueue(); 418 ReloadWorkQueue();
416 if (work_queue_.empty()) 419 if (work_queue_->empty())
417 break; 420 break;
418 421
419 // Execute oldest task. 422 // Execute oldest task.
420 do { 423 do {
421 PendingTask pending_task = work_queue_.front(); 424 PendingTask pending_task = work_queue_->front();
422 work_queue_.pop(); 425 work_queue_->pop();
423 if (!pending_task.delayed_run_time.is_null()) { 426 if (!pending_task.delayed_run_time.is_null()) {
424 AddToDelayedWorkQueue(pending_task); 427 AddToDelayedWorkQueue(pending_task);
425 // If we changed the topmost task, then it is time to re-schedule. 428 // If we changed the topmost task, then it is time to re-schedule.
426 if (delayed_work_queue_.top().task == pending_task.task) 429 if (delayed_work_queue_.top().task == pending_task.task)
427 pump_->ScheduleDelayedWork(pending_task.delayed_run_time); 430 pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
428 } else { 431 } else {
429 if (DeferOrRunPendingTask(pending_task)) 432 if (DeferOrRunPendingTask(pending_task))
430 return true; 433 return true;
431 } 434 }
432 } while (!work_queue_.empty()); 435 } while (!work_queue_->empty());
433 } 436 }
434 437
435 // Nothing happened. 438 // Nothing happened.
436 return false; 439 return false;
437 } 440 }
438 441
439 bool MessageLoop::DoDelayedWork(Time* next_delayed_work_time) { 442 bool MessageLoop::DoDelayedWork(Time* next_delayed_work_time) {
440 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { 443 if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
441 *next_delayed_work_time = Time(); 444 *next_delayed_work_time = Time();
442 return false; 445 return false;
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 Watcher *delegate) { 625 Watcher *delegate) {
623 return pump_libevent()->WatchFileDescriptor( 626 return pump_libevent()->WatchFileDescriptor(
624 fd, 627 fd,
625 persistent, 628 persistent,
626 static_cast<base::MessagePumpLibevent::Mode>(mode), 629 static_cast<base::MessagePumpLibevent::Mode>(mode),
627 controller, 630 controller,
628 delegate); 631 delegate);
629 } 632 }
630 633
631 #endif 634 #endif
OLDNEW
« no previous file with comments | « base/message_loop.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698