YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/gutil/singleton.h
Line
Count
Source
1
// Copyright 2003 Google Inc.
2
//
3
// The Singleton<Type> class manages a single instance of Type which will be
4
// created on first use and (usually) never destroyed.
5
//
6
//   MyClass* ptr = Singleton<MyClass>::get()
7
//   ptr->DoSomething();
8
//
9
// Singleton<> has no non-static members and is never actually instantiated.
10
//
11
// WARNING: Read go/singletons before using.
12
//
13
// This class is thread safe; the constructor will be run at most once, and
14
// no user will gain access to the object until the constructor is completed.
15
// The underlying Type must of course be thread-safe if you want to use it
16
// concurrently.
17
//
18
// If you want to ensure that your class can only exist as a singleton, make
19
// its constructors private, and make Singleton<> a friend:
20
//
21
//   class MySingletonOnlyClass {
22
//    public:
23
//     void DoSomething() { ... }
24
//    private:
25
//     DISALLOW_COPY_AND_ASSIGN(MySingletonOnlyClass);
26
//     MySingletonOnlyClass() { ... }
27
//     friend class Singleton<MySingletonOnlyClass>;
28
//   }
29
//
30
// If your singleton requires complex initialization, or does not have a
31
// suitable default constructor, you can provide a specialization of
32
// Singleton<Type>::CreateInstance() to perform the appropriate setup, e.g.:
33
//
34
//   template <>
35
//   Type* Singleton<VirtualType>::CreateInstance() { return new ConcreteImpl; }
36
//
37
// If you want to initialize something eagerly at startup, rather than lazily
38
// upon use, consider using REGISTER_MODULE_INITIALIZER (in base/googleinit.h).
39
//
40
// This class also allows users to pick a particular instance as the
41
// singleton with InjectInstance(). This enables unittesting and
42
// dependency injection. It must only be used at program startup.
43
//
44
// Caveats:
45
// (a) The instance is normally never destroyed.  Destroying a Singleton is
46
//     complex and error-prone; C++ books go on about this at great length,
47
//     and I have seen no perfect general solution to the problem.
48
//     We *do* offer UnsafeReset() which is not thread-safe at all.
49
//
50
// (b) Your class must have a default (no-argument) constructor, or you must
51
//     provide a specialization for Singleton<Type>::CreateInstance().
52
//
53
// (c) Your class's constructor must never throw an exception.
54
//
55
// Singleton::get() is very fast - about 1ns on a 2.4GHz Core 2.
56
57
//
58
// The following only applies to changes made to this file as part of YugaByte development.
59
//
60
// Portions Copyright (c) YugaByte, Inc.
61
//
62
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
63
// in compliance with the License.  You may obtain a copy of the License at
64
//
65
// http://www.apache.org/licenses/LICENSE-2.0
66
//
67
// Unless required by applicable law or agreed to in writing, software distributed under the License
68
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
69
// or implied.  See the License for the specific language governing permissions and limitations
70
// under the License.
71
//
72
#ifndef YB_GUTIL_SINGLETON_H
73
#define YB_GUTIL_SINGLETON_H
74
75
#include <stddef.h>
76
77
#include <glog/logging.h>
78
79
#include "yb/gutil/once.h"
80
81
namespace util {
82
namespace gtl {
83
template <typename SingletonType> class ScopedSingletonOverride;
84
template <typename SingletonType> class ScopedSingletonOverrideNoDelete;
85
}  // namespace gtl
86
}  // namespace util
87
88
template <typename Type>
89
class Singleton {
90
 public:
91
  // Return a pointer to the one true instance of the class.
92
155M
  static Type* get() {
93
155M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
155M
    return instance_;
95
155M
  }
Singleton<yb::HeapBufferAllocator>::get()
Line
Count
Source
92
27.9M
  static Type* get() {
93
27.9M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
27.9M
    return instance_;
95
27.9M
  }
Singleton<yb::TypeInfoResolver>::get()
Line
Count
Source
92
108M
  static Type* get() {
93
108M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
108M
    return instance_;
95
108M
  }
external_mini_cluster.cc:Singleton<yb::(anonymous namespace)::GlobalLogTailerState>::get()
Line
Count
Source
92
20.2k
  static Type* get() {
93
20.2k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
20.2k
    return instance_;
95
20.2k
  }
local_tablet_writer.cc:Singleton<yb::tablet::(anonymous namespace)::AutoIncrementingCounter>::get()
Line
Count
Source
92
96.0k
  static Type* get() {
93
96.0k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
96.0k
    return instance_;
95
96.0k
  }
Singleton<yb::EncoderResolver<yb::faststring> >::get()
Line
Count
Source
92
39.5k
  static Type* get() {
93
39.5k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
39.5k
    return instance_;
95
39.5k
  }
Singleton<yb::EncoderResolver<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::get()
Line
Count
Source
92
8.49k
  static Type* get() {
93
8.49k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
8.49k
    return instance_;
95
8.49k
  }
Singleton<yb::debug::TraceLog>::get()
Line
Count
Source
92
1.93M
  static Type* get() {
93
1.93M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
1.93M
    return instance_;
95
1.93M
  }
Singleton<yb::debug::TraceEventSyntheticDelayRegistry>::get()
Line
Count
Source
92
52
  static Type* get() {
93
52
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
52
    return instance_;
95
52
  }
Singleton<yb::flag_tags_internal::FlagTagRegistry>::get()
Line
Count
Source
92
16.6M
  static Type* get() {
93
16.6M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
16.6M
    return instance_;
95
16.6M
  }
Singleton<yb::docdb::DocPgTypeAnalyzer>::get()
Line
Count
Source
92
108k
  static Type* get() {
93
108k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
108k
    return instance_;
95
108k
  }
96
97
  // WARNING!!!  This function is not thread-safe and may leak memory.
98
  static void UnsafeReset() {
99
    delete instance_;
100
    instance_ = NULL;
101
    once_.state = GOOGLE_ONCE_INTERNAL_INIT;  // This is the bad part!
102
  }
103
104
  // This function is used to replace the instance used by
105
  // Singleton<Type>::get(). It can be used for breaking dependencies.  For
106
  // unittesting, you probably want to use ScopedSingletonOverride instead.
107
  //
108
  // This function must be called before Singleton<Type>::get() is
109
  // called and before any threads are created. If these assumptions
110
  // are violated, anything could happen, but we try to crash in debug
111
  // mode and do nothing in production.
112
  static void InjectInstance(Type* instance) {
113
    injected_instance_ = instance;
114
    GoogleOnceInit(&once_, &Singleton<Type>::Inject);
115
    injected_instance_ = NULL;  // Helps detect leaks in the unittest.
116
    if (instance_ != instance) {
117
      LOG(DFATAL) << "(jyasskin) InjectInstance() must be called at most once"
118
                  << " at the start of the program, before the Singleton has"
119
                  << " been accessed and before any threads have been created."
120
                  << " Ignoring the call in production.";
121
      delete instance;
122
    }
123
  }
124
125
 private:
126
  friend class util::gtl::ScopedSingletonOverride<Type>;
127
  friend class util::gtl::ScopedSingletonOverrideNoDelete<Type>;
128
129
  // Create the instance.
130
98.6k
  static void Init() {
131
98.6k
    instance_ = CreateInstance();
132
98.6k
  }
Singleton<yb::HeapBufferAllocator>::Init()
Line
Count
Source
130
8.70k
  static void Init() {
131
8.70k
    instance_ = CreateInstance();
132
8.70k
  }
Singleton<yb::TypeInfoResolver>::Init()
Line
Count
Source
130
21.8k
  static void Init() {
131
21.8k
    instance_ = CreateInstance();
132
21.8k
  }
external_mini_cluster.cc:Singleton<yb::(anonymous namespace)::GlobalLogTailerState>::Init()
Line
Count
Source
130
439
  static void Init() {
131
439
    instance_ = CreateInstance();
132
439
  }
local_tablet_writer.cc:Singleton<yb::tablet::(anonymous namespace)::AutoIncrementingCounter>::Init()
Line
Count
Source
130
54
  static void Init() {
131
54
    instance_ = CreateInstance();
132
54
  }
Singleton<yb::EncoderResolver<yb::faststring> >::Init()
Line
Count
Source
130
2.30k
  static void Init() {
131
2.30k
    instance_ = CreateInstance();
132
2.30k
  }
Singleton<yb::EncoderResolver<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::Init()
Line
Count
Source
130
8.01k
  static void Init() {
131
8.01k
    instance_ = CreateInstance();
132
8.01k
  }
Singleton<yb::debug::TraceLog>::Init()
Line
Count
Source
130
23.8k
  static void Init() {
131
23.8k
    instance_ = CreateInstance();
132
23.8k
  }
Singleton<yb::debug::TraceEventSyntheticDelayRegistry>::Init()
Line
Count
Source
130
25
  static void Init() {
131
25
    instance_ = CreateInstance();
132
25
  }
Singleton<yb::flag_tags_internal::FlagTagRegistry>::Init()
Line
Count
Source
130
32.7k
  static void Init() {
131
32.7k
    instance_ = CreateInstance();
132
32.7k
  }
Singleton<yb::docdb::DocPgTypeAnalyzer>::Init()
Line
Count
Source
130
743
  static void Init() {
131
743
    instance_ = CreateInstance();
132
743
  }
133
134
  // Create and return the instance. You can use Singleton for objects which
135
  // require more complex setup by defining a specialization for your type.
136
98.6k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
98.6k
    return ::new Type;
139
98.6k
  }
