YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/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
75.2M
  static Type* get() {
93
75.2M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
75.2M
    return instance_;
95
75.2M
  }
_ZN9SingletonIN2yb19HeapBufferAllocatorEE3getEv
Line
Count
Source
92
3.38M
  static Type* get() {
93
3.38M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
3.38M
    return instance_;
95
3.38M
  }
external_mini_cluster.cc:_ZN9SingletonIN2yb12_GLOBAL__N_120GlobalLogTailerStateEE3getEv
Line
Count
Source
92
10.7k
  static Type* get() {
93
10.7k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
10.7k
    return instance_;
95
10.7k
  }
local_tablet_writer.cc:_ZN9SingletonIN2yb6tablet12_GLOBAL__N_123AutoIncrementingCounterEE3getEv
Line
Count
Source
92
96.1k
  static Type* get() {
93
96.1k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
96.1k
    return instance_;
95
96.1k
  }
_ZN9SingletonIN2yb15EncoderResolverINS0_10faststringEEEE3getEv
Line
Count
Source
92
11.2k
  static Type* get() {
93
11.2k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
11.2k
    return instance_;
95
11.2k
  }
_ZN9SingletonIN2yb15EncoderResolverINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE3getEv
Line
Count
Source
92
5.90k
  static Type* get() {
93
5.90k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
5.90k
    return instance_;
95
5.90k
  }
_ZN9SingletonIN2yb16TypeInfoResolverEE3getEv
Line
Count
Source
92
59.4M
  static Type* get() {
93
59.4M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
59.4M
    return instance_;
95
59.4M
  }
_ZN9SingletonIN2yb5docdb17DocPgTypeAnalyzerEE3getEv
Line
Count
Source
92
49.1k
  static Type* get() {
93
49.1k
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
49.1k
    return instance_;
95
49.1k
  }
_ZN9SingletonIN2yb5debug8TraceLogEE3getEv
Line
Count
Source
92
1.60M
  static Type* get() {
93
1.60M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
1.60M
    return instance_;
95
1.60M
  }
_ZN9SingletonIN2yb5debug32TraceEventSyntheticDelayRegistryEE3getEv
Line
Count
Source
92
52
  static Type* get() {
93
52
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
52
    return instance_;
95
52
  }
_ZN9SingletonIN2yb18flag_tags_internal15FlagTagRegistryEE3getEv
Line
Count
Source
92
10.6M
  static Type* get() {
93
10.6M
    GoogleOnceInit(&once_, &Singleton<Type>::Init);
94
10.6M
    return instance_;
95
10.6M
  }
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
62.1k
  static void Init() {
131
62.1k
    instance_ = CreateInstance();
132
62.1k
  }
_ZN9SingletonIN2yb19HeapBufferAllocatorEE4InitEv
Line
Count
Source
130
5.28k
  static void Init() {
131
5.28k
    instance_ = CreateInstance();
132
5.28k
  }
external_mini_cluster.cc:_ZN9SingletonIN2yb12_GLOBAL__N_120GlobalLogTailerStateEE4InitEv
Line
Count
Source
130
229
  static void Init() {
131
229
    instance_ = CreateInstance();
132
229
  }
local_tablet_writer.cc:_ZN9SingletonIN2yb6tablet12_GLOBAL__N_123AutoIncrementingCounterEE4InitEv
Line
Count
Source
130
54
  static void Init() {
131
54
    instance_ = CreateInstance();
132
54
  }
_ZN9SingletonIN2yb15EncoderResolverINS0_10faststringEEEE4InitEv
Line
Count
Source
130
1.44k
  static void Init() {
131
1.44k
    instance_ = CreateInstance();
132
1.44k
  }
_ZN9SingletonIN2yb15EncoderResolverINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE4InitEv
Line
Count
Source
130
5.43k
  static void Init() {
131
5.43k
    instance_ = CreateInstance();
132
5.43k
  }
_ZN9SingletonIN2yb16TypeInfoResolverEE4InitEv
Line
Count
Source
130
12.4k
  static void Init() {
131
12.4k
    instance_ = CreateInstance();
132
12.4k
  }
_ZN9SingletonIN2yb5docdb17DocPgTypeAnalyzerEE4InitEv
Line
Count
Source
130
428
  static void Init() {
131
428
    instance_ = CreateInstance();
132
428
  }
_ZN9SingletonIN2yb5debug8TraceLogEE4InitEv
Line
Count
Source
130
16.2k
  static void Init() {
131
16.2k
    instance_ = CreateInstance();
132
16.2k
  }
_ZN9SingletonIN2yb5debug32TraceEventSyntheticDelayRegistryEE4InitEv
Line
Count
Source
130
25
  static void Init() {
131
25
    instance_ = CreateInstance();
132
25
  }
_ZN9SingletonIN2yb18flag_tags_internal15FlagTagRegistryEE4InitEv
Line
Count
Source
130
20.6k
  static void Init() {
131
20.6k
    instance_ = CreateInstance();
132
20.6k
  }
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
62.1k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
62.1k
    return ::new Type;
139
62.1k
  }
_ZN9SingletonIN2yb19HeapBufferAllocatorEE14CreateInstanceEv
Line
Count
Source
136
5.28k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
5.28k
    return ::new Type;
139
5.28k
  }
external_mini_cluster.cc:_ZN9SingletonIN2yb12_GLOBAL__N_120GlobalLogTailerStateEE14CreateInstanceEv
Line
Count
Source
136
229
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
229
    return ::new Type;
139
229
  }
local_tablet_writer.cc:_ZN9SingletonIN2yb6tablet12_GLOBAL__N_123AutoIncrementingCounterEE14CreateInstanceEv
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
  }
_ZN9SingletonIN2yb15EncoderResolverINS0_10faststringEEEE14CreateInstanceEv
Line
Count
Source
136
1.44k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
1.44k
    return ::new Type;
139
1.44k
  }
_ZN9SingletonIN2yb15EncoderResolverINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEEEE14CreateInstanceEv
Line
Count
Source
136
5.43k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
5.43k
    return ::new Type;
139
5.43k
  }
_ZN9SingletonIN2yb16TypeInfoResolverEE14CreateInstanceEv
Line
Count
Source
136
12.4k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
12.4k
    return ::new Type;
139
12.4k
  }
_ZN9SingletonIN2yb5docdb17DocPgTypeAnalyzerEE14CreateInstanceEv
Line
Count
Source
136
428
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
428
    return ::new Type;
139
428
  }
_ZN9SingletonIN2yb5debug8TraceLogEE14CreateInstanceEv
Line
Count
Source
136
16.2k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
16.2k
    return ::new Type;
139
16.2k
  }
_ZN9SingletonIN2yb5debug32TraceEventSyntheticDelayRegistryEE14CreateInstanceEv
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
  }
_ZN9SingletonIN2yb18flag_tags_internal15FlagTagRegistryEE14CreateInstanceEv
Line
Count
Source
136
20.6k
  static Type* CreateInstance() {
137
    // use ::new to work around a gcc bug when operator new is overloaded
138
20.6k
    return ::new Type;
139
20.6k
  }
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