1 // Copyright (c) 2010 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.
5 #include "testing/gtest/include/gtest/gtest.h"
6 #include "base/message_loop.h"
7 #include "base/thread.h"
8 #include "base/scoped_ptr.h"
9 #include "base/weak_ptr.h"
15 class OffThreadObjectCreator
{
17 static T
* NewObject() {
20 Thread
creator_thread("creator_thread");
21 creator_thread
.Start();
22 creator_thread
.message_loop()->PostTask(
24 NewRunnableFunction(OffThreadObjectCreator::CreateObject
, &result
));
26 DCHECK(result
); // We synchronized on thread destruction above.
30 static void CreateObject(T
** result
) {
36 struct Derived
: Base
{};
38 struct Producer
: SupportsWeakPtr
<Producer
> {};
39 struct Consumer
{ WeakPtr
<Producer
> producer
; };
43 TEST(WeakPtrTest
, Basic
) {
45 WeakPtrFactory
<int> factory(&data
);
46 WeakPtr
<int> ptr
= factory
.GetWeakPtr();
47 EXPECT_EQ(&data
, ptr
.get());
50 TEST(WeakPtrTest
, Comparison
) {
52 WeakPtrFactory
<int> factory(&data
);
53 WeakPtr
<int> ptr
= factory
.GetWeakPtr();
54 WeakPtr
<int> ptr2
= ptr
;
55 EXPECT_TRUE(ptr
== ptr2
);
58 TEST(WeakPtrTest
, OutOfScope
) {
60 EXPECT_TRUE(ptr
.get() == NULL
);
63 WeakPtrFactory
<int> factory(&data
);
64 ptr
= factory
.GetWeakPtr();
66 EXPECT_TRUE(ptr
.get() == NULL
);
69 TEST(WeakPtrTest
, Multiple
) {
73 WeakPtrFactory
<int> factory(&data
);
74 a
= factory
.GetWeakPtr();
75 b
= factory
.GetWeakPtr();
76 EXPECT_EQ(&data
, a
.get());
77 EXPECT_EQ(&data
, b
.get());
79 EXPECT_TRUE(a
.get() == NULL
);
80 EXPECT_TRUE(b
.get() == NULL
);
83 TEST(WeakPtrTest
, UpCast
) {
85 WeakPtrFactory
<Derived
> factory(&data
);
86 WeakPtr
<Base
> ptr
= factory
.GetWeakPtr();
87 ptr
= factory
.GetWeakPtr();
88 EXPECT_EQ(ptr
.get(), &data
);
91 TEST(WeakPtrTest
, SupportsWeakPtr
) {
93 WeakPtr
<Producer
> ptr
= f
.AsWeakPtr();
94 EXPECT_EQ(&f
, ptr
.get());
97 TEST(WeakPtrTest
, InvalidateWeakPtrs
) {
99 WeakPtrFactory
<int> factory(&data
);
100 WeakPtr
<int> ptr
= factory
.GetWeakPtr();
101 EXPECT_EQ(&data
, ptr
.get());
102 EXPECT_TRUE(factory
.HasWeakPtrs());
103 factory
.InvalidateWeakPtrs();
104 EXPECT_TRUE(ptr
.get() == NULL
);
105 EXPECT_FALSE(factory
.HasWeakPtrs());
108 TEST(WeakPtrTest
, HasWeakPtrs
) {
110 WeakPtrFactory
<int> factory(&data
);
112 WeakPtr
<int> ptr
= factory
.GetWeakPtr();
113 EXPECT_TRUE(factory
.HasWeakPtrs());
115 EXPECT_FALSE(factory
.HasWeakPtrs());
118 TEST(WeakPtrTest
, SingleThreaded1
) {
119 // Test that it is OK to create a class that supports weak references on one
120 // thread, but use it on another. This tests that we do not trip runtime
121 // checks that ensure that a weak reference is not used by multiple threads.
122 scoped_ptr
<Producer
> producer(OffThreadObjectCreator
<Producer
>::NewObject());
123 WeakPtr
<Producer
> weak_producer
= producer
->AsWeakPtr();
124 EXPECT_EQ(producer
.get(), weak_producer
.get());
127 TEST(WeakPtrTest
, SingleThreaded2
) {
128 // Test that it is OK to create a class that has a WeakPtr member on one
129 // thread, but use it on another. This tests that we do not trip runtime
130 // checks that ensure that a weak reference is not used by multiple threads.
131 scoped_ptr
<Consumer
> consumer(OffThreadObjectCreator
<Consumer
>::NewObject());
133 consumer
->producer
= producer
.AsWeakPtr();
134 EXPECT_EQ(&producer
, consumer
->producer
.get());