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

Side by Side Diff: base/task_scheduler/task_scheduler_impl_unittest.cc

Issue 2834063002: Separate the create and start phases in TaskSchedulerImpl. (Closed)
Patch Set: self-review Created 3 years, 8 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
OLDNEW
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
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
285 // This should not hang if the task is scheduled after Start().
gab 2017/04/25 15:16:15 implicit IMO, remove comment (same below)
fdoray 2017/04/25 18:43:35 Done.
286 task_running.Wait();
287 }
288
289 // Verifies that a task posted via PostDelayedTaskWithTraits with a delay
290 // doesn't run before Start() is called.
291 TEST_P(TaskSchedulerImplTest, PostDelayedTaskWithTraitsWithDelayBeforeStart) {
292 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL,
293 WaitableEvent::InitialState::NOT_SIGNALED);
294 scheduler_.PostDelayedTaskWithTraits(
295 FROM_HERE, GetParam().traits,
296 BindOnce(&VerifyTimeAndTaskEnvironmentAndSignalEvent, GetParam().traits,
297 TimeTicks::Now() + TestTimeouts::tiny_timeout(),
298 Unretained(&task_running)),
299 TestTimeouts::tiny_timeout());
300
301 // Wait a little bit to make sure that the task isn't scheduled before
302 // Start(). Note: This test won't catch a case where the task runs just after
303 // the check and before Start(). However, we expect the test to be flaky if
304 // the tested code allows that to happen.
305 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
306 EXPECT_FALSE(task_running.IsSignaled());
307
308 StartTaskScheduler();
309
310 // This should not hang if the task is scheduled after Start().
311 task_running.Wait();
312 }
313
314 // Verifies that a task posted via a TaskRunner doesn't run before Start() is
315 // called.
316 TEST_P(TaskSchedulerImplTest, PostTaskViaTaskRunnerBeforeStart) {
317 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL,
318 WaitableEvent::InitialState::NOT_SIGNALED);
319 CreateTaskRunnerWithTraitsAndExecutionMode(&scheduler_, GetParam().traits,
320 GetParam().execution_mode)
321 ->PostTask(FROM_HERE,
322 BindOnce(&VerifyTaskEnvironmentAndSignalEvent,
323 GetParam().traits, Unretained(&task_running)));
324
325 // Wait a little bit to make sure that the task isn't scheduled before
326 // Start(). Note: This test won't catch a case where the task runs just after
327 // the check and before Start(). However, we expect the test to be flaky if
328 // the tested code allows that to happen.
329 PlatformThread::Sleep(TestTimeouts::tiny_timeout());
330 EXPECT_FALSE(task_running.IsSignaled());
331
332 StartTaskScheduler();
333
334 // This should not hang if the task is scheduled after Start().
335 task_running.Wait();
336 }
337
264 INSTANTIATE_TEST_CASE_P(OneTraitsExecutionModePair, 338 INSTANTIATE_TEST_CASE_P(OneTraitsExecutionModePair,
265 TaskSchedulerImplTest, 339 TaskSchedulerImplTest,
266 ::testing::ValuesIn(GetTraitsExecutionModePairs())); 340 ::testing::ValuesIn(GetTraitsExecutionModePairs()));
267 341
268 // Spawns threads that simultaneously post Tasks to TaskRunners with various 342 // Spawns threads that simultaneously post Tasks to TaskRunners with various
269 // TaskTraits and ExecutionModes. Verifies that each Task runs on a thread with 343 // TaskTraits and ExecutionModes. Verifies that each Task runs on a thread with
270 // the expected priority and I/O restrictions and respects the characteristics 344 // the expected priority and I/O restrictions and respects the characteristics
271 // of its ExecutionMode. 345 // of its ExecutionMode.
272 TEST_F(TaskSchedulerImplTest, MultipleTraitsExecutionModePairs) { 346 TEST_F(TaskSchedulerImplTest, MultipleTraitsExecutionModePairs) {
347 StartTaskScheduler();
273 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; 348 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks;
274 for (const auto& traits_execution_mode_pair : GetTraitsExecutionModePairs()) { 349 for (const auto& traits_execution_mode_pair : GetTraitsExecutionModePairs()) {
275 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( 350 threads_posting_tasks.push_back(WrapUnique(
276 scheduler_.get(), traits_execution_mode_pair.traits, 351 new ThreadPostingTasks(&scheduler_, traits_execution_mode_pair.traits,
277 traits_execution_mode_pair.execution_mode))); 352 traits_execution_mode_pair.execution_mode)));
278 threads_posting_tasks.back()->Start(); 353 threads_posting_tasks.back()->Start();
279 } 354 }
280 355
281 for (const auto& thread : threads_posting_tasks) { 356 for (const auto& thread : threads_posting_tasks) {
282 thread->WaitForAllTasksToRun(); 357 thread->WaitForAllTasksToRun();
283 thread->Join(); 358 thread->Join();
284 } 359 }
285 } 360 }
286 361
287 TEST_F(TaskSchedulerImplTest, GetMaxConcurrentTasksWithTraitsDeprecated) { 362 TEST_F(TaskSchedulerImplTest, GetMaxConcurrentTasksWithTraitsDeprecated) {
288 EXPECT_EQ(1, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 363 StartTaskScheduler();
364 EXPECT_EQ(1, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
289 TaskTraits().WithPriority(TaskPriority::BACKGROUND))); 365 TaskTraits().WithPriority(TaskPriority::BACKGROUND)));
290 EXPECT_EQ( 366 EXPECT_EQ(
291 3, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 367 3, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
292 TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock())); 368 TaskTraits().WithPriority(TaskPriority::BACKGROUND).MayBlock()));
293 EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 369 EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
294 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE))); 370 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)));
295 EXPECT_EQ( 371 EXPECT_EQ(
296 12, 372 12,
297 scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 373 scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
298 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock())); 374 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE).MayBlock()));
299 EXPECT_EQ(4, scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 375 EXPECT_EQ(4, scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
300 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING))); 376 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING)));
301 EXPECT_EQ( 377 EXPECT_EQ(
302 12, 378 12,
303 scheduler_->GetMaxConcurrentTasksWithTraitsDeprecated( 379 scheduler_.GetMaxConcurrentTasksWithTraitsDeprecated(
304 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock())); 380 TaskTraits().WithPriority(TaskPriority::USER_BLOCKING).MayBlock()));
305 } 381 }
306 382
307 // Verify that the RunsTasksOnCurrentThread() method of a SequencedTaskRunner 383 // Verify that the RunsTasksOnCurrentThread() method of a SequencedTaskRunner
308 // returns false when called from a task that isn't part of the sequence. 384 // returns false when called from a task that isn't part of the sequence.
309 TEST_F(TaskSchedulerImplTest, SequencedRunsTasksOnCurrentThread) { 385 TEST_F(TaskSchedulerImplTest, SequencedRunsTasksOnCurrentThread) {
386 StartTaskScheduler();
310 auto single_thread_task_runner = 387 auto single_thread_task_runner =
311 scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); 388 scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits());
312 auto sequenced_task_runner = 389 auto sequenced_task_runner =
313 scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); 390 scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits());
314 391
315 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 392 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
316 WaitableEvent::InitialState::NOT_SIGNALED); 393 WaitableEvent::InitialState::NOT_SIGNALED);
317 single_thread_task_runner->PostTask( 394 single_thread_task_runner->PostTask(
318 FROM_HERE, 395 FROM_HERE,
319 BindOnce( 396 BindOnce(
320 [](scoped_refptr<TaskRunner> sequenced_task_runner, 397 [](scoped_refptr<TaskRunner> sequenced_task_runner,
321 WaitableEvent* task_ran) { 398 WaitableEvent* task_ran) {
322 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread()); 399 EXPECT_FALSE(sequenced_task_runner->RunsTasksOnCurrentThread());
323 task_ran->Signal(); 400 task_ran->Signal();
324 }, 401 },
325 sequenced_task_runner, Unretained(&task_ran))); 402 sequenced_task_runner, Unretained(&task_ran)));
326 task_ran.Wait(); 403 task_ran.Wait();
327 } 404 }
328 405
329 // Verify that the RunsTasksOnCurrentThread() method of a SingleThreadTaskRunner 406 // Verify that the RunsTasksOnCurrentThread() method of a SingleThreadTaskRunner
330 // returns false when called from a task that isn't part of the sequence. 407 // returns false when called from a task that isn't part of the sequence.
331 TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksOnCurrentThread) { 408 TEST_F(TaskSchedulerImplTest, SingleThreadRunsTasksOnCurrentThread) {
409 StartTaskScheduler();
332 auto sequenced_task_runner = 410 auto sequenced_task_runner =
333 scheduler_->CreateSequencedTaskRunnerWithTraits(TaskTraits()); 411 scheduler_.CreateSequencedTaskRunnerWithTraits(TaskTraits());
334 auto single_thread_task_runner = 412 auto single_thread_task_runner =
335 scheduler_->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); 413 scheduler_.CreateSingleThreadTaskRunnerWithTraits(TaskTraits());
336 414
337 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 415 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
338 WaitableEvent::InitialState::NOT_SIGNALED); 416 WaitableEvent::InitialState::NOT_SIGNALED);
339 sequenced_task_runner->PostTask( 417 sequenced_task_runner->PostTask(
340 FROM_HERE, 418 FROM_HERE,
341 BindOnce( 419 BindOnce(
342 [](scoped_refptr<TaskRunner> single_thread_task_runner, 420 [](scoped_refptr<TaskRunner> single_thread_task_runner,
343 WaitableEvent* task_ran) { 421 WaitableEvent* task_ran) {
344 EXPECT_FALSE(single_thread_task_runner->RunsTasksOnCurrentThread()); 422 EXPECT_FALSE(single_thread_task_runner->RunsTasksOnCurrentThread());
345 task_ran->Signal(); 423 task_ran->Signal();
346 }, 424 },
347 single_thread_task_runner, Unretained(&task_ran))); 425 single_thread_task_runner, Unretained(&task_ran)));
348 task_ran.Wait(); 426 task_ran.Wait();
349 } 427 }
350 428
351 #if defined(OS_WIN) 429 #if defined(OS_WIN)
352 TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) { 430 TEST_F(TaskSchedulerImplTest, COMSTATaskRunnersRunWithCOMSTA) {
431 StartTaskScheduler();
353 auto com_sta_task_runner = 432 auto com_sta_task_runner =
354 scheduler_->CreateCOMSTATaskRunnerWithTraits(TaskTraits()); 433 scheduler_.CreateCOMSTATaskRunnerWithTraits(TaskTraits());
355 434
356 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, 435 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL,
357 WaitableEvent::InitialState::NOT_SIGNALED); 436 WaitableEvent::InitialState::NOT_SIGNALED);
358 com_sta_task_runner->PostTask( 437 com_sta_task_runner->PostTask(
359 FROM_HERE, 438 FROM_HERE,
360 Bind( 439 Bind(
361 [](scoped_refptr<TaskRunner> single_thread_task_runner, 440 [](scoped_refptr<TaskRunner> single_thread_task_runner,
362 WaitableEvent* task_ran) { 441 WaitableEvent* task_ran) {
363 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); 442 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
364 if (SUCCEEDED(hr)) { 443 if (SUCCEEDED(hr)) {
365 ADD_FAILURE() << "COM STA was not initialized on this thread"; 444 ADD_FAILURE() << "COM STA was not initialized on this thread";
366 CoUninitialize(); 445 CoUninitialize();
367 } 446 }
368 task_ran->Signal(); 447 task_ran->Signal();
369 }, 448 },
370 com_sta_task_runner, Unretained(&task_ran))); 449 com_sta_task_runner, Unretained(&task_ran)));
371 task_ran.Wait(); 450 task_ran.Wait();
372 } 451 }
373 #endif // defined(OS_WIN) 452 #endif // defined(OS_WIN)
374 453
375 } // namespace internal 454 } // namespace internal
376 } // namespace base 455 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698