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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 destruction_observers_.AddObserver(destruction_observer); | 263 destruction_observers_.AddObserver(destruction_observer); |
264 } | 264 } |
265 | 265 |
266 void MessageLoop::RemoveDestructionObserver( | 266 void MessageLoop::RemoveDestructionObserver( |
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, |
| 274 const Closure& task) { |
274 DCHECK(!task.is_null()) << from_here.ToString(); | 275 DCHECK(!task.is_null()) << from_here.ToString(); |
275 PendingTask pending_task( | 276 PendingTask pending_task( |
276 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); | 277 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); |
277 AddToIncomingQueue(&pending_task); | 278 AddToIncomingQueue(&pending_task, false); |
| 279 } |
| 280 |
| 281 bool MessageLoop::TryPostTask( |
| 282 const tracked_objects::Location& from_here, |
| 283 const Closure& task) { |
| 284 DCHECK(!task.is_null()) << from_here.ToString(); |
| 285 PendingTask pending_task( |
| 286 from_here, task, CalculateDelayedRuntime(TimeDelta()), true); |
| 287 return AddToIncomingQueue(&pending_task, true); |
278 } | 288 } |
279 | 289 |
280 void MessageLoop::PostDelayedTask( | 290 void MessageLoop::PostDelayedTask( |
281 const tracked_objects::Location& from_here, | 291 const tracked_objects::Location& from_here, |
282 const Closure& task, | 292 const Closure& task, |
283 TimeDelta delay) { | 293 TimeDelta delay) { |
284 DCHECK(!task.is_null()) << from_here.ToString(); | 294 DCHECK(!task.is_null()) << from_here.ToString(); |
285 PendingTask pending_task( | 295 PendingTask pending_task( |
286 from_here, task, CalculateDelayedRuntime(delay), true); | 296 from_here, task, CalculateDelayedRuntime(delay), true); |
287 AddToIncomingQueue(&pending_task); | 297 AddToIncomingQueue(&pending_task, false); |
288 } | 298 } |
289 | 299 |
290 void MessageLoop::PostNonNestableTask( | 300 void MessageLoop::PostNonNestableTask( |
291 const tracked_objects::Location& from_here, | 301 const tracked_objects::Location& from_here, |
292 const Closure& task) { | 302 const Closure& task) { |
293 DCHECK(!task.is_null()) << from_here.ToString(); | 303 DCHECK(!task.is_null()) << from_here.ToString(); |
294 PendingTask pending_task( | 304 PendingTask pending_task( |
295 from_here, task, CalculateDelayedRuntime(TimeDelta()), false); | 305 from_here, task, CalculateDelayedRuntime(TimeDelta()), false); |
296 AddToIncomingQueue(&pending_task); | 306 AddToIncomingQueue(&pending_task, false); |
297 } | 307 } |
298 | 308 |
299 void MessageLoop::PostNonNestableDelayedTask( | 309 void MessageLoop::PostNonNestableDelayedTask( |
300 const tracked_objects::Location& from_here, | 310 const tracked_objects::Location& from_here, |
301 const Closure& task, | 311 const Closure& task, |
302 TimeDelta delay) { | 312 TimeDelta delay) { |
303 DCHECK(!task.is_null()) << from_here.ToString(); | 313 DCHECK(!task.is_null()) << from_here.ToString(); |
304 PendingTask pending_task( | 314 PendingTask pending_task( |
305 from_here, task, CalculateDelayedRuntime(delay), false); | 315 from_here, task, CalculateDelayedRuntime(delay), false); |
306 AddToIncomingQueue(&pending_task); | 316 AddToIncomingQueue(&pending_task, false); |
307 } | 317 } |
308 | 318 |
309 void MessageLoop::Run() { | 319 void MessageLoop::Run() { |
310 RunLoop run_loop; | 320 RunLoop run_loop; |
311 run_loop.Run(); | 321 run_loop.Run(); |
312 } | 322 } |
313 | 323 |
314 void MessageLoop::RunUntilIdle() { | 324 void MessageLoop::RunUntilIdle() { |
315 RunLoop run_loop; | 325 RunLoop run_loop; |
316 run_loop.RunUntilIdle(); | 326 run_loop.RunUntilIdle(); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
579 Time::ActivateHighResolutionTimer(false); | 589 Time::ActivateHighResolutionTimer(false); |
580 high_resolution_timer_expiration_ = TimeTicks(); | 590 high_resolution_timer_expiration_ = TimeTicks(); |
581 } | 591 } |
582 } | 592 } |
583 #endif | 593 #endif |
584 | 594 |
585 return delayed_run_time; | 595 return delayed_run_time; |
586 } | 596 } |
587 | 597 |
588 // Possibly called on a background thread! | 598 // Possibly called on a background thread! |
589 void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) { | 599 bool MessageLoop::AddToIncomingQueue(PendingTask* pending_task, |
| 600 bool use_try_lock) { |
590 // Warning: Don't try to short-circuit, and handle this thread's tasks more | 601 // 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 | 602 // directly, as it could starve handling of foreign threads. Put every task |
592 // into this queue. | 603 // into this queue. |
593 | 604 |
594 scoped_refptr<MessagePump> pump; | 605 scoped_refptr<MessagePump> pump; |
595 { | 606 { |
596 AutoLock locked(incoming_queue_lock_); | 607 if (use_try_lock) { |
597 | 608 if (!incoming_queue_lock_.Try()) { |
| 609 pending_task->task.Reset(); |
| 610 return false; |
| 611 } |
| 612 } else { |
| 613 incoming_queue_lock_.Acquire(); |
| 614 } |
| 615 AutoLock locked(incoming_queue_lock_, AutoLock::AlreadyAcquired()); |
598 // Initialize the sequence number. The sequence number is used for delayed | 616 // Initialize the sequence number. The sequence number is used for delayed |
599 // tasks (to faciliate FIFO sorting when two tasks have the same | 617 // tasks (to faciliate FIFO sorting when two tasks have the same |
600 // delayed_run_time value) and for identifying the task in about:tracing. | 618 // delayed_run_time value) and for identifying the task in about:tracing. |
601 pending_task->sequence_num = next_sequence_num_++; | 619 pending_task->sequence_num = next_sequence_num_++; |
602 | 620 |
603 TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask", | 621 TRACE_EVENT_FLOW_BEGIN0("task", "MessageLoop::PostTask", |
604 TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this))); | 622 TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this))); |
605 | 623 |
606 bool was_empty = incoming_queue_.empty(); | 624 bool was_empty = incoming_queue_.empty(); |
607 incoming_queue_.push(*pending_task); | 625 incoming_queue_.push(*pending_task); |
608 pending_task->task.Reset(); | 626 pending_task->task.Reset(); |
609 if (!was_empty) | 627 if (!was_empty) |
610 return; // Someone else should have started the sub-pump. | 628 return true; // Someone else should have started the sub-pump. |
611 | 629 |
612 pump = pump_; | 630 pump = pump_; |
613 } | 631 } |
614 // Since the incoming_queue_ may contain a task that destroys this message | 632 // 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|. | 633 // 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 | 634 // We use a stack-based reference to the message pump so that we can call |
617 // ScheduleWork outside of incoming_queue_lock_. | 635 // ScheduleWork outside of incoming_queue_lock_. |
618 | 636 |
619 pump->ScheduleWork(); | 637 pump->ScheduleWork(); |
| 638 return true; |
620 } | 639 } |
621 | 640 |
622 //------------------------------------------------------------------------------ | 641 //------------------------------------------------------------------------------ |
623 // Method and data for histogramming events and actions taken by each instance | 642 // Method and data for histogramming events and actions taken by each instance |
624 // on each thread. | 643 // on each thread. |
625 | 644 |
626 void MessageLoop::StartHistogrammer() { | 645 void MessageLoop::StartHistogrammer() { |
627 #if !defined(OS_NACL) // NaCl build has no metrics code. | 646 #if !defined(OS_NACL) // NaCl build has no metrics code. |
628 if (enable_histogrammer_ && !message_histogram_ | 647 if (enable_histogrammer_ && !message_histogram_ |
629 && StatisticsRecorder::IsActive()) { | 648 && StatisticsRecorder::IsActive()) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
806 fd, | 825 fd, |
807 persistent, | 826 persistent, |
808 mode, | 827 mode, |
809 controller, | 828 controller, |
810 delegate); | 829 delegate); |
811 } | 830 } |
812 | 831 |
813 #endif | 832 #endif |
814 | 833 |
815 } // namespace base | 834 } // namespace base |
OLD | NEW |