1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/weak_ptr.h" 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/message_loop.h" 93f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace base { 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttemplate <class T> 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass OffThreadObjectCreator { 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static T* NewObject() { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott T* result; 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Thread creator_thread("creator_thread"); 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott creator_thread.Start(); 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch creator_thread.message_loop()->PostTask( 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FROM_HERE, 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NewRunnableFunction(OffThreadObjectCreator::CreateObject, &result)); 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(result); // We synchronized on thread destruction above. 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return result; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static void CreateObject(T** result) { 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *result = new T; 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Base {}; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Derived : Base {}; 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Producer : SupportsWeakPtr<Producer> {}; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Consumer { WeakPtr<Producer> producer; }; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, Basic) { 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr = factory.GetWeakPtr(); 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&data, ptr.get()); 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, Comparison) { 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr = factory.GetWeakPtr(); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr2 = ptr; 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(ptr == ptr2); 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, OutOfScope) { 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(ptr.get() == NULL); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = factory.GetWeakPtr(); 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(ptr.get() == NULL); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, Multiple) { 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> a, b; 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott a = factory.GetWeakPtr(); 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott b = factory.GetWeakPtr(); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&data, a.get()); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&data, b.get()); 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(a.get() == NULL); 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(b.get() == NULL); 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, UpCast) { 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Derived data; 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<Derived> factory(&data); 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<Base> ptr = factory.GetWeakPtr(); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ptr = factory.GetWeakPtr(); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(ptr.get(), &data); 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, SupportsWeakPtr) { 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Producer f; 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<Producer> ptr = f.AsWeakPtr(); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&f, ptr.get()); 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, InvalidateWeakPtrs) { 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr = factory.GetWeakPtr(); 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&data, ptr.get()); 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(factory.HasWeakPtrs()); 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott factory.InvalidateWeakPtrs(); 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(ptr.get() == NULL); 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(factory.HasWeakPtrs()); 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, HasWeakPtrs) { 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int data; 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtrFactory<int> factory(&data); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<int> ptr = factory.GetWeakPtr(); 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(factory.HasWeakPtrs()); 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_FALSE(factory.HasWeakPtrs()); 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, SingleThreaded1) { 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test that it is OK to create a class that supports weak references on one 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // thread, but use it on another. This tests that we do not trip runtime 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // checks that ensure that a weak reference is not used by multiple threads. 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<Producer> producer(OffThreadObjectCreator<Producer>::NewObject()); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott WeakPtr<Producer> weak_producer = producer->AsWeakPtr(); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(producer.get(), weak_producer.get()); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST(WeakPtrTest, SingleThreaded2) { 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Test that it is OK to create a class that has a WeakPtr member on one 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // thread, but use it on another. This tests that we do not trip runtime 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // checks that ensure that a weak reference is not used by multiple threads. 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<Consumer> consumer(OffThreadObjectCreator<Consumer>::NewObject()); 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Producer producer; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott consumer->producer = producer.AsWeakPtr(); 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(&producer, consumer->producer.get()); 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace base 138