Index: base/singleton_unittest.cc |
diff --git a/base/singleton_unittest.cc b/base/singleton_unittest.cc |
index acb1247d96d09ba3f9b18929d419996f3a0baf1c..3d7e7e60d10d5f47e801d5b379aa9dd99be45ffc 100644 |
--- a/base/singleton_unittest.cc |
+++ b/base/singleton_unittest.cc |
@@ -12,87 +12,131 @@ namespace { |
COMPILE_ASSERT(DefaultSingletonTraits<int>::kRegisterAtExit == true, a); |
-template<typename Type> |
-struct LockTrait : public DefaultSingletonTraits<Type> { |
-}; |
+typedef void (*CallbackFunc)(); |
-struct Init5Trait : public DefaultSingletonTraits<int> { |
- static int* New() { |
- return new int(5); |
+class IntSingleton { |
+ public: |
+ static IntSingleton* GetInstance() { |
+ return Singleton<IntSingleton>::get(); |
} |
+ |
+ int value_; |
}; |
-typedef void (*CallbackFunc)(); |
+class Init5Singleton { |
+ public: |
+ struct Trait; |
-struct CallbackTrait : public DefaultSingletonTraits<CallbackFunc> { |
- static void Delete(CallbackFunc* p) { |
- if (*p) |
- (*p)(); |
- DefaultSingletonTraits<CallbackFunc>::Delete(p); |
+ static Init5Singleton* GetInstance() { |
+ return Singleton<Init5Singleton, Trait>::get(); |
} |
+ |
+ int value_; |
}; |
-struct StaticCallbackTrait : public StaticMemorySingletonTraits<CallbackFunc> { |
- static void Delete(CallbackFunc* p) { |
- if (*p) |
- (*p)(); |
- StaticMemorySingletonTraits<CallbackFunc>::Delete(p); |
+struct Init5Singleton::Trait : public DefaultSingletonTraits<Init5Singleton> { |
+ static Init5Singleton* New() { |
+ Init5Singleton* instance = new Init5Singleton(); |
+ instance->value_ = 5; |
+ return instance; |
} |
}; |
+int* SingletonInt() { |
+ return &IntSingleton::GetInstance()->value_; |
+} |
+ |
+int* SingletonInt5() { |
+ return &Init5Singleton::GetInstance()->value_; |
+} |
-struct NoLeakTrait : public CallbackTrait { |
+template <typename Type> |
+struct CallbackTrait : public DefaultSingletonTraits<Type> { |
+ static void Delete(Type* instance) { |
+ if (instance->callback_) |
+ (instance->callback_)(); |
+ DefaultSingletonTraits<Type>::Delete(instance); |
+ } |
}; |
-struct LeakTrait : public CallbackTrait { |
- static const bool kRegisterAtExit = false; |
+class CallbackSingleton { |
+ public: |
+ CallbackSingleton() : callback_(NULL) { } |
+ CallbackFunc callback_; |
}; |
-int* SingletonInt1() { |
- return Singleton<int>::get(); |
-} |
+class CallbackSingletonWithNoLeakTrait : public CallbackSingleton { |
+ public: |
+ struct Trait : public CallbackTrait<CallbackSingletonWithNoLeakTrait> { }; |
-int* SingletonInt2() { |
- // Force to use a different singleton than SingletonInt1. |
- return Singleton<int, DefaultSingletonTraits<int> >::get(); |
-} |
+ CallbackSingletonWithNoLeakTrait() : CallbackSingleton() { } |
-class DummyDifferentiatingClass { |
+ static CallbackSingletonWithNoLeakTrait* GetInstance() { |
+ return Singleton<CallbackSingletonWithNoLeakTrait, Trait>::get(); |
+ } |
}; |
-int* SingletonInt3() { |
- // Force to use a different singleton than SingletonInt1 and SingletonInt2. |
- // Note that any type can be used; int, float, std::wstring... |
- return Singleton<int, DefaultSingletonTraits<int>, |
- DummyDifferentiatingClass>::get(); |
-} |
+class CallbackSingletonWithLeakTrait : public CallbackSingleton { |
+ public: |
+ struct Trait : public CallbackTrait<CallbackSingletonWithLeakTrait> { |
+ static const bool kRegisterAtExit = false; |
+ }; |
-int* SingletonInt4() { |
- return Singleton<int, LockTrait<int> >::get(); |
-} |
+ CallbackSingletonWithLeakTrait() : CallbackSingleton() { } |
+ |
+ static CallbackSingletonWithLeakTrait* GetInstance() { |
+ return Singleton<CallbackSingletonWithLeakTrait, Trait>::get(); |
+ } |
+}; |
+ |
+class CallbackSingletonWithStaticTrait : public CallbackSingleton { |
+ public: |
+ struct Trait; |
+ |
+ CallbackSingletonWithStaticTrait() : CallbackSingleton() { } |
+ |
+ static CallbackSingletonWithStaticTrait* GetInstance() { |
+ return Singleton<CallbackSingletonWithStaticTrait, Trait>::get(); |
+ } |
+}; |
+ |
+struct CallbackSingletonWithStaticTrait::Trait |
+ : public StaticMemorySingletonTraits<CallbackSingletonWithStaticTrait> { |
+ static void Delete(CallbackSingletonWithStaticTrait* instance) { |
+ if (instance->callback_) |
+ (instance->callback_)(); |
+ StaticMemorySingletonTraits<CallbackSingletonWithStaticTrait>::Delete( |
+ instance); |
+ } |
+}; |
-int* SingletonInt5() { |
- return Singleton<int, Init5Trait>::get(); |
-} |
void SingletonNoLeak(CallbackFunc CallOnQuit) { |
- *Singleton<CallbackFunc, NoLeakTrait>::get() = CallOnQuit; |
+ CallbackSingletonWithNoLeakTrait::GetInstance()->callback_ = CallOnQuit; |
} |
void SingletonLeak(CallbackFunc CallOnQuit) { |
- *Singleton<CallbackFunc, LeakTrait>::get() = CallOnQuit; |
+ CallbackSingletonWithLeakTrait::GetInstance()->callback_ = CallOnQuit; |
} |
CallbackFunc* GetLeakySingleton() { |
- return Singleton<CallbackFunc, LeakTrait>::get(); |
+ return &CallbackSingletonWithLeakTrait::GetInstance()->callback_; |
+} |
+ |
+void DeleteLeakySingleton() { |
+ DefaultSingletonTraits<CallbackSingletonWithLeakTrait>::Delete( |
+ CallbackSingletonWithLeakTrait::GetInstance()); |
} |
void SingletonStatic(CallbackFunc CallOnQuit) { |
- *Singleton<CallbackFunc, StaticCallbackTrait>::get() = CallOnQuit; |
+ CallbackSingletonWithStaticTrait::GetInstance()->callback_ = CallOnQuit; |
} |
CallbackFunc* GetStaticSingleton() { |
- return Singleton<CallbackFunc, StaticCallbackTrait>::get(); |
+ return &CallbackSingletonWithStaticTrait::GetInstance()->callback_; |
+} |
+ |
+void ResurrectStaticSingleton() { |
} |
} // namespace |
@@ -149,10 +193,7 @@ bool SingletonTest::leaky_called_ = false; |
bool SingletonTest::static_called_ = false; |
TEST_F(SingletonTest, Basic) { |
- int* singleton_int_1; |
- int* singleton_int_2; |
- int* singleton_int_3; |
- int* singleton_int_4; |
+ int* singleton_int; |
int* singleton_int_5; |
CallbackFunc* leaky_singleton; |
CallbackFunc* static_singleton; |
@@ -160,49 +201,20 @@ TEST_F(SingletonTest, Basic) { |
{ |
base::ShadowingAtExitManager sem; |
{ |
- singleton_int_1 = SingletonInt1(); |
+ singleton_int = SingletonInt(); |
} |
// Ensure POD type initialization. |
- EXPECT_EQ(*singleton_int_1, 0); |
- *singleton_int_1 = 1; |
- |
- EXPECT_EQ(singleton_int_1, SingletonInt1()); |
- EXPECT_EQ(*singleton_int_1, 1); |
- |
- { |
- singleton_int_2 = SingletonInt2(); |
- } |
- // Same instance that 1. |
- EXPECT_EQ(*singleton_int_2, 1); |
- EXPECT_EQ(singleton_int_1, singleton_int_2); |
+ EXPECT_EQ(*singleton_int, 0); |
+ *singleton_int = 1; |
- { |
- singleton_int_3 = SingletonInt3(); |
- } |
- // Different instance than 1 and 2. |
- EXPECT_EQ(*singleton_int_3, 0); |
- EXPECT_NE(singleton_int_1, singleton_int_3); |
- *singleton_int_3 = 3; |
- EXPECT_EQ(*singleton_int_1, 1); |
- EXPECT_EQ(*singleton_int_2, 1); |
- |
- { |
- singleton_int_4 = SingletonInt4(); |
- } |
- // Use a lock for creation. Not really tested at length. |
- EXPECT_EQ(*singleton_int_4, 0); |
- *singleton_int_4 = 4; |
- EXPECT_NE(singleton_int_1, singleton_int_4); |
- EXPECT_NE(singleton_int_3, singleton_int_4); |
+ EXPECT_EQ(singleton_int, SingletonInt()); |
+ EXPECT_EQ(*singleton_int, 1); |
{ |
singleton_int_5 = SingletonInt5(); |
} |
// Is default initialized to 5. |
EXPECT_EQ(*singleton_int_5, 5); |
- EXPECT_NE(singleton_int_1, singleton_int_5); |
- EXPECT_NE(singleton_int_3, singleton_int_5); |
- EXPECT_NE(singleton_int_4, singleton_int_5); |
SingletonNoLeak(&CallbackNoLeak); |
SingletonLeak(&CallbackLeak); |
@@ -216,7 +228,7 @@ TEST_F(SingletonTest, Basic) { |
VerifiesCallbacks(); |
// Delete the leaky singleton. It is interesting to note that Purify does |
// *not* detect the leak when this call is commented out. :( |
- DefaultSingletonTraits<CallbackFunc>::Delete(leaky_singleton); |
+ DeleteLeakySingleton(); |
// The static singleton can't be acquired post-atexit. |
EXPECT_EQ(NULL, GetStaticSingleton()); |
@@ -225,8 +237,8 @@ TEST_F(SingletonTest, Basic) { |
base::ShadowingAtExitManager sem; |
// Verifiy that the variables were reset. |
{ |
- singleton_int_1 = SingletonInt1(); |
- EXPECT_EQ(*singleton_int_1, 0); |
+ singleton_int = SingletonInt(); |
+ EXPECT_EQ(*singleton_int, 0); |
} |
{ |
singleton_int_5 = SingletonInt5(); |
@@ -235,7 +247,7 @@ TEST_F(SingletonTest, Basic) { |
{ |
// Resurrect the static singleton, and assert that it |
// still points to the same (static) memory. |
- StaticMemorySingletonTraits<CallbackFunc>::Resurrect(); |
+ CallbackSingletonWithStaticTrait::Trait::Resurrect(); |
EXPECT_EQ(GetStaticSingleton(), static_singleton); |
} |
} |