| Index: base/timer/timer_unittest.cc
|
| diff --git a/base/timer/timer_unittest.cc b/base/timer/timer_unittest.cc
|
| index 7c3c1079d72f54be9585287c4ace5473c9c7b5f2..69338eb211b52c32e0bc31250c515597c30d02ca 100644
|
| --- a/base/timer/timer_unittest.cc
|
| +++ b/base/timer/timer_unittest.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/callback.h"
|
| #include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "base/memory/ref_counted.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "base/sequenced_task_runner.h"
|
| @@ -556,6 +557,50 @@ TEST(TimerTest, MessageLoopShutdown) {
|
| EXPECT_FALSE(did_run.IsSignaled());
|
| }
|
|
|
| +// Ref counted class which owns a Timer. The class passes a reference to itself
|
| +// via the |user_task| parameter in Timer::Start(). |Timer::user_task_| might
|
| +// end up holding the last reference to the class.
|
| +class OneShotSelfOwningTimerTester
|
| + : public RefCounted<OneShotSelfOwningTimerTester> {
|
| + public:
|
| + OneShotSelfOwningTimerTester() = default;
|
| +
|
| + void StartTimer() {
|
| + // Start timer with long delay in order to test the timer getting destroyed
|
| + // while a timer task is still pending.
|
| + timer_.Start(FROM_HERE, TimeDelta::FromDays(1),
|
| + base::Bind(&OneShotSelfOwningTimerTester::Run, this));
|
| + }
|
| +
|
| + private:
|
| + friend class RefCounted<OneShotSelfOwningTimerTester>;
|
| + ~OneShotSelfOwningTimerTester() = default;
|
| +
|
| + void Run() {
|
| + ADD_FAILURE() << "Timer unexpectedly fired.";
|
| + }
|
| +
|
| + OneShotTimer timer_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(OneShotSelfOwningTimerTester);
|
| +};
|
| +
|
| +TEST(TimerTest, MessageLoopShutdownSelfOwningTimer) {
|
| + // This test verifies that shutdown of the message loop does not cause crashes
|
| + // if there is a pending timer not yet fired and |Timer::user_task_| owns the
|
| + // timer. The test may only trigger exceptions if debug heap checking is
|
| + // enabled.
|
| +
|
| + MessageLoop loop;
|
| + scoped_refptr<OneShotSelfOwningTimerTester> tester =
|
| + new OneShotSelfOwningTimerTester();
|
| +
|
| + std::move(tester)->StartTimer();
|
| + // |Timer::user_task_| owns sole reference to |tester|.
|
| +
|
| + // MessageLoop destructs by falling out of scope. SHOULD NOT CRASH.
|
| +}
|
| +
|
| void TimerTestCallback() {
|
| }
|
|
|
|
|