1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome_frame/task_marshaller.h"
8 TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue()
13 TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() {
17 void TaskMarshallerThroughMessageQueue::PostTask(
18 const tracked_objects::Location
& from_here
, const base::Closure
& task
) {
22 bool has_work
= !pending_tasks_
.empty();
23 pending_tasks_
.push(task
);
26 // Don't post message if there is already one.
30 if (!::PostMessage(wnd_
, msg_
, 0, 0)) {
31 DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
36 void TaskMarshallerThroughMessageQueue::PostDelayedTask(
37 const tracked_objects::Location
& source
,
38 const base::Closure
& task
,
39 base::TimeDelta
& delay
) {
42 base::AutoLock
lock(lock_
);
43 base::PendingTask
delayed_task(source
, task
, base::TimeTicks::Now() + delay
,
45 base::TimeTicks top_run_time
= delayed_tasks_
.top().delayed_run_time
;
46 delayed_tasks_
.push(delayed_task
);
48 // Reschedule the timer if |delayed_task| will be the next delayed task to
50 if (delayed_task
.delayed_run_time
< top_run_time
) {
51 ::SetTimer(wnd_
, reinterpret_cast<UINT_PTR
>(this),
52 static_cast<DWORD
>(delay
.InMilliseconds()), NULL
);
56 BOOL
TaskMarshallerThroughMessageQueue::ProcessWindowMessage(HWND hWnd
,
62 if (hWnd
== wnd_
&& uMsg
== msg_
) {
68 if (hWnd
== wnd_
&& uMsg
== WM_TIMER
) {
69 ExecuteDelayedTasks();
77 base::Closure
TaskMarshallerThroughMessageQueue::PopTask() {
78 base::AutoLock
lock(lock_
);
79 if (pending_tasks_
.empty())
80 return base::Closure();
82 base::Closure task
= pending_tasks_
.front();
87 void TaskMarshallerThroughMessageQueue::ExecuteQueuedTasks() {
88 DCHECK(CalledOnValidThread());
90 while (!(task
= PopTask()).is_null())
94 void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() {
95 DCHECK(CalledOnValidThread());
96 ::KillTimer(wnd_
, reinterpret_cast<UINT_PTR
>(this));
100 if (delayed_tasks_
.empty()) {
105 base::PendingTask next_task
= delayed_tasks_
.top();
106 base::TimeTicks now
= base::TimeTicks::Now();
107 base::TimeTicks next_run
= next_task
.delayed_run_time
;
108 if (next_run
> now
) {
109 int64 delay
= (next_run
- now
).InMillisecondsRoundedUp();
110 ::SetTimer(wnd_
, reinterpret_cast<UINT_PTR
>(this),
111 static_cast<DWORD
>(delay
), NULL
);
116 delayed_tasks_
.pop();
119 // Run the task outside the lock.
120 next_task
.task
.Run();
124 void TaskMarshallerThroughMessageQueue::ClearTasks() {
125 base::AutoLock
lock(lock_
);
126 DVLOG_IF(1, !pending_tasks_
.empty()) << "Destroying "
127 << pending_tasks_
.size()
128 << " pending tasks.";
129 while (!pending_tasks_
.empty())
130 pending_tasks_
.pop();
132 while (!delayed_tasks_
.empty())
133 delayed_tasks_
.pop();