Singleton<yb::HeapBufferAllocator>::CreateInstance()
Line
Count
Source
136
8.70k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
8.70k
    return ::new Type;
139
8.70k
  }
Singleton<yb::TypeInfoResolver>::CreateInstance()
Line
Count
Source
136
21.8k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
21.8k
    return ::new Type;
139
21.8k
  }
external_mini_cluster.cc:Singleton<yb::(anonymous namespace)::GlobalLogTailerState>::CreateInstance()
Line
Count
Source
136
439
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
439
    return ::new Type;
139
439
  }
local_tablet_writer.cc:Singleton<yb::tablet::(anonymous namespace)::AutoIncrementingCounter>::CreateInstance()
Line
Count
Source
136
54
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
54
    return ::new Type;
139
54
  }
Singleton<yb::EncoderResolver<yb::faststring> >::CreateInstance()
Line
Count
Source
136
2.30k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
2.30k
    return ::new Type;
139
2.30k
  }
Singleton<yb::EncoderResolver<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::CreateInstance()
Line
Count
Source
136
8.01k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
8.01k
    return ::new Type;
139
8.01k
  }
Singleton<yb::debug::TraceLog>::CreateInstance()
Line
Count
Source
136
23.8k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
23.8k
    return ::new Type;
139
23.8k
  }
