Updating trunk VERSION from 833.0 to 834.0
[chromium-blink-merge.git] / base / lazy_instance_unittest.cc
blob28bf04ebb4238ba45e294f90e9559beb5e38f6ab
1 // Copyright (c) 2008 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 "base/at_exit.h"
6 #include "base/atomic_sequence_num.h"
7 #include "base/lazy_instance.h"
8 #include "base/threading/simple_thread.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace {
13 base::AtomicSequenceNumber constructed_seq_(base::LINKER_INITIALIZED);
14 base::AtomicSequenceNumber destructed_seq_(base::LINKER_INITIALIZED);
16 class ConstructAndDestructLogger {
17 public:
18 ConstructAndDestructLogger() {
19 constructed_seq_.GetNext();
21 ~ConstructAndDestructLogger() {
22 destructed_seq_.GetNext();
26 class SlowConstructor {
27 public:
28 SlowConstructor() : some_int_(0) {
29 // Sleep for 1 second to try to cause a race.
30 base::PlatformThread::Sleep(1000);
31 ++constructed;
32 some_int_ = 12;
34 int some_int() const { return some_int_; }
36 static int constructed;
37 private:
38 int some_int_;
41 int SlowConstructor::constructed = 0;
43 class SlowDelegate : public base::DelegateSimpleThread::Delegate {
44 public:
45 explicit SlowDelegate(base::LazyInstance<SlowConstructor>* lazy)
46 : lazy_(lazy) {}
48 virtual void Run() {
49 EXPECT_EQ(12, lazy_->Get().some_int());
50 EXPECT_EQ(12, lazy_->Pointer()->some_int());
53 private:
54 base::LazyInstance<SlowConstructor>* lazy_;
57 } // namespace
59 static base::LazyInstance<ConstructAndDestructLogger> lazy_logger(
60 base::LINKER_INITIALIZED);
62 TEST(LazyInstanceTest, Basic) {
64 base::ShadowingAtExitManager shadow;
66 EXPECT_EQ(0, constructed_seq_.GetNext());
67 EXPECT_EQ(0, destructed_seq_.GetNext());
69 lazy_logger.Get();
70 EXPECT_EQ(2, constructed_seq_.GetNext());
71 EXPECT_EQ(1, destructed_seq_.GetNext());
73 lazy_logger.Pointer();
74 EXPECT_EQ(3, constructed_seq_.GetNext());
75 EXPECT_EQ(2, destructed_seq_.GetNext());
77 EXPECT_EQ(4, constructed_seq_.GetNext());
78 EXPECT_EQ(4, destructed_seq_.GetNext());
81 static base::LazyInstance<SlowConstructor> lazy_slow(base::LINKER_INITIALIZED);
83 TEST(LazyInstanceTest, ConstructorThreadSafety) {
85 base::ShadowingAtExitManager shadow;
87 SlowDelegate delegate(&lazy_slow);
88 EXPECT_EQ(0, SlowConstructor::constructed);
90 base::DelegateSimpleThreadPool pool("lazy_instance_cons", 5);
91 pool.AddWork(&delegate, 20);
92 EXPECT_EQ(0, SlowConstructor::constructed);
94 pool.Start();
95 pool.JoinAll();
96 EXPECT_EQ(1, SlowConstructor::constructed);
100 namespace {
102 // DeleteLogger is an object which sets a flag when it's destroyed.
103 // It accepts a bool* and sets the bool to true when the dtor runs.
104 class DeleteLogger {
105 public:
106 DeleteLogger() : deleted_(NULL) {}
107 ~DeleteLogger() { *deleted_ = true; }
109 void SetDeletedPtr(bool* deleted) {
110 deleted_ = deleted;
113 private:
114 bool* deleted_;
117 } // anonymous namespace
119 TEST(LazyInstanceTest, LeakyLazyInstance) {
120 // Check that using a plain LazyInstance causes the dtor to run
121 // when the AtExitManager finishes.
122 bool deleted1 = false;
124 base::ShadowingAtExitManager shadow;
125 static base::LazyInstance<DeleteLogger> test(base::LINKER_INITIALIZED);
126 test.Get().SetDeletedPtr(&deleted1);
128 EXPECT_TRUE(deleted1);
130 // Check that using a *leaky* LazyInstance makes the dtor not run
131 // when the AtExitManager finishes.
132 bool deleted2 = false;
134 base::ShadowingAtExitManager shadow;
135 static base::LazyInstance<DeleteLogger,
136 base::LeakyLazyInstanceTraits<DeleteLogger> >
137 test(base::LINKER_INITIALIZED);
138 test.Get().SetDeletedPtr(&deleted2);
140 EXPECT_FALSE(deleted2);