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 |