| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/timer/timer.h" | 5 #include "base/timer/timer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/memory/ref_counted.h" |
| 16 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 17 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 18 #include "base/sequenced_task_runner.h" | 19 #include "base/sequenced_task_runner.h" |
| 19 #include "base/single_thread_task_runner.h" | 20 #include "base/single_thread_task_runner.h" |
| 20 #include "base/synchronization/waitable_event.h" | 21 #include "base/synchronization/waitable_event.h" |
| 21 #include "base/test/sequenced_worker_pool_owner.h" | 22 #include "base/test/sequenced_worker_pool_owner.h" |
| 22 #include "base/test/test_mock_time_task_runner.h" | 23 #include "base/test/test_mock_time_task_runner.h" |
| 23 #include "base/threading/platform_thread.h" | 24 #include "base/threading/platform_thread.h" |
| 24 #include "base/threading/sequenced_task_runner_handle.h" | 25 #include "base/threading/sequenced_task_runner_handle.h" |
| 25 #include "base/threading/thread.h" | 26 #include "base/threading/thread.h" |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 { | 550 { |
| 550 MessageLoop loop; | 551 MessageLoop loop; |
| 551 a.Start(); | 552 a.Start(); |
| 552 b.Start(); | 553 b.Start(); |
| 553 } // MessageLoop destructs by falling out of scope. | 554 } // MessageLoop destructs by falling out of scope. |
| 554 } // OneShotTimers destruct. SHOULD NOT CRASH, of course. | 555 } // OneShotTimers destruct. SHOULD NOT CRASH, of course. |
| 555 | 556 |
| 556 EXPECT_FALSE(did_run.IsSignaled()); | 557 EXPECT_FALSE(did_run.IsSignaled()); |
| 557 } | 558 } |
| 558 | 559 |
| 560 // Ref counted class which owns a Timer. The class passes a reference to itself |
| 561 // via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might |
| 562 // end up holding the last reference to the class. |
| 563 class OneShotSelfOwningTimerTester |
| 564 : public RefCounted<OneShotSelfOwningTimerTester> { |
| 565 public: |
| 566 OneShotSelfOwningTimerTester() = default; |
| 567 |
| 568 void StartTimer() { |
| 569 // Start timer with long delay in order to test the timer getting destroyed |
| 570 // while a timer task is still pending. |
| 571 timer_.Start(FROM_HERE, TimeDelta::FromDays(1), |
| 572 base::Bind(&OneShotSelfOwningTimerTester::Run, this)); |
| 573 } |
| 574 |
| 575 private: |
| 576 friend class RefCounted<OneShotSelfOwningTimerTester>; |
| 577 ~OneShotSelfOwningTimerTester() = default; |
| 578 |
| 579 void Run() { |
| 580 ADD_FAILURE() << "Timer unexpectedly fired."; |
| 581 } |
| 582 |
| 583 OneShotTimer timer_; |
| 584 |
| 585 DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester); |
| 586 }; |
| 587 |
| 588 TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) { |
| 589 // This test verifies that shutdown of the message loop does not cause crashes |
| 590 // if there is a pending timer not yet fired and |Timer::user_task_| owns the |
| 591 // timer. The test may only trigger exceptions if debug heap checking is |
| 592 // enabled. |
| 593 |
| 594 MessageLoop loop; |
| 595 scoped_refptr<OneShotSelfOwningTimerTester> tester = |
| 596 new OneShotSelfOwningTimerTester(); |
| 597 |
| 598 std::move(tester)->StartTimer(); |
| 599 // |Timer::user_task_| owns sole reference to |tester|. |
| 600 |
| 601 // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH. |
| 602 } |
| 603 |
| 559 void TimerTestCallback() { | 604 void TimerTestCallback() { |
| 560 } | 605 } |
| 561 | 606 |
| 562 TEST(TimerTest, NonRepeatIsRunning) { | 607 TEST(TimerTest, NonRepeatIsRunning) { |
| 563 { | 608 { |
| 564 MessageLoop loop; | 609 MessageLoop loop; |
| 565 Timer timer(false, false); | 610 Timer timer(false, false); |
| 566 EXPECT_FALSE(timer.IsRunning()); | 611 EXPECT_FALSE(timer.IsRunning()); |
| 567 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback)); | 612 timer.Start(FROM_HERE, TimeDelta::FromDays(1), Bind(&TimerTestCallback)); |
| 568 EXPECT_TRUE(timer.IsRunning()); | 613 EXPECT_TRUE(timer.IsRunning()); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 Bind(&SetCallbackHappened1)); | 715 Bind(&SetCallbackHappened1)); |
| 671 timer.Reset(); | 716 timer.Reset(); |
| 672 // Since Reset happened before task ran, the user_task must not be cleared: | 717 // Since Reset happened before task ran, the user_task must not be cleared: |
| 673 ASSERT_FALSE(timer.user_task().is_null()); | 718 ASSERT_FALSE(timer.user_task().is_null()); |
| 674 RunLoop().Run(); | 719 RunLoop().Run(); |
| 675 EXPECT_TRUE(g_callback_happened1); | 720 EXPECT_TRUE(g_callback_happened1); |
| 676 } | 721 } |
| 677 } | 722 } |
| 678 | 723 |
| 679 } // namespace base | 724 } // namespace base |
| OLD | NEW |