Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/message_loop.h" | 5 #include "base/message_loop.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 267 DestructionObserver* destruction_observer) { | 267 DestructionObserver* destruction_observer) { |
| 268 DCHECK_EQ(this, current()); | 268 DCHECK_EQ(this, current()); |
| 269 destruction_observers_.RemoveObserver(destruction_observer); | 269 destruction_observers_.RemoveObserver(destruction_observer); |
| 270 } | 270 } |
| 271 | 271 |
| 272 void MessageLoop::PostTask( | 272 void MessageLoop::PostTask( |
| 273 const tracked_objects::Location& from_here, const Closure& task) { | 273 const tracked_objects::Location& from_here, const Closure& task) { |
| 274 DCHECK(!task.is_null()) << from_here.ToString(); | 274 DCHECK(!task.is_null()) << from_here.ToString(); |
| 275 PendingTask pending_task( | 275 PendingTask pending_task( |
| 276 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); | 276 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); |
| 277 AddToIncomingQueue(&pending_task); | 277 AddToIncomingQueue(&pending_task, false); |
| 278 } | |
| 279 | |
| 280 bool MessageLoop::TryPostTask( | |
| 281 const tracked_objects::Location& from_here, const Closure& task) { | |
|
jar (doing other things)
2013/04/26 21:59:43
nit: one arg per line if you need to wrap.
You co
| |
| 282 DCHECK(!task.is_null()) << from_here.ToString(); | |
| 283 PendingTask pending_task( | |
| 284 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); | |
| 285 return AddToIncomingQueue(&pending_task, true); | |
| 278 } | 286 } |
| 279 | 287 |
| 280 void MessageLoop::PostDelayedTask( | 288 void MessageLoop::PostDelayedTask( |
| 281 const tracked_objects::Location& from_here, | 289 const tracked_objects::Location& from_here, |
| 282 const Closure& task, | 290 const Closure& task, |
| 283 TimeDelta delay) { | 291 TimeDelta delay) { |
| 284 DCHECK(!task.is_null()) << from_here.ToString(); | 292 DCHECK(!task.is_null()) << from_here.ToString(); |
| 285 PendingTask pending_task( | 293 PendingTask pending_task( |
| 286 from_here, task, CalculateDelayedRuntime(delay), true); | 294 from_here, task, CalculateDelayedRuntime(delay), true); |
| 287 AddToIncomingQueue(&pending_task); | 295 AddToIncomingQueue(&pending_task, false); |
| 288 } | 296 } |
| 289 | 297 |
| 290 void MessageLoop::PostNonNestableTask( | 298 void MessageLoop::PostNonNestableTask( |
| 291 const tracked_objects::Location& from_here, | 299 const tracked_objects::Location& from_here, |
| 292 const Closure& task) { | 300 const Closure& task) { |
| 293 DCHECK(!task.is_null()) << from_here.ToString(); | 301 DCHECK(!task.is_null()) << from_here.ToString(); |
| 294 PendingTask pending_task( | 302 PendingTask pending_task( |
| 295 from_here, task, CalculateDelayedRuntime(TimeDelta()), false); | 303 from_here, task, CalculateDelayedRuntime(TimeDelta()), false); |
| 296 AddToIncomingQueue(&pending_task); | 304 AddToIncomingQueue(&pending_task, false); |
| 297 } | 305 } |
| 298 | 306 |
| 299 void MessageLoop::PostNonNestableDelayedTask( | 307 void MessageLoop::PostNonNestableDelayedTask( |
| 300 const tracked_objects::Location& from_here, | 308 const tracked_objects::Location& from_here, |
| 301 const Closure& task, | 309 const Closure& task, |
| 302 TimeDelta delay) { | 310 TimeDelta delay) { |
| 303 DCHECK(!task.is_null()) << from_here.ToString(); | 311 DCHECK(!task.is_null()) << from_here.ToString(); |
| 304 PendingTask pending_task( | 312 PendingTask pending_task( |
| 305 from_here, task, CalculateDelayedRuntime(delay), false); | 313 from_here, task, CalculateDelayedRuntime(delay), false); |
| 306 AddToIncomingQueue(&pending_task); | 314 AddToIncomingQueue(&pending_task, false); |
| 307 } | 315 } |
| 308 | 316 |
| 309 void MessageLoop::Run() { | 317 void MessageLoop::Run() { |
| 310 RunLoop run_loop; | 318 RunLoop run_loop; |
| 311 run_loop.Run(); | 319 run_loop.Run(); |
| 312 } | 320 } |
| 313 | 321 |
| 314 void MessageLoop::RunUntilIdle() { | 322 void MessageLoop::RunUntilIdle() { |
| 315 RunLoop run_loop; | 323 RunLoop run_loop; |
| 316 run_loop.RunUntilIdle(); | 324 run_loop.RunUntilIdle(); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 Time::ActivateHighResolutionTimer(false); | 587 Time::ActivateHighResolutionTimer(false); |
| 580 high_resolution_timer_expiration_ = TimeTicks(); | 588 high_resolution_timer_expiration_ = TimeTicks(); |
| 581 } | 589 } |
| 582 } | 590 } |
| 583 #endif | 591 #endif |
| 584 | 592 |
| 585 return delayed_run_time; | 593 return delayed_run_time; |
| 586 } | 594 } |
| 587 | 595 |
| 588 // Possibly called on a background thread! | 596 // Possibly called on a background thread! |
| 589 void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) { | 597 bool MessageLoop::AddToIncomingQueue(PendingTask* pending_task, |
| 598 bool use_try_lock) { | |
| 590 // Warning: Don't try to short-circuit, and handle this thread's tasks more | 599 // Warning: Don't try to short-circuit, and handle this thread's tasks more |
| 591 // directly, as it could starve handling of foreign threads. Put every task | 600 // directly, as it could starve handling of foreign threads. Put every task |
| 592 // into this queue. | 601 // into this queue. |
| 593 | 602 |
| 594 scoped_refptr<MessagePump> pump; | 603 scoped_refptr<MessagePump> pump; |
| 595 { | 604 { |
| 596 AutoLock locked(incoming_queue_lock_); | 605 if (use_try_lock) { |
| 597 | 606 if (!incoming_queue_lock_.Try()) { |
| 607 pending_task->task.Reset(); | |
| 608 return false; | |
| 609 } | |
| 610 } else { | |
| 611 incoming_queue_lock_.Acquire(); | |
| 612 } | |
| 613 AutoLock locked(incoming_queue_lock_, AutoLock::NoAcquire()); | |
|
jar (doing other things)
2013/04/21 15:29:35
Interesting API. Did you consider having a second
cpu_(ooo_6.6-7.5)
2013/04/22 23:30:59
Yeah, the main drawback is having to add state to
| |
| 598 // Initialize the sequence number. The sequence number is used for delayed | 614 // Initialize the sequence number. The sequence number is used for delayed |
| 599 // tasks (to faciliate FIFO sorting when two tasks have the same | 615 // tasks (to faciliate FIFO sorting when two tasks have the same |
| 600 // delayed_run_time value) and for identifying the task in about:tracing. | 616 // delayed_run_time value) and for identifying the task in about:tracing. |
| 601 pending_task->sequence_num = next_sequence_num_++; | 617 pending_task->sequence_num = next_sequence_num_++; |
| 602 | 618 |
| 603 TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask", | 619 TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask", |
| 604 TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this))); | 620 TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this))); |
| 605 | 621 |
| 606 bool was_empty = incoming_queue_.empty(); | 622 bool was_empty = incoming_queue_.empty(); |
| 607 incoming_queue_.push(*pending_task); | 623 incoming_queue_.push(*pending_task); |
| 608 pending_task->task.Reset(); | 624 pending_task->task.Reset(); |
| 609 if (!was_empty) | 625 if (!was_empty) |
| 610 return; // Someone else should have started the sub-pump. | 626 return true; // Someone else should have started the sub-pump. |
| 611 | 627 |
| 612 pump = pump_; | 628 pump = pump_; |
| 613 } | 629 } |
| 614 // Since the incoming_queue_ may contain a task that destroys this message | 630 // Since the incoming_queue_ may contain a task that destroys this message |
| 615 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. | 631 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. |
| 616 // We use a stack-based reference to the message pump so that we can call | 632 // We use a stack-based reference to the message pump so that we can call |
| 617 // ScheduleWork outside of incoming_queue_lock_. | 633 // ScheduleWork outside of incoming_queue_lock_. |
| 618 | 634 |
| 619 pump->ScheduleWork(); | 635 pump->ScheduleWork(); |
| 636 return true; | |
| 620 } | 637 } |
| 621 | 638 |
| 622 //------------------------------------------------------------------------------ | 639 //------------------------------------------------------------------------------ |
| 623 // Method and data for histogramming events and actions taken by each instance | 640 // Method and data for histogramming events and actions taken by each instance |
| 624 // on each thread. | 641 // on each thread. |
| 625 | 642 |
| 626 void MessageLoop::StartHistogrammer() { | 643 void MessageLoop::StartHistogrammer() { |
| 627 #if !defined(OS_NACL) // NaCl build has no metrics code. | 644 #if !defined(OS_NACL) // NaCl build has no metrics code. |
| 628 if (enable_histogrammer_ && !message_histogram_ | 645 if (enable_histogrammer_ && !message_histogram_ |
| 629 && StatisticsRecorder::IsActive()) { | 646 && StatisticsRecorder::IsActive()) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 806 fd, | 823 fd, |
| 807 persistent, | 824 persistent, |
| 808 mode, | 825 mode, |
| 809 controller, | 826 controller, |
| 810 delegate); | 827 delegate); |
| 811 } | 828 } |
| 812 | 829 |
| 813 #endif | 830 #endif |
| 814 | 831 |
| 815 } // namespace base | 832 } // namespace base |
| OLD | NEW |