OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" | 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/synchronization/atomic_flag.h" | |
9 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
10 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
11 #include "base/task_scheduler/delayed_task_manager.h" | 12 #include "base/task_scheduler/delayed_task_manager.h" |
12 #include "base/task_scheduler/post_task.h" | 13 #include "base/task_scheduler/post_task.h" |
13 #include "base/task_scheduler/scheduler_worker_pool_params.h" | 14 #include "base/task_scheduler/scheduler_worker_pool_params.h" |
14 #include "base/task_scheduler/task_tracker.h" | 15 #include "base/task_scheduler/task_tracker.h" |
15 #include "base/task_scheduler/task_traits.h" | 16 #include "base/task_scheduler/task_traits.h" |
16 #include "base/test/test_timeouts.h" | 17 #include "base/test/test_timeouts.h" |
18 #include "base/threading/platform_thread.h" | |
17 #include "base/threading/simple_thread.h" | 19 #include "base/threading/simple_thread.h" |
18 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
20 | 22 |
21 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
22 #include <windows.h> | 24 #include <windows.h> |
23 #include <objbase.h> | 25 #include <objbase.h> |
24 | 26 |
25 #include "base/win/current_module.h" | 27 #include "base/win/current_module.h" |
26 #endif // defined(OS_WIN) | 28 #endif // defined(OS_WIN) |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
105 *thread_priority = PlatformThread::GetCurrentThreadPriority(); | 107 *thread_priority = PlatformThread::GetCurrentThreadPriority(); |
106 } | 108 } |
107 | 109 |
108 void ShouldNotRun() { | 110 void ShouldNotRun() { |
109 ADD_FAILURE() << "Ran a task that shouldn't run."; | 111 ADD_FAILURE() << "Ran a task that shouldn't run."; |
110 } | 112 } |
111 | 113 |
112 } // namespace | 114 } // namespace |
113 | 115 |
114 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 116 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
117 single_thread_task_runner_manager_->Start(); | |
robliao
2017/04/10 20:52:48
Given the majority of the tests start the task run
fdoray
2017/04/11 15:27:24
Done.
| |
115 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 118 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
116 single_thread_task_runner_manager_ | 119 single_thread_task_runner_manager_ |
117 ->CreateSingleThreadTaskRunnerWithTraits( | 120 ->CreateSingleThreadTaskRunnerWithTraits( |
118 TaskTraits().WithShutdownBehavior( | 121 TaskTraits().WithShutdownBehavior( |
119 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 122 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
120 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 123 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
121 single_thread_task_runner_manager_ | 124 single_thread_task_runner_manager_ |
122 ->CreateSingleThreadTaskRunnerWithTraits( | 125 ->CreateSingleThreadTaskRunnerWithTraits( |
123 TaskTraits().WithShutdownBehavior( | 126 TaskTraits().WithShutdownBehavior( |
124 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 127 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
125 | 128 |
126 PlatformThreadRef thread_ref_1; | 129 PlatformThreadRef thread_ref_1; |
127 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1)); | 130 task_runner_1->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_1)); |
128 PlatformThreadRef thread_ref_2; | 131 PlatformThreadRef thread_ref_2; |
129 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2)); | 132 task_runner_2->PostTask(FROM_HERE, Bind(&CaptureThreadRef, &thread_ref_2)); |
130 | 133 |
131 task_tracker_.Shutdown(); | 134 task_tracker_.Shutdown(); |
132 | 135 |
133 ASSERT_FALSE(thread_ref_1.is_null()); | 136 ASSERT_FALSE(thread_ref_1.is_null()); |
134 ASSERT_FALSE(thread_ref_2.is_null()); | 137 ASSERT_FALSE(thread_ref_2.is_null()); |
135 EXPECT_NE(thread_ref_1, thread_ref_2); | 138 EXPECT_NE(thread_ref_1, thread_ref_2); |
136 } | 139 } |
137 | 140 |
138 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 141 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
142 single_thread_task_runner_manager_->Start(); | |
139 // Why are events used here instead of the task tracker? | 143 // Why are events used here instead of the task tracker? |
140 // Shutting down can cause priorities to get raised. This means we have to use | 144 // Shutting down can cause priorities to get raised. This means we have to use |
141 // events to determine when a task is run. | 145 // events to determine when a task is run. |
142 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 146 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
143 single_thread_task_runner_manager_ | 147 single_thread_task_runner_manager_ |
144 ->CreateSingleThreadTaskRunnerWithTraits( | 148 ->CreateSingleThreadTaskRunnerWithTraits( |
145 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 149 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); |
146 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = | 150 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = |
147 single_thread_task_runner_manager_ | 151 single_thread_task_runner_manager_ |
148 ->CreateSingleThreadTaskRunnerWithTraits( | 152 ->CreateSingleThreadTaskRunnerWithTraits( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 waitable_event_user_blocking.Wait(); | 193 waitable_event_user_blocking.Wait(); |
190 | 194 |
191 if (Lock::HandlesMultipleThreadPriorities()) | 195 if (Lock::HandlesMultipleThreadPriorities()) |
192 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 196 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
193 else | 197 else |
194 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 198 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
195 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); | 199 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); |
196 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); | 200 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); |
197 } | 201 } |
198 | 202 |
203 // Verify that a task posted before Start() doesn't run until Start() is called. | |
204 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskBeforeStart) { | |
205 AtomicFlag manager_started; | |
206 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | |
207 WaitableEvent::InitialState::NOT_SIGNALED); | |
208 single_thread_task_runner_manager_ | |
209 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()) | |
210 ->PostTask( | |
211 FROM_HERE, | |
212 Bind( | |
213 [](WaitableEvent* task_running, AtomicFlag* manager_started) { | |
214 task_running->Signal(); | |
215 | |
216 // The task should not run before Start(). | |
217 EXPECT_TRUE(manager_started->IsSet()); | |
218 }, | |
219 Unretained(&task_running), Unretained(&manager_started))); | |
220 | |
221 // Wait a little bit to make sure that the task isn't scheduled before start. | |
222 // Note: This test won't catch a case where the task is scheduled between | |
223 // setting |manager_started| and calling Start(). However, we expect the test | |
224 // to be flaky if the tested code allows that to happen. | |
225 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | |
226 manager_started.Set(); | |
227 single_thread_task_runner_manager_->Start(); | |
228 | |
229 // This should not hang if the task is scheduled after Start(). | |
230 task_running.Wait(); | |
231 } | |
232 | |
199 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 233 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { |
234 single_thread_task_runner_manager_->Start(); | |
200 auto task_runner = single_thread_task_runner_manager_ | 235 auto task_runner = single_thread_task_runner_manager_ |
201 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 236 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
202 task_tracker_.Shutdown(); | 237 task_tracker_.Shutdown(); |
203 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun))); | 238 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRun))); |
204 } | 239 } |
205 | 240 |
206 // Verify that a Task runs shortly after its delay expires. | 241 // Verify that a Task runs shortly after its delay expires. |
207 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 242 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { |
243 single_thread_task_runner_manager_->Start(); | |
208 TimeTicks start_time = TimeTicks::Now(); | 244 TimeTicks start_time = TimeTicks::Now(); |
209 | 245 |
210 // Post a task with a short delay. | 246 // Post a task with a short delay. |
211 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 247 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
212 WaitableEvent::InitialState::NOT_SIGNALED); | 248 WaitableEvent::InitialState::NOT_SIGNALED); |
213 auto task_runner = single_thread_task_runner_manager_ | 249 auto task_runner = single_thread_task_runner_manager_ |
214 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 250 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
215 EXPECT_TRUE(task_runner->PostDelayedTask( | 251 EXPECT_TRUE(task_runner->PostDelayedTask( |
216 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)), | 252 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_ran)), |
217 TestTimeouts::tiny_timeout())); | 253 TestTimeouts::tiny_timeout())); |
218 | 254 |
219 // Wait until the task runs. | 255 // Wait until the task runs. |
220 task_ran.Wait(); | 256 task_ran.Wait(); |
221 | 257 |
222 // Expect the task to run after its delay expires, but not more than 250 ms | 258 // Expect the task to run after its delay expires, but not more than 250 ms |
223 // after that. | 259 // after that. |
224 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 260 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
225 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 261 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
226 EXPECT_LT(actual_delay, | 262 EXPECT_LT(actual_delay, |
227 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 263 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
228 } | 264 } |
229 | 265 |
230 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 266 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, |
231 RunsTasksOnCurrentThread) { | 267 RunsTasksOnCurrentThread) { |
268 single_thread_task_runner_manager_->Start(); | |
232 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 269 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
233 single_thread_task_runner_manager_ | 270 single_thread_task_runner_manager_ |
234 ->CreateSingleThreadTaskRunnerWithTraits( | 271 ->CreateSingleThreadTaskRunnerWithTraits( |
235 TaskTraits().WithShutdownBehavior( | 272 TaskTraits().WithShutdownBehavior( |
236 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 273 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
237 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 274 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
238 single_thread_task_runner_manager_ | 275 single_thread_task_runner_manager_ |
239 ->CreateSingleThreadTaskRunnerWithTraits( | 276 ->CreateSingleThreadTaskRunnerWithTraits( |
240 TaskTraits().WithShutdownBehavior( | 277 TaskTraits().WithShutdownBehavior( |
241 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 278 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
303 single_thread_task_runner_manager_.reset(); | 340 single_thread_task_runner_manager_.reset(); |
304 } | 341 } |
305 | 342 |
306 private: | 343 private: |
307 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest); | 344 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest); |
308 }; | 345 }; |
309 | 346 |
310 } // namespace | 347 } // namespace |
311 | 348 |
312 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { | 349 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { |
350 single_thread_task_runner_manager_->Start(); | |
313 // Exercises the codepath where the workers are unavailable for unregistration | 351 // Exercises the codepath where the workers are unavailable for unregistration |
314 // because of a Join call. | 352 // because of a Join call. |
315 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 353 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
316 WaitableEvent::InitialState::NOT_SIGNALED); | 354 WaitableEvent::InitialState::NOT_SIGNALED); |
317 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 355 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
318 WaitableEvent::InitialState::NOT_SIGNALED); | 356 WaitableEvent::InitialState::NOT_SIGNALED); |
319 | 357 |
320 { | 358 { |
321 auto task_runner = single_thread_task_runner_manager_ | 359 auto task_runner = single_thread_task_runner_manager_ |
322 ->CreateSingleThreadTaskRunnerWithTraits( | 360 ->CreateSingleThreadTaskRunnerWithTraits( |
323 TaskTraits().WithBaseSyncPrimitives()); | 361 TaskTraits().WithBaseSyncPrimitives()); |
324 EXPECT_TRUE(task_runner->PostTask( | 362 EXPECT_TRUE(task_runner->PostTask( |
325 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); | 363 FROM_HERE, Bind(&WaitableEvent::Signal, Unretained(&task_running)))); |
326 EXPECT_TRUE(task_runner->PostTask( | 364 EXPECT_TRUE(task_runner->PostTask( |
327 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 365 FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
328 } | 366 } |
329 | 367 |
330 task_running.Wait(); | 368 task_running.Wait(); |
331 CallJoinFromDifferentThread join_from_different_thread( | 369 CallJoinFromDifferentThread join_from_different_thread( |
332 single_thread_task_runner_manager_.get()); | 370 single_thread_task_runner_manager_.get()); |
333 join_from_different_thread.Start(); | 371 join_from_different_thread.Start(); |
334 join_from_different_thread.WaitForRunToStart(); | 372 join_from_different_thread.WaitForRunToStart(); |
335 task_blocking.Signal(); | 373 task_blocking.Signal(); |
336 join_from_different_thread.Join(); | 374 join_from_different_thread.Join(); |
337 } | 375 } |
338 | 376 |
339 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 377 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
340 ConcurrentJoinExtraSkippedTask) { | 378 ConcurrentJoinExtraSkippedTask) { |
379 single_thread_task_runner_manager_->Start(); | |
341 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 380 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
342 // SingleThreadTaskRunners to unregister themselves. | 381 // SingleThreadTaskRunners to unregister themselves. |
343 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 382 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
344 WaitableEvent::InitialState::NOT_SIGNALED); | 383 WaitableEvent::InitialState::NOT_SIGNALED); |
345 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 384 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
346 WaitableEvent::InitialState::NOT_SIGNALED); | 385 WaitableEvent::InitialState::NOT_SIGNALED); |
347 | 386 |
348 { | 387 { |
349 auto task_runner = single_thread_task_runner_manager_ | 388 auto task_runner = single_thread_task_runner_manager_ |
350 ->CreateSingleThreadTaskRunnerWithTraits( | 389 ->CreateSingleThreadTaskRunnerWithTraits( |
(...skipping 10 matching lines...) Expand all Loading... | |
361 single_thread_task_runner_manager_.get()); | 400 single_thread_task_runner_manager_.get()); |
362 join_from_different_thread.Start(); | 401 join_from_different_thread.Start(); |
363 join_from_different_thread.WaitForRunToStart(); | 402 join_from_different_thread.WaitForRunToStart(); |
364 task_blocking.Signal(); | 403 task_blocking.Signal(); |
365 join_from_different_thread.Join(); | 404 join_from_different_thread.Join(); |
366 } | 405 } |
367 | 406 |
368 #if defined(OS_WIN) | 407 #if defined(OS_WIN) |
369 | 408 |
370 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 409 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { |
410 single_thread_task_runner_manager_->Start(); | |
371 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 411 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
372 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 412 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
373 TaskTraits().WithShutdownBehavior( | 413 TaskTraits().WithShutdownBehavior( |
374 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 414 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
375 | 415 |
376 com_task_runner->PostTask( | 416 com_task_runner->PostTask( |
377 FROM_HERE, Bind([]() { | 417 FROM_HERE, Bind([]() { |
378 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 418 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
379 if (SUCCEEDED(hr)) { | 419 if (SUCCEEDED(hr)) { |
380 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 420 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 } | 464 } |
425 | 465 |
426 bool register_class_succeeded_ = false; | 466 bool register_class_succeeded_ = false; |
427 | 467 |
428 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 468 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
429 }; | 469 }; |
430 | 470 |
431 } // namespace | 471 } // namespace |
432 | 472 |
433 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 473 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
474 single_thread_task_runner_manager_->Start(); | |
434 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 475 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
435 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 476 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
436 TaskTraits().WithShutdownBehavior( | 477 TaskTraits().WithShutdownBehavior( |
437 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 478 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
438 HWND hwnd = nullptr; | 479 HWND hwnd = nullptr; |
439 // HWNDs process messages on the thread that created them, so we have to | 480 // HWNDs process messages on the thread that created them, so we have to |
440 // create them within the context of the task runner to properly simulate a | 481 // create them within the context of the task runner to properly simulate a |
441 // COM callback. | 482 // COM callback. |
442 com_task_runner->PostTask( | 483 com_task_runner->PostTask( |
443 FROM_HERE, | 484 FROM_HERE, |
(...skipping 11 matching lines...) Expand all Loading... | |
455 com_task_runner->PostTask( | 496 com_task_runner->PostTask( |
456 FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); | 497 FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); |
457 | 498 |
458 task_tracker_.Shutdown(); | 499 task_tracker_.Shutdown(); |
459 } | 500 } |
460 | 501 |
461 #endif // defined(OS_WIN) | 502 #endif // defined(OS_WIN) |
462 | 503 |
463 } // namespace internal | 504 } // namespace internal |
464 } // namespace base | 505 } // namespace base |
OLD | NEW |