| Index: chrome_frame/task_marshaller.cc
|
| diff --git a/chrome_frame/task_marshaller.cc b/chrome_frame/task_marshaller.cc
|
| index f597262645a00abadac34e1cd0638f0f92bab8c5..9ad74a0ab5615c710f804a357579643d9da1b606 100644
|
| --- a/chrome_frame/task_marshaller.cc
|
| +++ b/chrome_frame/task_marshaller.cc
|
| @@ -5,17 +5,17 @@
|
| #include "chrome_frame/task_marshaller.h"
|
| #include "base/task.h"
|
|
|
| -TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue() {
|
| - wnd_ = NULL;
|
| - msg_ = 0xFFFF;
|
| +TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue()
|
| + : wnd_(NULL),
|
| + msg_(0xFFFF) {
|
| }
|
|
|
| TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() {
|
| - DeleteAll();
|
| + ClearTasks();
|
| }
|
|
|
| void TaskMarshallerThroughMessageQueue::PostTask(
|
| - const tracked_objects::Location& from_here, Task* task) {
|
| + const tracked_objects::Location& from_here, const base::Closure& task) {
|
| DCHECK(wnd_ != NULL);
|
| lock_.Acquire();
|
| bool has_work = !pending_tasks_.empty();
|
| @@ -28,22 +28,27 @@ void TaskMarshallerThroughMessageQueue::PostTask(
|
|
|
| if (!::PostMessage(wnd_, msg_, 0, 0)) {
|
| DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
|
| - DeleteAll();
|
| + ClearTasks();
|
| }
|
| }
|
|
|
| void TaskMarshallerThroughMessageQueue::PostDelayedTask(
|
| const tracked_objects::Location& source,
|
| - Task* task,
|
| + const base::Closure& task,
|
| base::TimeDelta& delay) {
|
| - DCHECK(wnd_ != NULL);
|
| + DCHECK(wnd_);
|
| +
|
| base::AutoLock lock(lock_);
|
| - DelayedTask delayed_task(task, base::Time::Now() + delay);
|
| + base::PendingTask delayed_task(source, task, base::TimeTicks::Now() + delay,
|
| + true);
|
| + base::TimeTicks top_run_time = delayed_tasks_.top().delayed_run_time;
|
| delayed_tasks_.push(delayed_task);
|
| - // If we become the 'top' task - reschedule the timer.
|
| - if (delayed_tasks_.top().task == task) {
|
| +
|
| + // Reschedule the timer if |delayed_task| will be the next delayed task to
|
| + // run.
|
| + if (delayed_task.delayed_run_time < top_run_time) {
|
| ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
|
| - static_cast<DWORD>(delay.InMilliseconds()), NULL);
|
| + static_cast<DWORD>(delay.InMilliseconds()), NULL);
|
| }
|
| }
|
|
|
| @@ -68,28 +73,27 @@ BOOL TaskMarshallerThroughMessageQueue::ProcessWindowMessage(HWND hWnd,
|
| return FALSE;
|
| }
|
|
|
| -Task* TaskMarshallerThroughMessageQueue::PopTask() {
|
| +base::Closure TaskMarshallerThroughMessageQueue::PopTask() {
|
| base::AutoLock lock(lock_);
|
| - Task* task = NULL;
|
| - if (!pending_tasks_.empty()) {
|
| - task = pending_tasks_.front();
|
| - pending_tasks_.pop();
|
| - }
|
| + if (pending_tasks_.empty())
|
| + return base::Closure();
|
| +
|
| + base::Closure task = pending_tasks_.front();
|
| + pending_tasks_.pop();
|
| return task;
|
| }
|
|
|
| void TaskMarshallerThroughMessageQueue::ExecuteQueuedTasks() {
|
| DCHECK(CalledOnValidThread());
|
| - Task* task;
|
| - while ((task = PopTask()) != NULL) {
|
| - RunTask(task);
|
| - }
|
| + base::Closure task;
|
| + while (!(task = PopTask()).is_null())
|
| + task.Run();
|
| }
|
|
|
| void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() {
|
| DCHECK(CalledOnValidThread());
|
| ::KillTimer(wnd_, reinterpret_cast<UINT_PTR>(this));
|
| - while (1) {
|
| + while (true) {
|
| lock_.Acquire();
|
|
|
| if (delayed_tasks_.empty()) {
|
| @@ -97,13 +101,13 @@ void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() {
|
| return;
|
| }
|
|
|
| - base::Time now = base::Time::Now();
|
| - DelayedTask next_task = delayed_tasks_.top();
|
| - base::Time next_run = next_task.run_at;
|
| + base::PendingTask next_task = delayed_tasks_.top();
|
| + base::TimeTicks now = base::TimeTicks::Now();
|
| + base::TimeTicks next_run = next_task.delayed_run_time;
|
| if (next_run > now) {
|
| int64 delay = (next_run - now).InMillisecondsRoundedUp();
|
| ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
|
| - static_cast<DWORD>(delay), NULL);
|
| + static_cast<DWORD>(delay), NULL);
|
| lock_.Release();
|
| return;
|
| }
|
| @@ -112,46 +116,18 @@ void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() {
|
| lock_.Release();
|
|
|
| // Run the task outside the lock.
|
| - RunTask(next_task.task);
|
| + next_task.task.Run();
|
| }
|
| }
|
|
|
| -void TaskMarshallerThroughMessageQueue::DeleteAll() {
|
| +void TaskMarshallerThroughMessageQueue::ClearTasks() {
|
| base::AutoLock lock(lock_);
|
| DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying "
|
| << pending_tasks_.size()
|
| << " pending tasks.";
|
| - while (!pending_tasks_.empty()) {
|
| - Task* task = pending_tasks_.front();
|
| + while (!pending_tasks_.empty())
|
| pending_tasks_.pop();
|
| - delete task;
|
| - }
|
|
|
| - while (!delayed_tasks_.empty()) {
|
| - delete delayed_tasks_.top().task;
|
| + while (!delayed_tasks_.empty())
|
| delayed_tasks_.pop();
|
| - }
|
| -}
|
| -
|
| -void TaskMarshallerThroughMessageQueue::RunTask(Task* task) {
|
| - ++invoke_task_;
|
| - task->Run();
|
| - --invoke_task_;
|
| - delete task;
|
| -}
|
| -
|
| -bool TaskMarshallerThroughMessageQueue::DelayedTask::operator<(
|
| - const DelayedTask& other) const {
|
| - // Since the top of a priority queue is defined as the "greatest" element, we
|
| - // need to invert the comparison here. We want the smaller time to be at the
|
| - // top of the heap.
|
| - if (run_at < other.run_at)
|
| - return false;
|
| -
|
| - if (run_at > other.run_at)
|
| - return true;
|
| -
|
| - // If the times happen to match, then we use the sequence number to decide.
|
| - // Compare the difference to support integer roll-over.
|
| - return (seq - other.seq) > 0;
|
| }
|
|
|