| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/sync/weak_handle.h" | 5 #include "chrome/browser/sync/weak_handle.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/memory/weak_ptr.h" | 9 #include "base/memory/weak_ptr.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/threading/thread.h" | 11 #include "base/threading/thread.h" |
| 12 #include "base/tracked.h" | 12 #include "base/tracked.h" |
| 13 #include "testing/gmock/include/gmock/gmock.h" | 13 #include "testing/gmock/include/gmock/gmock.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 | 15 |
| 16 namespace browser_sync { | 16 namespace browser_sync { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 using ::testing::_; |
| 20 using ::testing::SaveArg; |
| 19 using ::testing::StrictMock; | 21 using ::testing::StrictMock; |
| 20 | 22 |
| 21 class Base { | 23 class Base { |
| 22 public: | 24 public: |
| 23 Base() : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} | 25 Base() : weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {} |
| 24 | 26 |
| 25 WeakHandle<Base> AsWeakHandle() { | 27 WeakHandle<Base> AsWeakHandle() { |
| 26 return MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); | 28 return MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); |
| 27 } | 29 } |
| 28 | 30 |
| 29 void Kill() { | 31 void Kill() { |
| 30 weak_ptr_factory_.InvalidateWeakPtrs(); | 32 weak_ptr_factory_.InvalidateWeakPtrs(); |
| 31 } | 33 } |
| 32 | 34 |
| 33 MOCK_METHOD0(Test, void()); | 35 MOCK_METHOD0(Test, void()); |
| 34 MOCK_METHOD1(Test1, void(const int&)); | 36 MOCK_METHOD1(Test1, void(const int&)); |
| 35 MOCK_METHOD2(Test2, void(const int&, Base*)); | 37 MOCK_METHOD2(Test2, void(const int&, Base*)); |
| 36 MOCK_METHOD3(Test3, void(const int&, Base*, float)); | 38 MOCK_METHOD3(Test3, void(const int&, Base*, float)); |
| 37 MOCK_METHOD4(Test4, void(const int&, Base*, float, const char*)); | 39 MOCK_METHOD4(Test4, void(const int&, Base*, float, const char*)); |
| 38 | 40 |
| 41 MOCK_METHOD1(TestWithSelf, void(const WeakHandle<Base>&)); |
| 42 |
| 39 private: | 43 private: |
| 40 base::WeakPtrFactory<Base> weak_ptr_factory_; | 44 base::WeakPtrFactory<Base> weak_ptr_factory_; |
| 41 }; | 45 }; |
| 42 | 46 |
| 43 class WeakHandleTest : public ::testing::Test { | 47 class WeakHandleTest : public ::testing::Test { |
| 44 protected: | 48 protected: |
| 45 virtual void TearDown() { | 49 virtual void TearDown() { |
| 46 // Process any last-minute posted tasks. | 50 // Process any last-minute posted tasks. |
| 47 PumpLoop(); | 51 PumpLoop(); |
| 48 } | 52 } |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 | 198 |
| 195 { | 199 { |
| 196 base::Thread t("Test thread"); | 200 base::Thread t("Test thread"); |
| 197 ASSERT_TRUE(t.Start()); | 201 ASSERT_TRUE(t.Start()); |
| 198 t.message_loop()->DeleteSoon(FROM_HERE, h); | 202 t.message_loop()->DeleteSoon(FROM_HERE, h); |
| 199 } | 203 } |
| 200 | 204 |
| 201 PumpLoop(); | 205 PumpLoop(); |
| 202 } | 206 } |
| 203 | 207 |
| 208 void CallTestWithSelf(const WeakHandle<Base>& b1) { |
| 209 StrictMock<Base> b2; |
| 210 b1.Call(FROM_HERE, &Base::TestWithSelf, b2.AsWeakHandle()); |
| 211 } |
| 212 |
| 213 TEST_F(WeakHandleTest, WithDestroyedThread) { |
| 214 StrictMock<Base> b1; |
| 215 WeakHandle<Base> b2; |
| 216 EXPECT_CALL(b1, TestWithSelf(_)).WillOnce(SaveArg<0>(&b2)); |
| 217 |
| 218 { |
| 219 base::Thread t("Test thread"); |
| 220 ASSERT_TRUE(t.Start()); |
| 221 t.message_loop()->PostTask(FROM_HERE, |
| 222 base::Bind(&CallTestWithSelf, |
| 223 b1.AsWeakHandle())); |
| 224 } |
| 225 |
| 226 // Calls b1.TestWithSelf(). |
| 227 PumpLoop(); |
| 228 |
| 229 // Shouldn't do anything, since the thread is gone. |
| 230 b2.Call(FROM_HERE, &Base::Test); |
| 231 |
| 232 // |b2| shouldn't leak when it's destroyed, even if the original |
| 233 // thread is gone. |
| 234 } |
| 235 |
| 204 TEST_F(WeakHandleTest, InitializedAcrossCopyAssign) { | 236 TEST_F(WeakHandleTest, InitializedAcrossCopyAssign) { |
| 205 StrictMock<Base> b; | 237 StrictMock<Base> b; |
| 206 EXPECT_CALL(b, Test()).Times(3); | 238 EXPECT_CALL(b, Test()).Times(3); |
| 207 | 239 |
| 208 EXPECT_TRUE(b.AsWeakHandle().IsInitialized()); | 240 EXPECT_TRUE(b.AsWeakHandle().IsInitialized()); |
| 209 b.AsWeakHandle().Call(FROM_HERE, &Base::Test); | 241 b.AsWeakHandle().Call(FROM_HERE, &Base::Test); |
| 210 | 242 |
| 211 { | 243 { |
| 212 WeakHandle<Base> h(b.AsWeakHandle()); | 244 WeakHandle<Base> h(b.AsWeakHandle()); |
| 213 EXPECT_TRUE(h.IsInitialized()); | 245 EXPECT_TRUE(h.IsInitialized()); |
| 214 h.Call(FROM_HERE, &Base::Test); | 246 h.Call(FROM_HERE, &Base::Test); |
| 215 h.Reset(); | 247 h.Reset(); |
| 216 EXPECT_FALSE(h.IsInitialized()); | 248 EXPECT_FALSE(h.IsInitialized()); |
| 217 } | 249 } |
| 218 | 250 |
| 219 { | 251 { |
| 220 WeakHandle<Base> h; | 252 WeakHandle<Base> h; |
| 221 h = b.AsWeakHandle(); | 253 h = b.AsWeakHandle(); |
| 222 EXPECT_TRUE(h.IsInitialized()); | 254 EXPECT_TRUE(h.IsInitialized()); |
| 223 h.Call(FROM_HERE, &Base::Test); | 255 h.Call(FROM_HERE, &Base::Test); |
| 224 h.Reset(); | 256 h.Reset(); |
| 225 EXPECT_FALSE(h.IsInitialized()); | 257 EXPECT_FALSE(h.IsInitialized()); |
| 226 } | 258 } |
| 227 | 259 |
| 228 PumpLoop(); | 260 PumpLoop(); |
| 229 } | 261 } |
| 230 | 262 |
| 231 } // namespace | 263 } // namespace |
| 232 } // namespace browser_sync | 264 } // namespace browser_sync |
| OLD | NEW |