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; |
} |