2 * Copyright 2015 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <folly/experimental/Singleton.h>
21 #include <folly/Benchmark.h>
23 #include <glog/logging.h>
24 #include <gtest/gtest.h>
26 using namespace folly;
28 // A simple class that tracks how often instances of the class and
29 // subclasses are created, and the ordering. Also tracks a global
30 // unique counter for each object.
31 std::atomic<size_t> global_counter(19770326);
33 static std::vector<Watchdog*> creation_order;
34 Watchdog() : serial_number(++global_counter) {
35 creation_order.push_back(this);
39 if (creation_order.back() != this) {
40 throw std::out_of_range("Watchdog destruction order mismatch");
42 creation_order.pop_back();
45 const size_t serial_number;
46 size_t livingWatchdogCount() const { return creation_order.size(); }
48 Watchdog(const Watchdog&) = delete;
49 Watchdog& operator=(const Watchdog&) = delete;
50 Watchdog(Watchdog&&) noexcept = default;
53 std::vector<Watchdog*> Watchdog::creation_order;
55 // Some basic types we use for tracking.
56 struct ChildWatchdog : public Watchdog {};
57 struct GlobalWatchdog : public Watchdog {};
58 struct UnregisteredWatchdog : public Watchdog {};
61 Singleton<GlobalWatchdog> global_watchdog;
64 // Test basic global usage (the default way singletons will generally
66 TEST(Singleton, BasicGlobalUsage) {
67 EXPECT_EQ(Watchdog::creation_order.size(), 0);
68 EXPECT_EQ(SingletonVault::singleton()->registeredSingletonCount(), 1);
69 EXPECT_EQ(SingletonVault::singleton()->livingSingletonCount(), 0);
70 auto wd1 = Singleton<GlobalWatchdog>::get();
71 EXPECT_NE(wd1, nullptr);
72 EXPECT_EQ(Watchdog::creation_order.size(), 1);
73 auto wd2 = Singleton<GlobalWatchdog>::get();
74 EXPECT_NE(wd2, nullptr);
76 EXPECT_EQ(Watchdog::creation_order.size(), 1);
77 SingletonVault::singleton()->destroyInstances();
78 EXPECT_EQ(Watchdog::creation_order.size(), 0);
81 TEST(Singleton, MissingSingleton) {
82 EXPECT_THROW([]() { auto u = Singleton<UnregisteredWatchdog>::get(); }(),
86 struct BasicUsageTag {};
87 template <typename T, typename Tag = detail::DefaultTag>
88 using SingletonBasicUsage = Singleton <T, Tag, BasicUsageTag>;
90 // Exercise some basic codepaths ensuring registration order and
91 // destruction order happen as expected, that instances are created
92 // when expected, etc etc.
93 TEST(Singleton, BasicUsage) {
94 auto& vault = *SingletonVault::singleton<BasicUsageTag>();
96 EXPECT_EQ(vault.registeredSingletonCount(), 0);
97 SingletonBasicUsage<Watchdog> watchdog_singleton;
98 EXPECT_EQ(vault.registeredSingletonCount(), 1);
100 SingletonBasicUsage<ChildWatchdog> child_watchdog_singleton;
101 EXPECT_EQ(vault.registeredSingletonCount(), 2);
103 vault.registrationComplete();
105 Watchdog* s1 = SingletonBasicUsage<Watchdog>::get();
106 EXPECT_NE(s1, nullptr);
108 Watchdog* s2 = SingletonBasicUsage<Watchdog>::get();
109 EXPECT_NE(s2, nullptr);
113 auto s3 = SingletonBasicUsage<ChildWatchdog>::get();
114 EXPECT_NE(s3, nullptr);
117 EXPECT_EQ(vault.registeredSingletonCount(), 2);
118 EXPECT_EQ(vault.livingSingletonCount(), 2);
120 vault.destroyInstances();
121 EXPECT_EQ(vault.registeredSingletonCount(), 2);
122 EXPECT_EQ(vault.livingSingletonCount(), 0);
125 struct DirectUsageTag {};
126 template <typename T, typename Tag = detail::DefaultTag>
127 using SingletonDirectUsage = Singleton <T, Tag, DirectUsageTag>;
129 TEST(Singleton, DirectUsage) {
130 auto& vault = *SingletonVault::singleton<DirectUsageTag>();
132 EXPECT_EQ(vault.registeredSingletonCount(), 0);
134 // Verify we can get to the underlying singletons via directly using
135 // the singleton definition.
136 SingletonDirectUsage<Watchdog> watchdog;
138 SingletonDirectUsage<Watchdog, TestTag> named_watchdog;
139 EXPECT_EQ(vault.registeredSingletonCount(), 2);
140 vault.registrationComplete();
142 EXPECT_NE(watchdog.get(), nullptr);
143 EXPECT_EQ(watchdog.get(), SingletonDirectUsage<Watchdog>::get());
144 EXPECT_NE(watchdog.get(), named_watchdog.get());
145 EXPECT_EQ(watchdog->livingWatchdogCount(), 2);
146 EXPECT_EQ((*watchdog).livingWatchdogCount(), 2);
148 vault.destroyInstances();
151 struct NamedUsageTag {};
152 template <typename T, typename Tag = detail::DefaultTag>
153 using SingletonNamedUsage = Singleton <T, Tag, NamedUsageTag>;
155 TEST(Singleton, NamedUsage) {
156 auto& vault = *SingletonVault::singleton<NamedUsageTag>();
158 EXPECT_EQ(vault.registeredSingletonCount(), 0);
160 // Define two named Watchdog singletons and one unnamed singleton.
163 typedef detail::DefaultTag Watchdog3;
164 SingletonNamedUsage<Watchdog, Watchdog1> watchdog1_singleton;
165 EXPECT_EQ(vault.registeredSingletonCount(), 1);
166 SingletonNamedUsage<Watchdog, Watchdog2> watchdog2_singleton;
167 EXPECT_EQ(vault.registeredSingletonCount(), 2);
168 SingletonNamedUsage<Watchdog, Watchdog3> watchdog3_singleton;
169 EXPECT_EQ(vault.registeredSingletonCount(), 3);
171 vault.registrationComplete();
173 // Verify our three singletons are distinct and non-nullptr.
174 Watchdog* s1 = SingletonNamedUsage<Watchdog, Watchdog1>::get();
175 EXPECT_EQ(s1, watchdog1_singleton.get());
176 Watchdog* s2 = SingletonNamedUsage<Watchdog, Watchdog2>::get();
177 EXPECT_EQ(s2, watchdog2_singleton.get());
179 Watchdog* s3 = SingletonNamedUsage<Watchdog, Watchdog3>::get();
180 EXPECT_EQ(s3, watchdog3_singleton.get());
184 // Verify the "default" singleton is the same as the DefaultTag-tagged
186 Watchdog* s4 = SingletonNamedUsage<Watchdog>::get();
187 EXPECT_EQ(s4, watchdog3_singleton.get());
189 vault.destroyInstances();
192 struct NaughtyUsageTag {};
193 template <typename T, typename Tag = detail::DefaultTag>
194 using SingletonNaughtyUsage = Singleton <T, Tag, NaughtyUsageTag>;
195 struct NaughtyUsageTag2 {};
196 template <typename T, typename Tag = detail::DefaultTag>
197 using SingletonNaughtyUsage2 = Singleton <T, Tag, NaughtyUsageTag2>;
199 // Some pathological cases such as getting unregistered singletons,
200 // double registration, etc.
201 TEST(Singleton, NaughtyUsage) {
202 auto& vault = *SingletonVault::singleton<NaughtyUsageTag>();
204 vault.registrationComplete();
207 EXPECT_THROW(Singleton<Watchdog>::get(), std::out_of_range);
208 EXPECT_THROW(SingletonNaughtyUsage<Watchdog>::get(), std::out_of_range);
210 vault.destroyInstances();
212 auto& vault2 = *SingletonVault::singleton<NaughtyUsageTag2>();
214 EXPECT_THROW(SingletonNaughtyUsage2<Watchdog>::get(), std::logic_error);
215 SingletonNaughtyUsage2<Watchdog> watchdog_singleton;
216 // double registration
218 SingletonNaughtyUsage2<Watchdog> watchdog_singleton;
221 vault2.destroyInstances();
222 // double registration after destroy
224 SingletonNaughtyUsage2<Watchdog> watchdog_singleton;
229 struct SharedPtrUsageTag {};
230 template <typename T, typename Tag = detail::DefaultTag>
231 using SingletonSharedPtrUsage = Singleton <T, Tag, SharedPtrUsageTag>;
233 TEST(Singleton, SharedPtrUsage) {
234 struct WatchdogHolder {
237 LOG(ERROR) << "The following log message with stack trace is expected";
241 std::shared_ptr<Watchdog> watchdog;
244 auto& vault = *SingletonVault::singleton<SharedPtrUsageTag>();
246 EXPECT_EQ(vault.registeredSingletonCount(), 0);
247 SingletonSharedPtrUsage<Watchdog> watchdog_singleton;
248 EXPECT_EQ(vault.registeredSingletonCount(), 1);
250 SingletonSharedPtrUsage<ChildWatchdog> child_watchdog_singleton;
251 EXPECT_EQ(vault.registeredSingletonCount(), 2);
254 SingletonSharedPtrUsage<Watchdog, ATag> named_watchdog_singleton;
256 SingletonSharedPtrUsage<WatchdogHolder> watchdog_holder_singleton;
258 vault.registrationComplete();
260 // Initilize holder singleton first, so that it's the last one to be
262 watchdog_holder_singleton.get();
264 Watchdog* s1 = SingletonSharedPtrUsage<Watchdog>::get();
265 EXPECT_NE(s1, nullptr);
267 Watchdog* s2 = SingletonSharedPtrUsage<Watchdog>::get();
268 EXPECT_NE(s2, nullptr);
272 auto weak_s1 = SingletonSharedPtrUsage<Watchdog>::get_weak();
274 auto shared_s1 = weak_s1.lock();
275 EXPECT_EQ(shared_s1.get(), s1);
276 EXPECT_EQ(shared_s1.use_count(), 2);
278 auto old_serial = shared_s1->serial_number;
282 SingletonSharedPtrUsage<Watchdog, ATag>::get_weak();
283 auto locked = named_weak_s1.lock();
284 EXPECT_NE(locked.get(), shared_s1.get());
287 // We should release externally locked shared_ptr, otherwise it will be
289 watchdog_holder_singleton->watchdog = std::move(shared_s1);
291 LOG(ERROR) << "The following log message regarding shared_ptr is expected";
293 auto start_time = std::chrono::steady_clock::now();
294 vault.destroyInstances();
295 auto duration = std::chrono::steady_clock::now() - start_time;
296 EXPECT_TRUE(duration > std::chrono::seconds{4} &&
297 duration < std::chrono::seconds{6});
299 EXPECT_EQ(vault.registeredSingletonCount(), 4);
300 EXPECT_EQ(vault.livingSingletonCount(), 0);
302 EXPECT_TRUE(weak_s1.expired());
304 auto empty_s1 = SingletonSharedPtrUsage<Watchdog>::get_weak();
305 EXPECT_FALSE(empty_s1.lock());
307 vault.reenableInstances();
309 // Singleton should be re-created only after reenableInstances() was called.
310 Watchdog* new_s1 = SingletonSharedPtrUsage<Watchdog>::get();
311 // Track serial number rather than pointer since the memory could be
312 // re-used when we create new_s1.
313 EXPECT_NE(new_s1->serial_number, old_serial);
315 auto new_s1_weak = SingletonSharedPtrUsage<Watchdog>::get_weak();
316 auto new_s1_shared = new_s1_weak.lock();
317 std::thread t([new_s1_shared]() mutable {
318 std::this_thread::sleep_for(std::chrono::seconds{2});
319 new_s1_shared.reset();
321 new_s1_shared.reset();
323 auto start_time = std::chrono::steady_clock::now();
324 vault.destroyInstances();
325 auto duration = std::chrono::steady_clock::now() - start_time;
326 EXPECT_TRUE(duration > std::chrono::seconds{1} &&
327 duration < std::chrono::seconds{3});
329 EXPECT_TRUE(new_s1_weak.expired());
333 // Some classes to test singleton dependencies. NeedySingleton has a
334 // dependency on NeededSingleton, which happens during its
337 template <typename T, typename Tag = detail::DefaultTag>
338 using SingletonNeedy = Singleton <T, Tag, NeedyTag>;
340 struct NeededSingleton {};
341 struct NeedySingleton {
343 auto unused = SingletonNeedy<NeededSingleton>::get();
344 EXPECT_NE(unused, nullptr);
348 // Ensure circular dependencies fail -- a singleton that needs itself, whoops.
349 struct SelfNeedyTag {};
350 template <typename T, typename Tag = detail::DefaultTag>
351 using SingletonSelfNeedy = Singleton <T, Tag, SelfNeedyTag>;
353 struct SelfNeedySingleton {
354 SelfNeedySingleton() {
355 auto unused = SingletonSelfNeedy<SelfNeedySingleton>::get();
356 EXPECT_NE(unused, nullptr);
360 TEST(Singleton, SingletonDependencies) {
361 SingletonNeedy<NeededSingleton> needed_singleton;
362 SingletonNeedy<NeedySingleton> needy_singleton;
363 auto& needy_vault = *SingletonVault::singleton<NeedyTag>();
365 needy_vault.registrationComplete();
367 EXPECT_EQ(needy_vault.registeredSingletonCount(), 2);
368 EXPECT_EQ(needy_vault.livingSingletonCount(), 0);
370 auto needy = SingletonNeedy<NeedySingleton>::get();
371 EXPECT_EQ(needy_vault.livingSingletonCount(), 2);
373 SingletonSelfNeedy<SelfNeedySingleton> self_needy_singleton;
374 auto& self_needy_vault = *SingletonVault::singleton<SelfNeedyTag>();
376 self_needy_vault.registrationComplete();
378 SingletonSelfNeedy<SelfNeedySingleton>::get();
383 // A test to ensure multiple threads contending on singleton creation
384 // properly wait for creation rather than thinking it is a circular
386 class Slowpoke : public Watchdog {
388 Slowpoke() { std::this_thread::sleep_for(std::chrono::milliseconds(10)); }
391 struct ConcurrencyTag {};
392 template <typename T, typename Tag = detail::DefaultTag>
393 using SingletonConcurrency = Singleton <T, Tag, ConcurrencyTag>;
395 TEST(Singleton, SingletonConcurrency) {
396 auto& vault = *SingletonVault::singleton<ConcurrencyTag>();
397 SingletonConcurrency<Slowpoke> slowpoke_singleton;
398 vault.registrationComplete();
400 std::mutex gatekeeper;
402 auto func = [&gatekeeper]() {
405 auto unused = SingletonConcurrency<Slowpoke>::get();
408 EXPECT_EQ(vault.livingSingletonCount(), 0);
409 std::vector<std::thread> threads;
410 for (int i = 0; i < 100; ++i) {
411 threads.emplace_back(func);
413 // If circular dependency checks fail, the unlock would trigger a
414 // crash. Instead, it succeeds, and we have exactly one living
417 for (auto& t : threads) {
420 EXPECT_EQ(vault.livingSingletonCount(), 1);
423 struct ConcurrencyStressTag {};
424 template <typename T, typename Tag = detail::DefaultTag>
425 using SingletonConcurrencyStress = Singleton <T, Tag, ConcurrencyStressTag>;
427 TEST(Singleton, SingletonConcurrencyStress) {
428 auto& vault = *SingletonVault::singleton<ConcurrencyStressTag>();
429 SingletonConcurrencyStress<Slowpoke> slowpoke_singleton;
431 std::vector<std::thread> ts;
432 for (size_t i = 0; i < 100; ++i) {
433 ts.emplace_back([&]() {
434 slowpoke_singleton.get_weak().lock();
438 for (size_t i = 0; i < 100; ++i) {
439 std::chrono::milliseconds d(20);
441 std::this_thread::sleep_for(d);
442 vault.destroyInstances();
443 std::this_thread::sleep_for(d);
444 vault.destroyInstances();
452 // Benchmarking a normal singleton vs a Meyers singleton vs a Folly
453 // singleton. Meyers are insanely fast, but (hopefully) Folly
454 // singletons are fast "enough."
455 int* getMeyersSingleton() {
456 static auto ret = new int(0);
460 int normal_singleton_value = 0;
461 int* getNormalSingleton() {
462 doNotOptimizeAway(&normal_singleton_value);
463 return &normal_singleton_value;
467 template <typename T, typename Tag = detail::DefaultTag>
468 using SingletonMock = Singleton <T, Tag, MockTag>;
470 // Verify that existing Singleton's can be overridden
471 // using the make_mock functionality.
472 TEST(Singleton, MockTest) {
473 auto& vault = *SingletonVault::singleton<MockTag>();
475 SingletonMock<Watchdog> watchdog_singleton;
476 vault.registrationComplete();
478 // Registring singletons after registrationComplete called works
479 // with make_mock (but not with Singleton ctor).
480 EXPECT_EQ(vault.registeredSingletonCount(), 1);
481 int serial_count_first = SingletonMock<Watchdog>::get()->serial_number;
483 // Override existing mock using make_mock.
484 SingletonMock<Watchdog>::make_mock();
486 EXPECT_EQ(vault.registeredSingletonCount(), 1);
487 int serial_count_mock = SingletonMock<Watchdog>::get()->serial_number;
489 // If serial_count value is the same, then singleton was not replaced.
490 EXPECT_NE(serial_count_first, serial_count_mock);
493 struct BenchmarkSingleton {
497 BENCHMARK(NormalSingleton, n) {
498 for (size_t i = 0; i < n; ++i) {
499 doNotOptimizeAway(getNormalSingleton());
503 BENCHMARK_RELATIVE(MeyersSingleton, n) {
504 for (size_t i = 0; i < n; ++i) {
505 doNotOptimizeAway(getMeyersSingleton());
509 struct BenchmarkTag {};
510 template <typename T, typename Tag = detail::DefaultTag>
511 using SingletonBenchmark = Singleton <T, Tag, BenchmarkTag>;
516 SingletonBenchmark<BenchmarkSingleton, GetTag> benchmark_singleton_get;
517 SingletonBenchmark<BenchmarkSingleton, GetWeakTag> benchmark_singleton_get_weak;
519 BENCHMARK_RELATIVE(FollySingleton, n) {
520 for (size_t i = 0; i < n; ++i) {
521 doNotOptimizeAway(SingletonBenchmark<BenchmarkSingleton, GetTag>::get());
525 BENCHMARK_RELATIVE(FollySingletonWeak, n) {
526 for (size_t i = 0; i < n; ++i) {
527 SingletonBenchmark<BenchmarkSingleton, GetWeakTag>::get_weak();
531 int main(int argc, char* argv[]) {
532 testing::InitGoogleTest(&argc, argv);
533 google::InitGoogleLogging(argv[0]);
534 google::ParseCommandLineFlags(&argc, &argv, true);
536 SingletonVault::singleton()->registrationComplete();
538 auto ret = RUN_ALL_TESTS();
540 folly::runBenchmarksOnFlag();