OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/at_exit.h" | 5 #include "base/at_exit.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 COMPILE_ASSERT(DefaultSingletonTraits<int>::kRegisterAtExit == true, a); | 13 COMPILE_ASSERT(DefaultSingletonTraits<int>::kRegisterAtExit == true, a); |
14 | 14 |
15 template<typename Type> | 15 template<typename Type> |
16 struct LockTrait : public DefaultSingletonTraits<Type> { | 16 struct LockTrait : public DefaultSingletonTraits<Type> { |
17 }; | 17 }; |
18 | 18 |
19 struct Init5Trait : public DefaultSingletonTraits<int> { | |
20 static int* New() { | |
21 return new int(5); | |
22 } | |
23 }; | |
24 | |
25 typedef void (*CallbackFunc)(); | 19 typedef void (*CallbackFunc)(); |
26 | 20 |
27 struct CallbackTrait : public DefaultSingletonTraits<CallbackFunc> { | 21 class IntSingleton { |
28 static void Delete(CallbackFunc* p) { | 22 public: |
29 if (*p) | 23 class DummyDifferentiatingClass { |
30 (*p)(); | 24 }; |
31 DefaultSingletonTraits<CallbackFunc>::Delete(p); | 25 |
26 struct Init5Trait : public DefaultSingletonTraits<IntSingleton> { | |
27 static IntSingleton* New() { | |
28 IntSingleton* instance = new IntSingleton(); | |
29 instance->value_ = 5; | |
30 return instance; | |
31 } | |
32 }; | |
33 | |
34 static IntSingleton* GetInstance() { | |
35 return Singleton<IntSingleton>::get(); | |
32 } | 36 } |
33 }; | 37 static IntSingleton* GetInstanceWithDefaultTraits() { |
38 return Singleton<IntSingleton, | |
39 DefaultSingletonTraits<IntSingleton> >::get(); | |
40 } | |
41 static IntSingleton* GetInstanceWithDifferentiatingClass() { | |
42 return Singleton<IntSingleton, | |
43 DefaultSingletonTraits<IntSingleton>, | |
44 DummyDifferentiatingClass>::get(); | |
45 } | |
46 static IntSingleton* GetInstanceWithLockTrait() { | |
47 return Singleton<IntSingleton, LockTrait<IntSingleton> >::get(); | |
48 } | |
49 static IntSingleton* GetInstanceWithInit5Trait() { | |
50 return Singleton<IntSingleton, Init5Trait>::get(); | |
51 } | |
34 | 52 |
35 struct StaticCallbackTrait : public StaticMemorySingletonTraits<CallbackFunc> { | 53 int value_; |
36 static void Delete(CallbackFunc* p) { | |
37 if (*p) | |
38 (*p)(); | |
39 StaticMemorySingletonTraits<CallbackFunc>::Delete(p); | |
40 } | |
41 }; | |
42 | |
43 | |
44 struct NoLeakTrait : public CallbackTrait { | |
45 }; | |
46 | |
47 struct LeakTrait : public CallbackTrait { | |
48 static const bool kRegisterAtExit = false; | |
49 }; | 54 }; |
50 | 55 |
51 int* SingletonInt1() { | 56 int* SingletonInt1() { |
52 return Singleton<int>::get(); | 57 return &IntSingleton::GetInstance()->value_; |
53 } | 58 } |
54 | 59 |
55 int* SingletonInt2() { | 60 int* SingletonInt2() { |
56 // Force to use a different singleton than SingletonInt1. | 61 // Force to use a different singleton than SingletonInt1. |
57 return Singleton<int, DefaultSingletonTraits<int> >::get(); | 62 return &IntSingleton::GetInstanceWithDefaultTraits()->value_; |
58 } | 63 } |
59 | 64 |
60 class DummyDifferentiatingClass { | |
61 }; | |
62 | |
63 int* SingletonInt3() { | 65 int* SingletonInt3() { |
64 // Force to use a different singleton than SingletonInt1 and SingletonInt2. | 66 // Force to use a different singleton than SingletonInt1 and SingletonInt2. |
65 // Note that any type can be used; int, float, std::wstring... | 67 // Note that any type can be used; int, float, std::wstring... |
M-A Ruel
2010/12/10 14:52:18
The second line of the comment shouldn't be at tha
Satish
2010/12/10 17:13:48
I removed this line since it doesn't make sense wi
| |
66 return Singleton<int, DefaultSingletonTraits<int>, | 68 return &IntSingleton::GetInstanceWithDifferentiatingClass()->value_; |
67 DummyDifferentiatingClass>::get(); | |
68 } | 69 } |
69 | 70 |
70 int* SingletonInt4() { | 71 int* SingletonInt4() { |
71 return Singleton<int, LockTrait<int> >::get(); | 72 return &IntSingleton::GetInstanceWithLockTrait()->value_; |
72 } | 73 } |
73 | 74 |
74 int* SingletonInt5() { | 75 int* SingletonInt5() { |
75 return Singleton<int, Init5Trait>::get(); | 76 return &IntSingleton::GetInstanceWithInit5Trait()->value_; |
77 } | |
78 | |
79 class CallbackSingleton { | |
80 public: | |
81 struct CallbackTrait : public DefaultSingletonTraits<CallbackSingleton> { | |
82 static void Delete(CallbackSingleton* instance) { | |
83 if (instance->callback_) | |
84 (instance->callback_)(); | |
85 DefaultSingletonTraits<CallbackSingleton>::Delete(instance); | |
86 } | |
87 }; | |
88 | |
89 struct NoLeakTrait : public CallbackTrait { | |
90 }; | |
91 | |
92 struct LeakTrait : public CallbackTrait { | |
93 static const bool kRegisterAtExit = false; | |
94 }; | |
95 | |
96 CallbackSingleton() : callback_(NULL) { | |
97 } | |
98 | |
99 static CallbackSingleton* GetInstanceWithNoLeakTrait() { | |
100 return Singleton<CallbackSingleton, NoLeakTrait>::get(); | |
101 } | |
102 static CallbackSingleton* GetInstanceWithLeakTrait() { | |
103 return Singleton<CallbackSingleton, LeakTrait>::get(); | |
104 } | |
105 static CallbackSingleton* GetInstanceWithStaticTrait(); | |
106 | |
107 CallbackFunc callback_; | |
108 }; | |
109 | |
110 struct StaticCallbackTrait | |
111 : public StaticMemorySingletonTraits<CallbackSingleton> { | |
112 static void Delete(CallbackSingleton* instance) { | |
113 if (instance->callback_) | |
114 (instance->callback_)(); | |
115 StaticMemorySingletonTraits<CallbackSingleton>::Delete(instance); | |
116 } | |
117 }; | |
118 | |
119 CallbackSingleton* CallbackSingleton::GetInstanceWithStaticTrait() { | |
120 return Singleton<CallbackSingleton, StaticCallbackTrait>::get(); | |
76 } | 121 } |
77 | 122 |
78 void SingletonNoLeak(CallbackFunc CallOnQuit) { | 123 void SingletonNoLeak(CallbackFunc CallOnQuit) { |
79 *Singleton<CallbackFunc, NoLeakTrait>::get() = CallOnQuit; | 124 CallbackSingleton::GetInstanceWithNoLeakTrait()->callback_ = CallOnQuit; |
80 } | 125 } |
81 | 126 |
82 void SingletonLeak(CallbackFunc CallOnQuit) { | 127 void SingletonLeak(CallbackFunc CallOnQuit) { |
83 *Singleton<CallbackFunc, LeakTrait>::get() = CallOnQuit; | 128 CallbackSingleton::GetInstanceWithLeakTrait()->callback_ = CallOnQuit; |
84 } | 129 } |
85 | 130 |
86 CallbackFunc* GetLeakySingleton() { | 131 CallbackFunc* GetLeakySingleton() { |
87 return Singleton<CallbackFunc, LeakTrait>::get(); | 132 return &CallbackSingleton::GetInstanceWithLeakTrait()->callback_; |
88 } | 133 } |
89 | 134 |
90 void SingletonStatic(CallbackFunc CallOnQuit) { | 135 void SingletonStatic(CallbackFunc CallOnQuit) { |
91 *Singleton<CallbackFunc, StaticCallbackTrait>::get() = CallOnQuit; | 136 CallbackSingleton::GetInstanceWithStaticTrait()->callback_ = CallOnQuit; |
92 } | 137 } |
93 | 138 |
94 CallbackFunc* GetStaticSingleton() { | 139 CallbackFunc* GetStaticSingleton() { |
95 return Singleton<CallbackFunc, StaticCallbackTrait>::get(); | 140 return &CallbackSingleton::GetInstanceWithStaticTrait()->callback_; |
96 } | 141 } |
97 | 142 |
98 } // namespace | 143 } // namespace |
99 | 144 |
100 class SingletonTest : public testing::Test { | 145 class SingletonTest : public testing::Test { |
101 public: | 146 public: |
102 SingletonTest() { } | 147 SingletonTest() { } |
103 | 148 |
104 virtual void SetUp() { | 149 virtual void SetUp() { |
105 non_leak_called_ = false; | 150 non_leak_called_ = false; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 singleton_int_1 = SingletonInt1(); | 273 singleton_int_1 = SingletonInt1(); |
229 EXPECT_EQ(*singleton_int_1, 0); | 274 EXPECT_EQ(*singleton_int_1, 0); |
230 } | 275 } |
231 { | 276 { |
232 singleton_int_5 = SingletonInt5(); | 277 singleton_int_5 = SingletonInt5(); |
233 EXPECT_EQ(*singleton_int_5, 5); | 278 EXPECT_EQ(*singleton_int_5, 5); |
234 } | 279 } |
235 { | 280 { |
236 // Resurrect the static singleton, and assert that it | 281 // Resurrect the static singleton, and assert that it |
237 // still points to the same (static) memory. | 282 // still points to the same (static) memory. |
238 StaticMemorySingletonTraits<CallbackFunc>::Resurrect(); | 283 StaticMemorySingletonTraits<CallbackSingleton>::Resurrect(); |
239 EXPECT_EQ(GetStaticSingleton(), static_singleton); | 284 EXPECT_EQ(GetStaticSingleton(), static_singleton); |
240 } | 285 } |
241 } | 286 } |
242 // The leaky singleton shouldn't leak since SingletonLeak has not been called. | 287 // The leaky singleton shouldn't leak since SingletonLeak has not been called. |
243 VerifiesCallbacksNotCalled(); | 288 VerifiesCallbacksNotCalled(); |
244 } | 289 } |
OLD | NEW |