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

Side by Side Diff: webrtc/base/task_queue_win.cc

Issue 2139723003: Handle initialization race in TaskQueue on Windows, discovered by drmemory (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Use QS_ALLEVENTS Created 4 years, 5 months 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
« no previous file with comments | « webrtc/base/task_queue.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 /* 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
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
OLDNEW
« no previous file with comments | « webrtc/base/task_queue.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698