Singleton<yb::debug::TraceEventSyntheticDelayRegistry>::CreateInstance()
Line
Count
Source
136
25
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
25
    return ::new Type;
139
25
  }
Singleton<yb::flag_tags_internal::FlagTagRegistry>::CreateInstance()
Line
Count
Source
136
32.7k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
32.7k
    return ::new Type;
139
32.7k
  }
Singleton<yb::docdb::DocPgTypeAnalyzer>::CreateInstance()
Line
Count
Source
136
743
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
743
    return ::new Type;
139
743
  }
140
141
  // Inject the instance.
142
  static void Inject() {
143
    instance_ = injected_instance_;
144
  }
145
146
  // Used by ScopedSingletonOverride.  Definitely not threadsafe.  No one
147
  // should be calling this other than ScopedSingletonOverride (which has
148
  // friend access to do this and makes sure it calls get() first).
149
  static void OverrideSingleton(Type* override_instance) {
150
    instance_ = override_instance;
151
  }
152
153
  static GoogleOnceType once_;
154
  static Type* instance_;
155
  static Type* injected_instance_;
156
};
157
158
template <typename Type>
159
GoogleOnceType Singleton<Type>::once_ = GOOGLE_ONCE_INIT;
160
161
template <typename Type>
162
Type* Singleton<Type>::instance_ = NULL;
163
164
template <typename Type>
165
Type* Singleton<Type>::injected_instance_ = NULL;
166
167
#endif  // YB_GUTIL_SINGLETON_H