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/simple_thread.h"
9 #include "testing/gtest/include/gtest/gtest.h"
13 base::AtomicSequenceNumber
constructed_seq_(base::LINKER_INITIALIZED
);
14 base::AtomicSequenceNumber
destructed_seq_(base::LINKER_INITIALIZED
);
16 class ConstructAndDestructLogger
{
18 ConstructAndDestructLogger() {
19 constructed_seq_
.GetNext();
21 ~ConstructAndDestructLogger() {
22 destructed_seq_
.GetNext();
26 class SlowConstructor
{
28 SlowConstructor() : some_int_(0) {
29 PlatformThread::Sleep(1000); // Sleep for 1 second to try to cause a race.
33 int some_int() const { return some_int_
; }
35 static int constructed
;
40 int SlowConstructor::constructed
= 0;
42 class SlowDelegate
: public base::DelegateSimpleThread::Delegate
{
44 explicit SlowDelegate(base::LazyInstance
<SlowConstructor
>* lazy
)
48 EXPECT_EQ(12, lazy_
->Get().some_int());
49 EXPECT_EQ(12, lazy_
->Pointer()->some_int());
53 base::LazyInstance
<SlowConstructor
>* lazy_
;
58 static base::LazyInstance
<ConstructAndDestructLogger
> lazy_logger(
59 base::LINKER_INITIALIZED
);
61 TEST(LazyInstanceTest
, Basic
) {
63 base::ShadowingAtExitManager shadow
;
65 EXPECT_EQ(0, constructed_seq_
.GetNext());
66 EXPECT_EQ(0, destructed_seq_
.GetNext());
69 EXPECT_EQ(2, constructed_seq_
.GetNext());
70 EXPECT_EQ(1, destructed_seq_
.GetNext());
72 lazy_logger
.Pointer();
73 EXPECT_EQ(3, constructed_seq_
.GetNext());
74 EXPECT_EQ(2, destructed_seq_
.GetNext());
76 EXPECT_EQ(4, constructed_seq_
.GetNext());
77 EXPECT_EQ(4, destructed_seq_
.GetNext());
80 static base::LazyInstance
<SlowConstructor
> lazy_slow(base::LINKER_INITIALIZED
);
82 TEST(LazyInstanceTest
, ConstructorThreadSafety
) {
84 base::ShadowingAtExitManager shadow
;
86 SlowDelegate
delegate(&lazy_slow
);
87 EXPECT_EQ(0, SlowConstructor::constructed
);
89 base::DelegateSimpleThreadPool
pool("lazy_instance_cons", 5);
90 pool
.AddWork(&delegate
, 20);
91 EXPECT_EQ(0, SlowConstructor::constructed
);
95 EXPECT_EQ(1, SlowConstructor::constructed
);