1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/basictypes.h" 6 #include "base/bind.h" 7 #include "base/location.h" 8 #include "base/memory/scoped_ptr.h" 9 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/run_loop.h" 11 #include "base/time/time.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 #include "webkit/browser/fileapi/timed_task_helper.h" 14 15 namespace fileapi { 16 17 namespace { 18 19 class Embedder { 20 public: 21 Embedder() 22 : timer_(base::MessageLoopProxy::current().get()), timer_fired_(false) {} 23 24 void OnTimerFired() { 25 timer_fired_ = true; 26 } 27 28 TimedTaskHelper* timer() { return &timer_; } 29 bool timer_fired() const { return timer_fired_; } 30 31 private: 32 TimedTaskHelper timer_; 33 bool timer_fired_; 34 }; 35 36 } // namespace 37 38 TEST(TimedTaskHelper, FireTimerWhenAlive) { 39 base::MessageLoop message_loop; 40 Embedder embedder; 41 42 ASSERT_FALSE(embedder.timer_fired()); 43 ASSERT_FALSE(embedder.timer()->IsRunning()); 44 45 embedder.timer()->Start( 46 FROM_HERE, 47 base::TimeDelta::FromSeconds(0), 48 base::Bind(&Embedder::OnTimerFired, base::Unretained(&embedder))); 49 50 ASSERT_TRUE(embedder.timer()->IsRunning()); 51 embedder.timer()->Reset(); 52 ASSERT_TRUE(embedder.timer()->IsRunning()); 53 54 base::RunLoop().RunUntilIdle(); 55 56 ASSERT_TRUE(embedder.timer_fired()); 57 } 58 59 TEST(TimedTaskHelper, FireTimerWhenAlreadyDeleted) { 60 base::MessageLoop message_loop; 61 62 // Run message loop after embedder is already deleted to make sure callback 63 // doesn't cause a crash for use after free. 64 { 65 Embedder embedder; 66 67 ASSERT_FALSE(embedder.timer_fired()); 68 ASSERT_FALSE(embedder.timer()->IsRunning()); 69 70 embedder.timer()->Start( 71 FROM_HERE, 72 base::TimeDelta::FromSeconds(0), 73 base::Bind(&Embedder::OnTimerFired, base::Unretained(&embedder))); 74 75 ASSERT_TRUE(embedder.timer()->IsRunning()); 76 } 77 78 // At this point the callback is still in the message queue but 79 // embedder is gone. 80 base::RunLoop().RunUntilIdle(); 81 } 82 83 } // namespace fileapi 84