| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 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 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 } | 130 } |
| 131 | 131 |
| 132 virtual void Run() { | 132 virtual void Run() { |
| 133 // Do nothing. | 133 // Do nothing. |
| 134 } | 134 } |
| 135 | 135 |
| 136 private: | 136 private: |
| 137 Event* event_; | 137 Event* event_; |
| 138 }; | 138 }; |
| 139 | 139 |
| 140 // A bool wrapped in a mutex, to avoid data races. Using a volatile |
| 141 // bool should be sufficient for correct code ("eventual consistency" |
| 142 // between caches is sufficient), but we can't tell the compiler about |
| 143 // that, and then tsan complains about a data race. |
| 144 |
| 145 // See also discussion at |
| 146 // http://stackoverflow.com/questions/7223164/is-mutex-needed-to-synchronize-a-s
imple-flag-between-pthreads |
| 147 |
| 148 // Using std::atomic<bool> or std::atomic_flag in C++11 is probably |
| 149 // the right thing to do, but those features are not yet allowed. Or |
| 150 // rtc::AtomicInt, if/when that is added. Since the use isn't |
| 151 // performance critical, use a plain critical section for the time |
| 152 // being. |
| 153 |
| 154 class AtomicBool { |
| 155 public: |
| 156 explicit AtomicBool(bool value = false) : flag_(value) {} |
| 157 AtomicBool& operator=(bool value) { |
| 158 CritScope scoped_lock(&cs_); |
| 159 flag_ = value; |
| 160 return *this; |
| 161 } |
| 162 bool get() const { |
| 163 CritScope scoped_lock(&cs_); |
| 164 return flag_; |
| 165 } |
| 166 |
| 167 private: |
| 168 mutable CriticalSection cs_; |
| 169 bool flag_; |
| 170 }; |
| 171 |
| 140 // Function objects to test Thread::Invoke. | 172 // Function objects to test Thread::Invoke. |
| 141 struct FunctorA { | 173 struct FunctorA { |
| 142 int operator()() { return 42; } | 174 int operator()() { return 42; } |
| 143 }; | 175 }; |
| 144 class FunctorB { | 176 class FunctorB { |
| 145 public: | 177 public: |
| 146 explicit FunctorB(bool* flag) : flag_(flag) {} | 178 explicit FunctorB(AtomicBool* flag) : flag_(flag) {} |
| 147 void operator()() { if (flag_) *flag_ = true; } | 179 void operator()() { if (flag_) *flag_ = true; } |
| 148 private: | 180 private: |
| 149 bool* flag_; | 181 AtomicBool* flag_; |
| 150 }; | 182 }; |
| 151 struct FunctorC { | 183 struct FunctorC { |
| 152 int operator()() { | 184 int operator()() { |
| 153 Thread::Current()->ProcessMessages(50); | 185 Thread::Current()->ProcessMessages(50); |
| 154 return 24; | 186 return 24; |
| 155 } | 187 } |
| 156 }; | 188 }; |
| 157 | 189 |
| 158 // See: https://code.google.com/p/webrtc/issues/detail?id=2409 | 190 // See: https://code.google.com/p/webrtc/issues/detail?id=2409 |
| 159 TEST(ThreadTest, DISABLED_Main) { | 191 TEST(ThreadTest, DISABLED_Main) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 delete cthread; | 291 delete cthread; |
| 260 current_thread->WrapCurrent(); | 292 current_thread->WrapCurrent(); |
| 261 } | 293 } |
| 262 | 294 |
| 263 TEST(ThreadTest, Invoke) { | 295 TEST(ThreadTest, Invoke) { |
| 264 // Create and start the thread. | 296 // Create and start the thread. |
| 265 Thread thread; | 297 Thread thread; |
| 266 thread.Start(); | 298 thread.Start(); |
| 267 // Try calling functors. | 299 // Try calling functors. |
| 268 EXPECT_EQ(42, thread.Invoke<int>(FunctorA())); | 300 EXPECT_EQ(42, thread.Invoke<int>(FunctorA())); |
| 269 bool called = false; | 301 AtomicBool called; |
| 270 FunctorB f2(&called); | 302 FunctorB f2(&called); |
| 271 thread.Invoke<void>(f2); | 303 thread.Invoke<void>(f2); |
| 272 EXPECT_TRUE(called); | 304 EXPECT_TRUE(called.get()); |
| 273 // Try calling bare functions. | 305 // Try calling bare functions. |
| 274 struct LocalFuncs { | 306 struct LocalFuncs { |
| 275 static int Func1() { return 999; } | 307 static int Func1() { return 999; } |
| 276 static void Func2() {} | 308 static void Func2() {} |
| 277 }; | 309 }; |
| 278 EXPECT_EQ(999, thread.Invoke<int>(&LocalFuncs::Func1)); | 310 EXPECT_EQ(999, thread.Invoke<int>(&LocalFuncs::Func1)); |
| 279 thread.Invoke<void>(&LocalFuncs::Func2); | 311 thread.Invoke<void>(&LocalFuncs::Func2); |
| 280 } | 312 } |
| 281 | 313 |
| 282 // Verifies that two threads calling Invoke on each other at the same time does | 314 // Verifies that two threads calling Invoke on each other at the same time does |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 Event invoke_started_; | 433 Event invoke_started_; |
| 402 Thread* expected_thread_; | 434 Thread* expected_thread_; |
| 403 }; | 435 }; |
| 404 | 436 |
| 405 TEST_F(AsyncInvokeTest, FireAndForget) { | 437 TEST_F(AsyncInvokeTest, FireAndForget) { |
| 406 AsyncInvoker invoker; | 438 AsyncInvoker invoker; |
| 407 // Create and start the thread. | 439 // Create and start the thread. |
| 408 Thread thread; | 440 Thread thread; |
| 409 thread.Start(); | 441 thread.Start(); |
| 410 // Try calling functor. | 442 // Try calling functor. |
| 411 bool called = false; | 443 AtomicBool called; |
| 412 invoker.AsyncInvoke<void>(&thread, FunctorB(&called)); | 444 invoker.AsyncInvoke<void>(&thread, FunctorB(&called)); |
| 413 EXPECT_TRUE_WAIT(called, kWaitTimeout); | 445 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); |
| 414 } | 446 } |
| 415 | 447 |
| 416 TEST_F(AsyncInvokeTest, WithCallback) { | 448 TEST_F(AsyncInvokeTest, WithCallback) { |
| 417 AsyncInvoker invoker; | 449 AsyncInvoker invoker; |
| 418 // Create and start the thread. | 450 // Create and start the thread. |
| 419 Thread thread; | 451 Thread thread; |
| 420 thread.Start(); | 452 thread.Start(); |
| 421 // Try calling functor. | 453 // Try calling functor. |
| 422 SetExpectedThreadForIntCallback(Thread::Current()); | 454 SetExpectedThreadForIntCallback(Thread::Current()); |
| 423 invoker.AsyncInvoke(&thread, FunctorA(), | 455 invoker.AsyncInvoke(&thread, FunctorA(), |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 // Wait for the call to begin. | 503 // Wait for the call to begin. |
| 472 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | 504 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); |
| 473 } | 505 } |
| 474 // Invoker is destroyed. Function should not execute. | 506 // Invoker is destroyed. Function should not execute. |
| 475 Thread::Current()->ProcessMessages(kWaitTimeout); | 507 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 476 EXPECT_EQ(0, int_value_); | 508 EXPECT_EQ(0, int_value_); |
| 477 } | 509 } |
| 478 | 510 |
| 479 TEST_F(AsyncInvokeTest, Flush) { | 511 TEST_F(AsyncInvokeTest, Flush) { |
| 480 AsyncInvoker invoker; | 512 AsyncInvoker invoker; |
| 481 bool flag1 = false; | 513 AtomicBool flag1; |
| 482 bool flag2 = false; | 514 AtomicBool flag2; |
| 483 // Queue two async calls to the current thread. | 515 // Queue two async calls to the current thread. |
| 484 invoker.AsyncInvoke<void>(Thread::Current(), | 516 invoker.AsyncInvoke<void>(Thread::Current(), |
| 485 FunctorB(&flag1)); | 517 FunctorB(&flag1)); |
| 486 invoker.AsyncInvoke<void>(Thread::Current(), | 518 invoker.AsyncInvoke<void>(Thread::Current(), |
| 487 FunctorB(&flag2)); | 519 FunctorB(&flag2)); |
| 488 // Because we haven't pumped messages, these should not have run yet. | 520 // Because we haven't pumped messages, these should not have run yet. |
| 489 EXPECT_FALSE(flag1); | 521 EXPECT_FALSE(flag1.get()); |
| 490 EXPECT_FALSE(flag2); | 522 EXPECT_FALSE(flag2.get()); |
| 491 // Force them to run now. | 523 // Force them to run now. |
| 492 invoker.Flush(Thread::Current()); | 524 invoker.Flush(Thread::Current()); |
| 493 EXPECT_TRUE(flag1); | 525 EXPECT_TRUE(flag1.get()); |
| 494 EXPECT_TRUE(flag2); | 526 EXPECT_TRUE(flag2.get()); |
| 495 } | 527 } |
| 496 | 528 |
| 497 TEST_F(AsyncInvokeTest, FlushWithIds) { | 529 TEST_F(AsyncInvokeTest, FlushWithIds) { |
| 498 AsyncInvoker invoker; | 530 AsyncInvoker invoker; |
| 499 bool flag1 = false; | 531 AtomicBool flag1; |
| 500 bool flag2 = false; | 532 AtomicBool flag2; |
| 501 // Queue two async calls to the current thread, one with a message id. | 533 // Queue two async calls to the current thread, one with a message id. |
| 502 invoker.AsyncInvoke<void>(Thread::Current(), | 534 invoker.AsyncInvoke<void>(Thread::Current(), |
| 503 FunctorB(&flag1), | 535 FunctorB(&flag1), |
| 504 5); | 536 5); |
| 505 invoker.AsyncInvoke<void>(Thread::Current(), | 537 invoker.AsyncInvoke<void>(Thread::Current(), |
| 506 FunctorB(&flag2)); | 538 FunctorB(&flag2)); |
| 507 // Because we haven't pumped messages, these should not have run yet. | 539 // Because we haven't pumped messages, these should not have run yet. |
| 508 EXPECT_FALSE(flag1); | 540 EXPECT_FALSE(flag1.get()); |
| 509 EXPECT_FALSE(flag2); | 541 EXPECT_FALSE(flag2.get()); |
| 510 // Execute pending calls with id == 5. | 542 // Execute pending calls with id == 5. |
| 511 invoker.Flush(Thread::Current(), 5); | 543 invoker.Flush(Thread::Current(), 5); |
| 512 EXPECT_TRUE(flag1); | 544 EXPECT_TRUE(flag1.get()); |
| 513 EXPECT_FALSE(flag2); | 545 EXPECT_FALSE(flag2.get()); |
| 514 flag1 = false; | 546 flag1 = false; |
| 515 // Execute all pending calls. The id == 5 call should not execute again. | 547 // Execute all pending calls. The id == 5 call should not execute again. |
| 516 invoker.Flush(Thread::Current()); | 548 invoker.Flush(Thread::Current()); |
| 517 EXPECT_FALSE(flag1); | 549 EXPECT_FALSE(flag1.get()); |
| 518 EXPECT_TRUE(flag2); | 550 EXPECT_TRUE(flag2.get()); |
| 519 } | 551 } |
| 520 | 552 |
| 521 class GuardedAsyncInvokeTest : public testing::Test { | 553 class GuardedAsyncInvokeTest : public testing::Test { |
| 522 public: | 554 public: |
| 523 void IntCallback(int value) { | 555 void IntCallback(int value) { |
| 524 EXPECT_EQ(expected_thread_, Thread::Current()); | 556 EXPECT_EQ(expected_thread_, Thread::Current()); |
| 525 int_value_ = value; | 557 int_value_ = value; |
| 526 } | 558 } |
| 527 void AsyncInvokeIntCallback(GuardedAsyncInvoker* invoker, Thread* thread) { | 559 void AsyncInvokeIntCallback(GuardedAsyncInvoker* invoker, Thread* thread) { |
| 528 expected_thread_ = thread; | 560 expected_thread_ = thread; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 557 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { | 589 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { |
| 558 // Create and start the thread. | 590 // Create and start the thread. |
| 559 scoped_ptr<Thread> thread(new Thread()); | 591 scoped_ptr<Thread> thread(new Thread()); |
| 560 thread->Start(); | 592 thread->Start(); |
| 561 scoped_ptr<GuardedAsyncInvoker> invoker; | 593 scoped_ptr<GuardedAsyncInvoker> invoker; |
| 562 // Create the invoker on |thread|. | 594 // Create the invoker on |thread|. |
| 563 thread->Invoke<void>(CreateInvoker(&invoker)); | 595 thread->Invoke<void>(CreateInvoker(&invoker)); |
| 564 // Kill |thread|. | 596 // Kill |thread|. |
| 565 thread = nullptr; | 597 thread = nullptr; |
| 566 // Try calling functor. | 598 // Try calling functor. |
| 567 bool called = false; | 599 AtomicBool called; |
| 568 EXPECT_FALSE(invoker->AsyncInvoke<void>(FunctorB(&called))); | 600 EXPECT_FALSE(invoker->AsyncInvoke<void>(FunctorB(&called))); |
| 569 // With thread gone, nothing should happen. | 601 // With thread gone, nothing should happen. |
| 570 WAIT(called, kWaitTimeout); | 602 WAIT(called.get(), kWaitTimeout); |
| 571 EXPECT_FALSE(called); | 603 EXPECT_FALSE(called.get()); |
| 572 } | 604 } |
| 573 | 605 |
| 574 // Test that we can call AsyncInvoke with callback after the thread died. | 606 // Test that we can call AsyncInvoke with callback after the thread died. |
| 575 TEST_F(GuardedAsyncInvokeTest, KillThreadWithCallback) { | 607 TEST_F(GuardedAsyncInvokeTest, KillThreadWithCallback) { |
| 576 // Create and start the thread. | 608 // Create and start the thread. |
| 577 scoped_ptr<Thread> thread(new Thread()); | 609 scoped_ptr<Thread> thread(new Thread()); |
| 578 thread->Start(); | 610 thread->Start(); |
| 579 scoped_ptr<GuardedAsyncInvoker> invoker; | 611 scoped_ptr<GuardedAsyncInvoker> invoker; |
| 580 // Create the invoker on |thread|. | 612 // Create the invoker on |thread|. |
| 581 thread->Invoke<void>(CreateInvoker(&invoker)); | 613 thread->Invoke<void>(CreateInvoker(&invoker)); |
| 582 // Kill |thread|. | 614 // Kill |thread|. |
| 583 thread = nullptr; | 615 thread = nullptr; |
| 584 // Try calling functor. | 616 // Try calling functor. |
| 585 EXPECT_FALSE( | 617 EXPECT_FALSE( |
| 586 invoker->AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, | 618 invoker->AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, |
| 587 static_cast<GuardedAsyncInvokeTest*>(this))); | 619 static_cast<GuardedAsyncInvokeTest*>(this))); |
| 588 // With thread gone, callback should be cancelled. | 620 // With thread gone, callback should be cancelled. |
| 589 Thread::Current()->ProcessMessages(kWaitTimeout); | 621 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 590 EXPECT_EQ(0, int_value_); | 622 EXPECT_EQ(0, int_value_); |
| 591 } | 623 } |
| 592 | 624 |
| 593 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker | 625 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker |
| 594 // when Thread is still alive. | 626 // when Thread is still alive. |
| 595 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { | 627 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { |
| 596 GuardedAsyncInvoker invoker; | 628 GuardedAsyncInvoker invoker; |
| 597 // Try calling functor. | 629 // Try calling functor. |
| 598 bool called = false; | 630 AtomicBool called; |
| 599 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&called))); | 631 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&called))); |
| 600 EXPECT_TRUE_WAIT(called, kWaitTimeout); | 632 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); |
| 601 } | 633 } |
| 602 | 634 |
| 603 TEST_F(GuardedAsyncInvokeTest, WithCallback) { | 635 TEST_F(GuardedAsyncInvokeTest, WithCallback) { |
| 604 GuardedAsyncInvoker invoker; | 636 GuardedAsyncInvoker invoker; |
| 605 // Try calling functor. | 637 // Try calling functor. |
| 606 SetExpectedThreadForIntCallback(Thread::Current()); | 638 SetExpectedThreadForIntCallback(Thread::Current()); |
| 607 EXPECT_TRUE(invoker.AsyncInvoke(FunctorA(), | 639 EXPECT_TRUE(invoker.AsyncInvoke(FunctorA(), |
| 608 &GuardedAsyncInvokeTest::IntCallback, | 640 &GuardedAsyncInvokeTest::IntCallback, |
| 609 static_cast<GuardedAsyncInvokeTest*>(this))); | 641 static_cast<GuardedAsyncInvokeTest*>(this))); |
| 610 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); | 642 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 // Wait for the call to begin. | 685 // Wait for the call to begin. |
| 654 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | 686 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); |
| 655 } | 687 } |
| 656 // Invoker is destroyed. Function should not execute. | 688 // Invoker is destroyed. Function should not execute. |
| 657 Thread::Current()->ProcessMessages(kWaitTimeout); | 689 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 658 EXPECT_EQ(0, int_value_); | 690 EXPECT_EQ(0, int_value_); |
| 659 } | 691 } |
| 660 | 692 |
| 661 TEST_F(GuardedAsyncInvokeTest, Flush) { | 693 TEST_F(GuardedAsyncInvokeTest, Flush) { |
| 662 GuardedAsyncInvoker invoker; | 694 GuardedAsyncInvoker invoker; |
| 663 bool flag1 = false; | 695 AtomicBool flag1; |
| 664 bool flag2 = false; | 696 AtomicBool flag2; |
| 665 // Queue two async calls to the current thread. | 697 // Queue two async calls to the current thread. |
| 666 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1))); | 698 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1))); |
| 667 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); | 699 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); |
| 668 // Because we haven't pumped messages, these should not have run yet. | 700 // Because we haven't pumped messages, these should not have run yet. |
| 669 EXPECT_FALSE(flag1); | 701 EXPECT_FALSE(flag1.get()); |
| 670 EXPECT_FALSE(flag2); | 702 EXPECT_FALSE(flag2.get()); |
| 671 // Force them to run now. | 703 // Force them to run now. |
| 672 EXPECT_TRUE(invoker.Flush()); | 704 EXPECT_TRUE(invoker.Flush()); |
| 673 EXPECT_TRUE(flag1); | 705 EXPECT_TRUE(flag1.get()); |
| 674 EXPECT_TRUE(flag2); | 706 EXPECT_TRUE(flag2.get()); |
| 675 } | 707 } |
| 676 | 708 |
| 677 TEST_F(GuardedAsyncInvokeTest, FlushWithIds) { | 709 TEST_F(GuardedAsyncInvokeTest, FlushWithIds) { |
| 678 GuardedAsyncInvoker invoker; | 710 GuardedAsyncInvoker invoker; |
| 679 bool flag1 = false; | 711 AtomicBool flag1; |
| 680 bool flag2 = false; | 712 AtomicBool flag2; |
| 681 // Queue two async calls to the current thread, one with a message id. | 713 // Queue two async calls to the current thread, one with a message id. |
| 682 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1), 5)); | 714 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1), 5)); |
| 683 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); | 715 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); |
| 684 // Because we haven't pumped messages, these should not have run yet. | 716 // Because we haven't pumped messages, these should not have run yet. |
| 685 EXPECT_FALSE(flag1); | 717 EXPECT_FALSE(flag1.get()); |
| 686 EXPECT_FALSE(flag2); | 718 EXPECT_FALSE(flag2.get()); |
| 687 // Execute pending calls with id == 5. | 719 // Execute pending calls with id == 5. |
| 688 EXPECT_TRUE(invoker.Flush(5)); | 720 EXPECT_TRUE(invoker.Flush(5)); |
| 689 EXPECT_TRUE(flag1); | 721 EXPECT_TRUE(flag1.get()); |
| 690 EXPECT_FALSE(flag2); | 722 EXPECT_FALSE(flag2.get()); |
| 691 flag1 = false; | 723 flag1 = false; |
| 692 // Execute all pending calls. The id == 5 call should not execute again. | 724 // Execute all pending calls. The id == 5 call should not execute again. |
| 693 EXPECT_TRUE(invoker.Flush()); | 725 EXPECT_TRUE(invoker.Flush()); |
| 694 EXPECT_FALSE(flag1); | 726 EXPECT_FALSE(flag1.get()); |
| 695 EXPECT_TRUE(flag2); | 727 EXPECT_TRUE(flag2.get()); |
| 696 } | 728 } |
| 697 | 729 |
| 698 #if defined(WEBRTC_WIN) | 730 #if defined(WEBRTC_WIN) |
| 699 class ComThreadTest : public testing::Test, public MessageHandler { | 731 class ComThreadTest : public testing::Test, public MessageHandler { |
| 700 public: | 732 public: |
| 701 ComThreadTest() : done_(false) {} | 733 ComThreadTest() : done_(false) {} |
| 702 protected: | 734 protected: |
| 703 virtual void OnMessage(Message* message) { | 735 virtual void OnMessage(Message* message) { |
| 704 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); | 736 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); |
| 705 // S_FALSE means the thread was already inited for a multithread apartment. | 737 // S_FALSE means the thread was already inited for a multithread apartment. |
| 706 EXPECT_EQ(S_FALSE, hr); | 738 EXPECT_EQ(S_FALSE, hr); |
| 707 if (SUCCEEDED(hr)) { | 739 if (SUCCEEDED(hr)) { |
| 708 CoUninitialize(); | 740 CoUninitialize(); |
| 709 } | 741 } |
| 710 done_ = true; | 742 done_ = true; |
| 711 } | 743 } |
| 712 bool done_; | 744 bool done_; |
| 713 }; | 745 }; |
| 714 | 746 |
| 715 TEST_F(ComThreadTest, ComInited) { | 747 TEST_F(ComThreadTest, ComInited) { |
| 716 Thread* thread = new ComThread(); | 748 Thread* thread = new ComThread(); |
| 717 EXPECT_TRUE(thread->Start()); | 749 EXPECT_TRUE(thread->Start()); |
| 718 thread->Post(this, 0); | 750 thread->Post(this, 0); |
| 719 EXPECT_TRUE_WAIT(done_, 1000); | 751 EXPECT_TRUE_WAIT(done_, 1000); |
| 720 delete thread; | 752 delete thread; |
| 721 } | 753 } |
| 722 #endif | 754 #endif |
| OLD | NEW |