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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 84 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) | 84 VALUE_TO_NUMBER_AND_NAME(kTaskRunEvent) |
| 85 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) | 85 VALUE_TO_NUMBER_AND_NAME(kTimerEvent) |
| 86 | 86 |
| 87 {-1, NULL} // The list must be null terminated, per API to histogram. | 87 {-1, NULL} // The list must be null terminated, per API to histogram. |
| 88 }; | 88 }; |
| 89 | 89 |
| 90 bool enable_histogrammer_ = false; | 90 bool enable_histogrammer_ = false; |
| 91 | 91 |
| 92 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; | 92 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL; |
| 93 | 93 |
| 94 // Create a process-wide unique ID to represent this task in trace events. | |
| 95 uint64 GetTaskTraceID(const PendingTask& task, MessageLoop* loop) { | |
| 96 return (static_cast<uint64>(task.sequence_num) << 32) | | |
| 97 static_cast<uint64>(reinterpret_cast<intptr_t>(loop)); | |
|
jar (doing other things)
2012/09/13 02:14:49
Have you considered that message loops might gener
jbates
2012/09/13 17:07:01
Yep, that's definitely a concern. To deal with poi
| |
| 98 } | |
| 99 | |
| 94 } // namespace | 100 } // namespace |
| 95 | 101 |
| 96 //------------------------------------------------------------------------------ | 102 //------------------------------------------------------------------------------ |
| 97 | 103 |
| 98 #if defined(OS_WIN) | 104 #if defined(OS_WIN) |
| 99 | 105 |
| 100 // Upon a SEH exception in this thread, it restores the original unhandled | 106 // Upon a SEH exception in this thread, it restores the original unhandled |
| 101 // exception filter. | 107 // exception filter. |
| 102 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { | 108 static int SEHFilter(LPTOP_LEVEL_EXCEPTION_FILTER old_filter) { |
| 103 ::SetUnhandledExceptionFilter(old_filter); | 109 ::SetUnhandledExceptionFilter(old_filter); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 return false; | 433 return false; |
| 428 | 434 |
| 429 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); | 435 PendingTask pending_task = deferred_non_nestable_work_queue_.front(); |
| 430 deferred_non_nestable_work_queue_.pop(); | 436 deferred_non_nestable_work_queue_.pop(); |
| 431 | 437 |
| 432 RunTask(pending_task); | 438 RunTask(pending_task); |
| 433 return true; | 439 return true; |
| 434 } | 440 } |
| 435 | 441 |
| 436 void MessageLoop::RunTask(const PendingTask& pending_task) { | 442 void MessageLoop::RunTask(const PendingTask& pending_task) { |
| 443 TRACE_EVENT_ASYNC_END0("base", "MessageLoop::PostTask", | |
| 444 TRACE_ID_MANGLE(GetTaskTraceID(pending_task, this))); | |
|
jar (doing other things)
2012/09/13 02:14:49
... and just checking... when tracing is off, this
jbates
2012/09/13 17:07:01
Exactly.
| |
| 437 TRACE_EVENT2("task", "MessageLoop::RunTask", | 445 TRACE_EVENT2("task", "MessageLoop::RunTask", |
| 438 "src_file", pending_task.posted_from.file_name(), | 446 "src_file", pending_task.posted_from.file_name(), |
| 439 "src_func", pending_task.posted_from.function_name()); | 447 "src_func", pending_task.posted_from.function_name()); |
| 440 DCHECK(nestable_tasks_allowed_); | 448 DCHECK(nestable_tasks_allowed_); |
| 441 // Execute the task and assume the worst: It is probably not reentrant. | 449 // Execute the task and assume the worst: It is probably not reentrant. |
| 442 nestable_tasks_allowed_ = false; | 450 nestable_tasks_allowed_ = false; |
| 443 | 451 |
| 444 // Before running the task, store the program counter where it was posted | 452 // Before running the task, store the program counter where it was posted |
| 445 // and deliberately alias it to ensure it is on the stack if the task | 453 // and deliberately alias it to ensure it is on the stack if the task |
| 446 // crashes. Be careful not to assume that the variable itself will have the | 454 // crashes. Be careful not to assume that the variable itself will have the |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 475 return true; | 483 return true; |
| 476 } | 484 } |
| 477 | 485 |
| 478 // We couldn't run the task now because we're in a nested message loop | 486 // We couldn't run the task now because we're in a nested message loop |
| 479 // and the task isn't nestable. | 487 // and the task isn't nestable. |
| 480 deferred_non_nestable_work_queue_.push(pending_task); | 488 deferred_non_nestable_work_queue_.push(pending_task); |
| 481 return false; | 489 return false; |
| 482 } | 490 } |
| 483 | 491 |
| 484 void MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) { | 492 void MessageLoop::AddToDelayedWorkQueue(const PendingTask& pending_task) { |
| 485 // Move to the delayed work queue. Initialize the sequence number | 493 // Move to the delayed work queue. |
| 486 // before inserting into the delayed_work_queue_. The sequence number | 494 delayed_work_queue_.push(pending_task); |
| 487 // is used to faciliate FIFO sorting when two tasks have the same | |
| 488 // delayed_run_time value. | |
| 489 PendingTask new_pending_task(pending_task); | |
|
jbates
2012/09/13 01:36:32
Bonus: one less copy of the PendingTask struct.
| |
| 490 new_pending_task.sequence_num = next_sequence_num_++; | |
| 491 delayed_work_queue_.push(new_pending_task); | |
| 492 } | 495 } |
| 493 | 496 |
| 494 void MessageLoop::ReloadWorkQueue() { | 497 void MessageLoop::ReloadWorkQueue() { |
| 495 // We can improve performance of our loading tasks from incoming_queue_ to | 498 // We can improve performance of our loading tasks from incoming_queue_ to |
| 496 // work_queue_ by waiting until the last minute (work_queue_ is empty) to | 499 // work_queue_ by waiting until the last minute (work_queue_ is empty) to |
| 497 // load. That reduces the number of locks-per-task significantly when our | 500 // load. That reduces the number of locks-per-task significantly when our |
| 498 // queues get large. | 501 // queues get large. |
| 499 if (!work_queue_.empty()) | 502 if (!work_queue_.empty()) |
| 500 return; // Wait till we *really* need to lock and load. | 503 return; // Wait till we *really* need to lock and load. |
| 501 | 504 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 // Possibly called on a background thread! | 582 // Possibly called on a background thread! |
| 580 void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) { | 583 void MessageLoop::AddToIncomingQueue(PendingTask* pending_task) { |
| 581 // Warning: Don't try to short-circuit, and handle this thread's tasks more | 584 // Warning: Don't try to short-circuit, and handle this thread's tasks more |
| 582 // directly, as it could starve handling of foreign threads. Put every task | 585 // directly, as it could starve handling of foreign threads. Put every task |
| 583 // into this queue. | 586 // into this queue. |
| 584 | 587 |
| 585 scoped_refptr<base::MessagePump> pump; | 588 scoped_refptr<base::MessagePump> pump; |
| 586 { | 589 { |
| 587 base::AutoLock locked(incoming_queue_lock_); | 590 base::AutoLock locked(incoming_queue_lock_); |
| 588 | 591 |
| 592 // Initialize the sequence number. The sequence number is used for delayed | |
| 593 // tasks (to faciliate FIFO sorting when two tasks have the same | |
| 594 // delayed_run_time value) and for identifying the task in about:tracing. | |
| 595 pending_task->sequence_num = next_sequence_num_++; | |
|
jar (doing other things)
2012/09/13 02:14:49
:-)
Cute! You're using the incoming_queue_lock_,
jbates
2012/09/13 17:07:01
Done.
| |
| 596 | |
| 597 TRACE_EVENT_ASYNC_BEGIN0("base", "MessageLoop::PostTask", | |
| 598 TRACE_ID_MANGLE(GetTaskTraceID(*pending_task, this))); | |
| 599 | |
| 589 bool was_empty = incoming_queue_.empty(); | 600 bool was_empty = incoming_queue_.empty(); |
| 590 incoming_queue_.push(*pending_task); | 601 incoming_queue_.push(*pending_task); |
| 591 pending_task->task.Reset(); | 602 pending_task->task.Reset(); |
| 592 if (!was_empty) | 603 if (!was_empty) |
| 593 return; // Someone else should have started the sub-pump. | 604 return; // Someone else should have started the sub-pump. |
| 594 | 605 |
| 595 pump = pump_; | 606 pump = pump_; |
| 596 } | 607 } |
| 597 // Since the incoming_queue_ may contain a task that destroys this message | 608 // Since the incoming_queue_ may contain a task that destroys this message |
| 598 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. | 609 // loop, we cannot exit incoming_queue_lock_ until we are done with |this|. |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 768 Watcher *delegate) { | 779 Watcher *delegate) { |
| 769 return pump_libevent()->WatchFileDescriptor( | 780 return pump_libevent()->WatchFileDescriptor( |
| 770 fd, | 781 fd, |
| 771 persistent, | 782 persistent, |
| 772 static_cast<base::MessagePumpLibevent::Mode>(mode), | 783 static_cast<base::MessagePumpLibevent::Mode>(mode), |
| 773 controller, | 784 controller, |
| 774 delegate); | 785 delegate); |
| 775 } | 786 } |
| 776 | 787 |
| 777 #endif | 788 #endif |
| OLD | NEW |