OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/task_scheduler_impl.h" | 5 #include "base/task_scheduler/task_scheduler_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 TaskTraits().WithPriority(priority).MayBlock(), execution_mode)); | 171 TaskTraits().WithPriority(priority).MayBlock(), execution_mode)); |
172 } | 172 } |
173 } | 173 } |
174 | 174 |
175 return params; | 175 return params; |
176 } | 176 } |
177 | 177 |
178 class TaskSchedulerImplTest | 178 class TaskSchedulerImplTest |
179 : public testing::TestWithParam<TraitsExecutionModePair> { | 179 : public testing::TestWithParam<TraitsExecutionModePair> { |
180 protected: | 180 protected: |
181 TaskSchedulerImplTest() = default; | 181 TaskSchedulerImplTest() : scheduler_("Test") {} |
182 | 182 |
183 void SetUp() override { | 183 void StartTaskScheduler() { |
184 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; | 184 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; |
185 | 185 |
186 constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); | 186 constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30); |
187 constexpr int kMaxNumBackgroundThreads = 1; | 187 constexpr int kMaxNumBackgroundThreads = 1; |
188 constexpr int kMaxNumBackgroundBlockingThreads = 3; | 188 constexpr int kMaxNumBackgroundBlockingThreads = 3; |
189 constexpr int kMaxNumForegroundThreads = 4; | 189 constexpr int kMaxNumForegroundThreads = 4; |
190 constexpr int kMaxNumForegroundBlockingThreads = 12; | 190 constexpr int kMaxNumForegroundBlockingThreads = 12; |
191 | 191 |
192 scheduler_ = TaskSchedulerImpl::Create( | 192 scheduler_.Start( |
193 "Test", {{StandbyThreadPolicy::LAZY, kMaxNumBackgroundThreads, | 193 {{StandbyThreadPolicy::LAZY, kMaxNumBackgroundThreads, |
194 kSuggestedReclaimTime}, | 194 kSuggestedReclaimTime}, |
195 {StandbyThreadPolicy::LAZY, kMaxNumBackgroundBlockingThreads, | 195 {StandbyThreadPolicy::LAZY, kMaxNumBackgroundBlockingThreads, |
196 kSuggestedReclaimTime}, | 196 kSuggestedReclaimTime}, |
197 {StandbyThreadPolicy::LAZY, kMaxNumForegroundThreads, | 197 {StandbyThreadPolicy::LAZY, kMaxNumForegroundThreads, |
198 kSuggestedReclaimTime}, | 198 kSuggestedReclaimTime}, |
199 {StandbyThreadPolicy::LAZY, kMaxNumForegroundBlockingThreads, | 199 {StandbyThreadPolicy::LAZY, kMaxNumForegroundBlockingThreads, |
200 kSuggestedReclaimTime}}); | 200 kSuggestedReclaimTime}}); |
201 | |
202 ASSERT_TRUE(scheduler_); | |
203 } | 201 } |
204 | 202 |
205 void TearDown() override { scheduler_->JoinForTesting(); } | 203 void TearDown() override { scheduler_.JoinForTesting(); } |
206 | 204 |
207 std::unique_ptr<TaskSchedulerImpl> scheduler_; | 205 TaskSchedulerImpl scheduler_; |
208 | 206 |
209 private: | 207 private: |
210 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImplTest); | 208 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerImplTest); |
211 }; | 209 }; |
212 | 210 |
213 } // namespace | 211 } // namespace |
214 | 212 |
215 // Verifies that a Task posted via PostDelayedTaskWithTraits with parameterized | 213 // Verifies that a Task posted via PostDelayedTaskWithTraits with parameterized |
216 // TaskTraits and no delay runs on a thread with the expected priority and I/O | 214 // TaskTraits and no delay runs on a thread with the expected priority and I/O |
217 // restrictions. The ExecutionMode parameter is ignored by this test. | 215 // restrictions. The ExecutionMode parameter is ignored by this test. |
218 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsNoDelay) { | 216 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsNoDelay) { |
| 217 StartTaskScheduler(); |
219 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 218 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
220 WaitableEvent::InitialState::NOT_SIGNALED); | 219 WaitableEvent::InitialState::NOT_SIGNALED); |
221 scheduler_->PostDelayedTaskWithTraits( | 220 scheduler_.PostDelayedTaskWithTraits( |
222 FROM_HERE, GetParam().traits, | 221 FROM_HERE, GetParam().traits, |
223 BindOnce(&VerifyTaskEnvironmentAndSignalEvent, GetParam().traits, | 222 BindOnce(&VerifyTaskEnvironmentAndSignalEvent, GetParam().traits, |
224 Unretained(&task_ran)), | 223 Unretained(&task_ran)), |
225 TimeDelta()); | 224 TimeDelta()); |
226 task_ran.Wait(); | 225 task_ran.Wait(); |
227 } | 226 } |
228 | 227 |
229 // Verifies that a Task posted via PostDelayedTaskWithTraits with parameterized | 228 // Verifies that a Task posted via PostDelayedTaskWithTraits with parameterized |
230 // TaskTraits and a non-zero delay runs on a thread with the expected priority | 229 // TaskTraits and a non-zero delay runs on a thread with the expected priority |
231 // and I/O restrictions after the delay expires. The ExecutionMode parameter is | 230 // and I/O restrictions after the delay expires. The ExecutionMode parameter is |
232 // ignored by this test. | 231 // ignored by this test. |
233 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelay) { | 232 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelay) { |
| 233 StartTaskScheduler(); |
234 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 234 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
235 WaitableEvent::InitialState::NOT_SIGNALED); | 235 WaitableEvent::InitialState::NOT_SIGNALED); |
236 scheduler_->PostDelayedTaskWithTraits( | 236 scheduler_.PostDelayedTaskWithTraits( |
237 FROM_HERE, GetParam().traits, | 237 FROM_HERE, GetParam().traits, |
238 BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits, | 238 BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits, |
239 TimeTicks::Now() + TestTimeouts::tiny_timeout(), | 239 TimeTicks::Now() + TestTimeouts::tiny_timeout(), |
240 Unretained(&task_ran)), | 240 Unretained(&task_ran)), |
241 TestTimeouts::tiny_timeout()); | 241 TestTimeouts::tiny_timeout()); |
242 task_ran.Wait(); | 242 task_ran.Wait(); |
243 } | 243 } |
244 | 244 |
245 // Verifies that Tasks posted via a TaskRunner with parameterized TaskTraits and | 245 // Verifies that Tasks posted via a TaskRunner with parameterized TaskTraits and |
246 // ExecutionMode run on a thread with the expected priority and I/O restrictions | 246 // ExecutionMode run on a thread with the expected priority and I/O restrictions |
247 // and respect the characteristics of their ExecutionMode. | 247 // and respect the characteristics of their ExecutionMode. |
248 TEST_P(TaskSchedulerImplTest, PostTasksViaTaskRunner) { | 248 TEST_P(TaskSchedulerImplTest, PostTasksViaTaskRunner) { |
| 249 StartTaskScheduler(); |
249 test::TestTaskFactory factory( | 250 test::TestTaskFactory factory( |
250 CreateTaskRunnerWithTraitsAndExecutionMode( | 251 CreateTaskRunnerWithTraitsAndExecutionMode(&scheduler_, GetParam().traits, |
251 scheduler_.get(), GetParam().traits, GetParam().execution_mode), | 252 GetParam().execution_mode), |
252 GetParam().execution_mode); | 253 GetParam().execution_mode); |
253 EXPECT_FALSE(factory.task_runner()->RunsTasksOnCurrentThread()); | 254 EXPECT_FALSE(factory.task_runner()->RunsTasksOnCurrentThread()); |
254 | 255 |
255 const size_t kNumTasksPerTest = 150; | 256 const size_t kNumTasksPerTest = 150; |
256 for (size_t i = 0; i < kNumTasksPerTest; ++i) { | 257 for (size_t i = 0; i < kNumTasksPerTest; ++i) { |
257 factory.PostTask(test::TestTaskFactory::PostNestedTask::NO, | 258 factory.PostTask(test::TestTaskFactory::PostNestedTask::NO, |
258 Bind(&VerifyTaskEnvironment, GetParam().traits)); | 259 Bind(&VerifyTaskEnvironment, GetParam().traits)); |
259 } | 260 } |
260 | 261 |
261 factory.WaitForAllTasksToRun(); | 262 factory.WaitForAllTasksToRun(); |
262 } | 263 } |
263 | 264 |
| 265 // Verifies that a task posted via PostDelayedTaskWithTraits without a delay |
| 266 // doesn't run before Start() is called. |
| 267 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsNoDelayBeforeStart) { |
| 268 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 269 WaitableEvent::InitialState::NOT_SIGNALED); |
| 270 scheduler_.PostDelayedTaskWithTraits( |
| 271 FROM_HERE, GetParam().traits, |
| 272 BindOnce(&VerifyTaskEnvironmentAndSignalEvent, GetParam().traits, |
| 273 Unretained(&task_running)), |
| 274 TimeDelta()); |
| 275 |
| 276 // Wait a little bit to make sure that the task isn't scheduled before |
| 277 // Start(). Note: This test won't catch a case where the task runs just after |
| 278 // the check and before Start(). However, we expect the test to be flaky if |
| 279 // the tested code allows that to happen. |
| 280 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 281 EXPECT_FALSE(task_running.IsSignaled()); |
| 282 |
| 283 StartTaskScheduler(); |
| 284 task_running.Wait(); |
| 285 } |
| 286 |
| 287 // Verifies that a task posted via PostDelayedTaskWithTraits with a delay |
| 288 // doesn't run before Start() is called. |
| 289 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelayBeforeStart) { |
| 290 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 291 WaitableEvent::InitialState::NOT_SIGNALED); |
| 292 scheduler_.PostDelayedTaskWithTraits( |
| 293 FROM_HERE, GetParam().traits, |
| 294 BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits, |
| 295 TimeTicks::Now() + TestTimeouts::tiny_timeout(), |
| 296 Unretained(&task_running)), |
| 297 TestTimeouts::tiny_timeout()); |
| 298 |
| 299 // Wait a little bit to make sure that the task isn't scheduled before |
| 300 // Start(). Note: This test won't catch a case where the task runs just after |
| 301 // the check and before Start(). However, we expect the test to be flaky if |
| 302 // the tested code allows that to happen. |
| 303 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 304 EXPECT_FALSE(task_running.IsSignaled()); |
| 305 |
| 306 StartTaskScheduler(); |
| 307 task_running.Wait(); |
| 308 } |
| 309 |
| 310 // Verifies that a task posted via a TaskRunner doesn't run before Start() is |
| 311 // called. |
| 312 TEST_P(TaskSchedulerImplTest, PostTaskViaTaskRunnerBeforeStart) { |
| 313 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
| 314 WaitableEvent::InitialState::NOT_SIGNALED); |
| 315 CreateTaskRunnerWithTraitsAndExecutionMode(&scheduler_, GetParam().traits, |
| 316 GetParam().execution_mode) |
| 317 ->PostTask(FROM_HERE, |
| 318 BindOnce(&VerifyTaskEnvironmentAndSignalEvent, |
| 319 GetParam().traits, Unretained(&task_running))); |
| 320 |
| 321 // Wait a little bit to make sure that the task isn't scheduled before |
| 322 // Start(). Note: This test won't catch a case where the task runs just after |
| 323 // the check and before Start(). However, we expect the test to be flaky if |
| 324 // the tested code allows that to happen. |
| 325 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
| 326 EXPECT_FALSE(task_running.IsSignaled()); |
| 327 |
| 328 StartTaskScheduler(); |
| 329 |
| 330 // This should not hang if the task is scheduled after Start(). |
| 331 task_running.Wait(); |
| 332 } |
| 333 |
264 INSTANTIATE_TEST_CASE_P(OneTraitsExecutionModePair, | 334 INSTANTIATE_TEST_CASE_P(OneTraitsExecutionModePair, |
265 TaskSchedulerImplTest, | 335 TaskSchedulerImplTest, |
266 ::testing::ValuesIn(GetTraitsExecutionModePairs())); | 336 ::testing::ValuesIn(GetTraitsExecutionModePairs())); |
267 | 337 |
268 // Spawns threads that simultaneously post Tasks to TaskRunners with various | 338 // Spawns threads that simultaneously post Tasks to TaskRunners with various |
269 // TaskTraits and ExecutionModes. Verifies that each Task runs on a thread with | 339 // TaskTraits and ExecutionModes. Verifies that each Task runs on a thread with |
270 // the expected priority and I/O restrictions and respects the characteristics | 340 // the expected priority and I/O restrictions and respects the characteristics |
271 // of its ExecutionMode. | 341 // of its ExecutionMode. |
272 TEST_F(TaskSchedulerImplTest, MultipleTraitsExecutionModePairs) { | 342 TEST_F(TaskSchedulerImplTest, MultipleTraitsExecutionModePairs) { |
| 343 StartTaskScheduler(); |
273 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 344 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
274 for (const auto& traits_execution_mode_pair : GetTraitsExecutionModePairs()) { | 345 for (const auto& traits_execution_mode_pair : GetTraitsExecutionModePairs()) { |
275 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 346 threads_posting_tasks.push_back(WrapUnique( |
276 scheduler_.get(), traits_execution_mode_pair.traits, | 347 new ThreadPostingTasks(&scheduler_, traits_execution_mode_pair.traits, |
277 traits_execution_mode_pair.execution_mode))); | 348 traits_execution_mode_pair.execution_mode))); |
278 threads_posting_tasks.back()->Start(); | 349 threads_posting_tasks.back()->Start(); |
279 } | 350 } |
280 | 351 |
281 for (const auto& thread : threads_posting_tasks) { | 352 for (const auto& thread : threads_posting_tasks) { |
282 thread->WaitForAllTasksToRun(); | 353 thread->WaitForAllTasksToRun(); |
283 thread->Join(); | 354 thread->Join(); |
284 } | 355 } |
285 } | 356 } |
286 | 357 |
287 TEST_F(TaskSchedulerImplTest, GetMaxConcurrentTasksWithTraitsDeprecated) { | 358 TEST_F(TaskSchedulerImplTest, GetMaxConcurrentTasksWithTraitsDeprecated) { |
288 EXPECT_EQ(1, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 359 StartTaskScheduler(); |
| 360 EXPECT_EQ(1, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
289 TaskTraits().WithPriority(TaskPriority::BACKGROUND))); | 361 TaskTraits().WithPriority(TaskPriority::BACKGROUND))); |
290 EXPECT_EQ( | 362 EXPECT_EQ( |
291 3, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 363 3, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
292 TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock())); | 364 TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock())); |
293 EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 365 EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
294 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE))); | 366 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE))); |
295 EXPECT_EQ( | 367 EXPECT_EQ( |
296 12, | 368 12, |
297 scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 369 scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
298 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock())); | 370 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock())); |
299 EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 371 EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
300 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))); | 372 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))); |
301 EXPECT_EQ( | 373 EXPECT_EQ( |
302 12, | 374 12, |
303 scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( | 375 scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated( |
304 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock())); | 376 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock())); |
305 } | 377 } |
306 | 378 |
307 // Verify that the RunsTasksOnCurrentThread() method of a SequencedTaskRunner | 379 // Verify that the RunsTasksOnCurrentThread() method of a SequencedTaskRunner |
308 // returns false when called from a task that isn't part of the sequence. | 380 // returns false when called from a task that isn't part of the sequence. |
309 TEST_F(TaskSchedulerImplTest, SequencedRunsTasksOnCurrentThread) { | 381 TEST_F(TaskSchedulerImplTest, SequencedRunsTasksOnCurrentThread) { |
| 382 StartTaskScheduler(); |
310 auto single_thread_task_runner = | 383 auto single_thread_task_runner = |
311 scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 384 scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
312 auto sequenced_task_runner = | 385 auto sequenced_task_runner = |
313 scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); | 386 scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
314 | 387 |
315 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 388 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
316 WaitableEvent::InitialState::NOT_SIGNALED); | 389 WaitableEvent::InitialState::NOT_SIGNALED); |
317 single_thread_task_runner->PostTask( | 390 single_thread_task_runner->PostTask( |
318 FROM_HERE, | 391 FROM_HERE, |
319 BindOnce( | 392 BindOnce( |
320 [](scoped_refptr<TaskRunner> sequenced_task_runner, | 393 [](scoped_refptr<TaskRunner> sequenced_task_runner, |
321 WaitableEvent* task_ran) { | 394 WaitableEvent* task_ran) { |
322 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); | 395 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); |
323 task_ran->Signal(); | 396 task_ran->Signal(); |
324 }, | 397 }, |
325 sequenced_task_runner, Unretained(&task_ran))); | 398 sequenced_task_runner, Unretained(&task_ran))); |
326 task_ran.Wait(); | 399 task_ran.Wait(); |
327 } | 400 } |
328 | 401 |
329 // Verify that the RunsTasksOnCurrentThread() method of a SingleThreadTaskRunner | 402 // Verify that the RunsTasksOnCurrentThread() method of a SingleThreadTaskRunner |
330 // returns false when called from a task that isn't part of the sequence. | 403 // returns false when called from a task that isn't part of the sequence. |
331 TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksOnCurrentThread) { | 404 TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksOnCurrentThread) { |
| 405 StartTaskScheduler(); |
332 auto sequenced_task_runner = | 406 auto sequenced_task_runner = |
333 scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); | 407 scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits()); |
334 auto single_thread_task_runner = | 408 auto single_thread_task_runner = |
335 scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 409 scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); |
336 | 410 |
337 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 411 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
338 WaitableEvent::InitialState::NOT_SIGNALED); | 412 WaitableEvent::InitialState::NOT_SIGNALED); |
339 sequenced_task_runner->PostTask( | 413 sequenced_task_runner->PostTask( |
340 FROM_HERE, | 414 FROM_HERE, |
341 BindOnce( | 415 BindOnce( |
342 [](scoped_refptr<TaskRunner> single_thread_task_runner, | 416 [](scoped_refptr<TaskRunner> single_thread_task_runner, |
343 WaitableEvent* task_ran) { | 417 WaitableEvent* task_ran) { |
344 EXPECT_FALSE(single_thread_task_runner->RunsTasksOnCurrentThread()); | 418 EXPECT_FALSE(single_thread_task_runner->RunsTasksOnCurrentThread()); |
345 task_ran->Signal(); | 419 task_ran->Signal(); |
346 }, | 420 }, |
347 single_thread_task_runner, Unretained(&task_ran))); | 421 single_thread_task_runner, Unretained(&task_ran))); |
348 task_ran.Wait(); | 422 task_ran.Wait(); |
349 } | 423 } |
350 | 424 |
351 #if defined(OS_WIN) | 425 #if defined(OS_WIN) |
352 TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { | 426 TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { |
| 427 StartTaskScheduler(); |
353 auto com_sta_task_runner = | 428 auto com_sta_task_runner = |
354 scheduler_->CreateCOMSTATaskRunnerWithTraits(TaskTraits()); | 429 scheduler_.CreateCOMSTATaskRunnerWithTraits(TaskTraits()); |
355 | 430 |
356 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 431 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
357 WaitableEvent::InitialState::NOT_SIGNALED); | 432 WaitableEvent::InitialState::NOT_SIGNALED); |
358 com_sta_task_runner->PostTask( | 433 com_sta_task_runner->PostTask( |
359 FROM_HERE, | 434 FROM_HERE, |
360 Bind( | 435 Bind( |
361 [](scoped_refptr<TaskRunner> single_thread_task_runner, | 436 [](scoped_refptr<TaskRunner> single_thread_task_runner, |
362 WaitableEvent* task_ran) { | 437 WaitableEvent* task_ran) { |
363 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 438 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
364 if (SUCCEEDED(hr)) { | 439 if (SUCCEEDED(hr)) { |
365 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 440 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
366 CoUninitialize(); | 441 CoUninitialize(); |
367 } | 442 } |
368 task_ran->Signal(); | 443 task_ran->Signal(); |
369 }, | 444 }, |
370 com_sta_task_runner, Unretained(&task_ran))); | 445 com_sta_task_runner, Unretained(&task_ran))); |
371 task_ran.Wait(); | 446 task_ran.Wait(); |
372 } | 447 } |
373 #endif // defined(OS_WIN) | 448 #endif // defined(OS_WIN) |
374 | 449 |
375 } // namespace internal | 450 } // namespace internal |
376 } // namespace base | 451 } // namespace base |
OLD | NEW |