Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(773)

Side by Side Diff: chrome_frame/task_marshaller.cc

Issue 8591009: ChromeFrame: Convert TaskMarshallerThroughMessageQueue to new Callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes. Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome_frame/task_marshaller.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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 "chrome_frame/task_marshaller.h" 5 #include "chrome_frame/task_marshaller.h"
6 #include "base/task.h" 6 #include "base/task.h"
7 7
8 TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue() { 8 TaskMarshallerThroughMessageQueue::TaskMarshallerThroughMessageQueue()
9 wnd_ = NULL; 9 : wnd_(NULL),
10 msg_ = 0xFFFF; 10 msg_(0xFFFF) {
11 } 11 }
12 12
13 TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() { 13 TaskMarshallerThroughMessageQueue::~TaskMarshallerThroughMessageQueue() {
14 DeleteAll(); 14 ClearTasks();
15 } 15 }
16 16
17 void TaskMarshallerThroughMessageQueue::PostTask( 17 void TaskMarshallerThroughMessageQueue::PostTask(
18 const tracked_objects::Location& from_here, Task* task) { 18 const tracked_objects::Location& from_here, const base::Closure& task) {
19 DCHECK(wnd_ != NULL); 19 DCHECK(wnd_ != NULL);
20 lock_.Acquire(); 20 lock_.Acquire();
21 bool has_work = !pending_tasks_.empty(); 21 bool has_work = !pending_tasks_.empty();
22 pending_tasks_.push(task); 22 pending_tasks_.push(task);
23 lock_.Release(); 23 lock_.Release();
24 24
25 // Don't post message if there is already one. 25 // Don't post message if there is already one.
26 if (has_work) 26 if (has_work)
27 return; 27 return;
28 28
29 if (!::PostMessage(wnd_, msg_, 0, 0)) { 29 if (!::PostMessage(wnd_, msg_, 0, 0)) {
30 DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window."; 30 DVLOG(1) << "Dropping MSG_EXECUTE_TASK message for destroyed window.";
31 DeleteAll(); 31 ClearTasks();
32 } 32 }
33 } 33 }
34 34
35 void TaskMarshallerThroughMessageQueue::PostDelayedTask( 35 void TaskMarshallerThroughMessageQueue::PostDelayedTask(
36 const tracked_objects::Location& source, 36 const tracked_objects::Location& source,
37 Task* task, 37 const base::Closure& task,
38 base::TimeDelta& delay) { 38 base::TimeDelta& delay) {
39 DCHECK(wnd_ != NULL); 39 DCHECK(wnd_);
40
40 base::AutoLock lock(lock_); 41 base::AutoLock lock(lock_);
41 DelayedTask delayed_task(task, base::Time::Now() + delay); 42 base::PendingTask delayed_task(source, task, base::TimeTicks::Now() + delay,
43 true);
44 base::TimeTicks top_run_time = delayed_tasks_.top().delayed_run_time;
42 delayed_tasks_.push(delayed_task); 45 delayed_tasks_.push(delayed_task);
43 // If we become the 'top' task - reschedule the timer. 46
44 if (delayed_tasks_.top().task == task) { 47 // Reschedule the timer if |delayed_task| will be the next delayed task to
48 // run.
49 if (delayed_task.delayed_run_time < top_run_time) {
45 ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this), 50 ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
46 static_cast<DWORD>(delay.InMilliseconds()), NULL); 51 static_cast<DWORD>(delay.InMilliseconds()), NULL);
47 } 52 }
48 } 53 }
49 54
50 BOOL TaskMarshallerThroughMessageQueue::ProcessWindowMessage(HWND hWnd, 55 BOOL TaskMarshallerThroughMessageQueue::ProcessWindowMessage(HWND hWnd,
51 UINT uMsg, 56 UINT uMsg,
52 WPARAM wParam, 57 WPARAM wParam,
53 LPARAM lParam, 58 LPARAM lParam,
54 LRESULT& lResult, 59 LRESULT& lResult,
55 DWORD dwMsgMapID) { 60 DWORD dwMsgMapID) {
56 if (hWnd == wnd_ && uMsg == msg_) { 61 if (hWnd == wnd_ && uMsg == msg_) {
57 ExecuteQueuedTasks(); 62 ExecuteQueuedTasks();
58 lResult = 0; 63 lResult = 0;
59 return TRUE; 64 return TRUE;
60 } 65 }
61 66
62 if (hWnd == wnd_ && uMsg == WM_TIMER) { 67 if (hWnd == wnd_ && uMsg == WM_TIMER) {
63 ExecuteDelayedTasks(); 68 ExecuteDelayedTasks();
64 lResult = 0; 69 lResult = 0;
65 return TRUE; 70 return TRUE;
66 } 71 }
67 72
68 return FALSE; 73 return FALSE;
69 } 74 }
70 75
71 Task* TaskMarshallerThroughMessageQueue::PopTask() { 76 base::Closure TaskMarshallerThroughMessageQueue::PopTask() {
72 base::AutoLock lock(lock_); 77 base::AutoLock lock(lock_);
73 Task* task = NULL; 78 if (pending_tasks_.empty())
74 if (!pending_tasks_.empty()) { 79 return base::Closure();
75 task = pending_tasks_.front(); 80
76 pending_tasks_.pop(); 81 base::Closure task = pending_tasks_.front();
77 } 82 pending_tasks_.pop();
78 return task; 83 return task;
79 } 84 }
80 85
81 void TaskMarshallerThroughMessageQueue::ExecuteQueuedTasks() { 86 void TaskMarshallerThroughMessageQueue::ExecuteQueuedTasks() {
82 DCHECK(CalledOnValidThread()); 87 DCHECK(CalledOnValidThread());
83 Task* task; 88 base::Closure task;
84 while ((task = PopTask()) != NULL) { 89 while (!(task = PopTask()).is_null())
85 RunTask(task); 90 task.Run();
86 }
87 } 91 }
88 92
89 void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() { 93 void TaskMarshallerThroughMessageQueue::ExecuteDelayedTasks() {
90 DCHECK(CalledOnValidThread()); 94 DCHECK(CalledOnValidThread());
91 ::KillTimer(wnd_, reinterpret_cast<UINT_PTR>(this)); 95 ::KillTimer(wnd_, reinterpret_cast<UINT_PTR>(this));
92 while (1) { 96 while (true) {
93 lock_.Acquire(); 97 lock_.Acquire();
94 98
95 if (delayed_tasks_.empty()) { 99 if (delayed_tasks_.empty()) {
96 lock_.Release(); 100 lock_.Release();
97 return; 101 return;
98 } 102 }
99 103
100 base::Time now = base::Time::Now(); 104 base::PendingTask next_task = delayed_tasks_.top();
101 DelayedTask next_task = delayed_tasks_.top(); 105 base::TimeTicks now = base::TimeTicks::Now();
102 base::Time next_run = next_task.run_at; 106 base::TimeTicks next_run = next_task.delayed_run_time;
103 if (next_run > now) { 107 if (next_run > now) {
104 int64 delay = (next_run - now).InMillisecondsRoundedUp(); 108 int64 delay = (next_run - now).InMillisecondsRoundedUp();
105 ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this), 109 ::SetTimer(wnd_, reinterpret_cast<UINT_PTR>(this),
106 static_cast<DWORD>(delay), NULL); 110 static_cast<DWORD>(delay), NULL);
107 lock_.Release(); 111 lock_.Release();
108 return; 112 return;
109 } 113 }
110 114
111 delayed_tasks_.pop(); 115 delayed_tasks_.pop();
112 lock_.Release(); 116 lock_.Release();
113 117
114 // Run the task outside the lock. 118 // Run the task outside the lock.
115 RunTask(next_task.task); 119 next_task.task.Run();
116 } 120 }
117 } 121 }
118 122
119 void TaskMarshallerThroughMessageQueue::DeleteAll() { 123 void TaskMarshallerThroughMessageQueue::ClearTasks() {
120 base::AutoLock lock(lock_); 124 base::AutoLock lock(lock_);
121 DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying " 125 DVLOG_IF(1, !pending_tasks_.empty()) << "Destroying "
122 << pending_tasks_.size() 126 << pending_tasks_.size()
123 << " pending tasks."; 127 << " pending tasks.";
124 while (!pending_tasks_.empty()) { 128 while (!pending_tasks_.empty())
125 Task* task = pending_tasks_.front();
126 pending_tasks_.pop(); 129 pending_tasks_.pop();
127 delete task;
128 }
129 130
130 while (!delayed_tasks_.empty()) { 131 while (!delayed_tasks_.empty())
131 delete delayed_tasks_.top().task;
132 delayed_tasks_.pop(); 132 delayed_tasks_.pop();
133 }
134 } 133 }
135
136 void TaskMarshallerThroughMessageQueue::RunTask(Task* task) {
137 ++invoke_task_;
138 task->Run();
139 --invoke_task_;
140 delete task;
141 }
142
143 bool TaskMarshallerThroughMessageQueue::DelayedTask::operator<(
144 const DelayedTask& other) const {
145 // Since the top of a priority queue is defined as the "greatest" element, we
146 // need to invert the comparison here. We want the smaller time to be at the
147 // top of the heap.
148 if (run_at < other.run_at)
149 return false;
150
151 if (run_at > other.run_at)
152 return true;
153
154 // If the times happen to match, then we use the sequence number to decide.
155 // Compare the difference to support integer roll-over.
156 return (seq - other.seq) > 0;
157 }
OLDNEW
« no previous file with comments | « chrome_frame/task_marshaller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698