OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2016 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/base/task_queue.h" | 11 #include "webrtc/base/task_queue.h" |
12 | 12 |
13 #include <string.h> | 13 #include <string.h> |
14 #include <unordered_map> | |
15 | 14 |
16 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/logging.h" | 16 #include "webrtc/base/logging.h" |
18 | 17 |
19 namespace rtc { | 18 namespace rtc { |
20 namespace { | 19 namespace { |
21 #define WM_RUN_TASK WM_USER + 1 | 20 #define WM_RUN_TASK WM_USER + 1 |
22 #define WM_QUEUE_DELAYED_TASK WM_USER + 2 | 21 #define WM_QUEUE_DELAYED_TASK WM_USER + 2 |
23 | 22 |
24 DWORD g_queue_ptr_tls = 0; | 23 DWORD g_queue_ptr_tls = 0; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 }); | 124 }); |
126 } | 125 } |
127 | 126 |
128 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task, | 127 void TaskQueue::PostTaskAndReply(std::unique_ptr<QueuedTask> task, |
129 std::unique_ptr<QueuedTask> reply) { | 128 std::unique_ptr<QueuedTask> reply) { |
130 return PostTaskAndReply(std::move(task), std::move(reply), Current()); | 129 return PostTaskAndReply(std::move(task), std::move(reply), Current()); |
131 } | 130 } |
132 | 131 |
133 // static | 132 // static |
134 bool TaskQueue::ThreadMain(void* context) { | 133 bool TaskQueue::ThreadMain(void* context) { |
135 std::unordered_map<UINT_PTR, std::unique_ptr<QueuedTask>> delayed_tasks; | 134 DelayedTasks delayed_tasks; |
| 135 while (true) { |
| 136 DWORD result = ::MsgWaitForMultipleObjectsEx(0, nullptr, INFINITE, |
| 137 QS_ALLEVENTS, MWMO_ALERTABLE); |
| 138 RTC_CHECK_NE(WAIT_FAILED, result); |
| 139 if (result == WAIT_OBJECT_0) { |
| 140 if (!ProcessQueuedMessages(&delayed_tasks)) |
| 141 break; |
| 142 } else { |
| 143 RTC_DCHECK_EQ(WAIT_IO_COMPLETION, result); |
| 144 } |
| 145 } |
| 146 return false; |
| 147 } |
136 | 148 |
137 BOOL ret; | 149 // static |
138 MSG msg; | 150 bool TaskQueue::ProcessQueuedMessages(DelayedTasks* delayed_tasks) { |
139 | 151 MSG msg = {}; |
140 while ((ret = GetMessage(&msg, nullptr, 0, 0)) != 0 && ret != -1) { | 152 while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) && |
| 153 msg.message != WM_QUIT) { |
141 if (!msg.hwnd) { | 154 if (!msg.hwnd) { |
142 switch (msg.message) { | 155 switch (msg.message) { |
143 case WM_RUN_TASK: { | 156 case WM_RUN_TASK: { |
144 QueuedTask* task = reinterpret_cast<QueuedTask*>(msg.lParam); | 157 QueuedTask* task = reinterpret_cast<QueuedTask*>(msg.lParam); |
145 if (task->Run()) | 158 if (task->Run()) |
146 delete task; | 159 delete task; |
147 break; | 160 break; |
148 } | 161 } |
149 case WM_QUEUE_DELAYED_TASK: { | 162 case WM_QUEUE_DELAYED_TASK: { |
150 QueuedTask* task = reinterpret_cast<QueuedTask*>(msg.lParam); | 163 QueuedTask* task = reinterpret_cast<QueuedTask*>(msg.lParam); |
151 uint32_t milliseconds = msg.wParam & 0xFFFFFFFF; | 164 uint32_t milliseconds = msg.wParam & 0xFFFFFFFF; |
152 #if defined(_WIN64) | 165 #if defined(_WIN64) |
153 // Subtract the time it took to queue the timer. | 166 // Subtract the time it took to queue the timer. |
154 const DWORD now = GetTickCount(); | 167 const DWORD now = GetTickCount(); |
155 DWORD post_time = now - (msg.wParam >> 32); | 168 DWORD post_time = now - (msg.wParam >> 32); |
156 milliseconds = | 169 milliseconds = |
157 post_time > milliseconds ? 0 : milliseconds - post_time; | 170 post_time > milliseconds ? 0 : milliseconds - post_time; |
158 #endif | 171 #endif |
159 UINT_PTR timer_id = SetTimer(nullptr, 0, milliseconds, nullptr); | 172 UINT_PTR timer_id = SetTimer(nullptr, 0, milliseconds, nullptr); |
160 delayed_tasks.insert(std::make_pair(timer_id, task)); | 173 delayed_tasks->insert(std::make_pair(timer_id, task)); |
161 break; | 174 break; |
162 } | 175 } |
163 case WM_TIMER: { | 176 case WM_TIMER: { |
164 KillTimer(nullptr, msg.wParam); | 177 KillTimer(nullptr, msg.wParam); |
165 auto found = delayed_tasks.find(msg.wParam); | 178 auto found = delayed_tasks->find(msg.wParam); |
166 RTC_DCHECK(found != delayed_tasks.end()); | 179 RTC_DCHECK(found != delayed_tasks->end()); |
167 if (!found->second->Run()) | 180 if (!found->second->Run()) |
168 found->second.release(); | 181 found->second.release(); |
169 delayed_tasks.erase(found); | 182 delayed_tasks->erase(found); |
170 break; | 183 break; |
171 } | 184 } |
172 default: | 185 default: |
173 RTC_NOTREACHED(); | 186 RTC_NOTREACHED(); |
174 break; | 187 break; |
175 } | 188 } |
176 } else { | 189 } else { |
177 TranslateMessage(&msg); | 190 TranslateMessage(&msg); |
178 DispatchMessage(&msg); | 191 DispatchMessage(&msg); |
179 } | 192 } |
180 } | 193 } |
| 194 return msg.message != WM_QUIT; |
| 195 } |
181 | 196 |
182 return false; | |
183 } | |
184 } // namespace rtc | 197 } // namespace rtc |
OLD | NEW |