Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: base/singleton.h

Issue 5682008: Make members of Singleton<T> private and only visible to the singleton type. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_SINGLETON_H_ 5 #ifndef BASE_SINGLETON_H_
6 #define BASE_SINGLETON_H_ 6 #define BASE_SINGLETON_H_
7 #pragma once 7 #pragma once
8 8
9 #include "base/at_exit.h" 9 #include "base/at_exit.h"
10 #include "base/atomicops.h" 10 #include "base/atomicops.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 107
108 // Signal the object was already deleted, so it is not revived. 108 // Signal the object was already deleted, so it is not revived.
109 static base::subtle::Atomic32 dead_; 109 static base::subtle::Atomic32 dead_;
110 }; 110 };
111 111
112 template <typename Type> intptr_t 112 template <typename Type> intptr_t
113 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize]; 113 StaticMemorySingletonTraits<Type>::buffer_[kBufferSize];
114 template <typename Type> base::subtle::Atomic32 114 template <typename Type> base::subtle::Atomic32
115 StaticMemorySingletonTraits<Type>::dead_ = 0; 115 StaticMemorySingletonTraits<Type>::dead_ = 0;
116 116
117
118 // The Singleton<Type, Traits, DifferentiatingType> class manages a single 117 // The Singleton<Type, Traits, DifferentiatingType> class manages a single
119 // instance of Type which will be created on first use and will be destroyed at 118 // instance of Type which will be created on first use and will be destroyed at
120 // normal process exit). The Trait::Delete function will not be called on 119 // normal process exit). The Trait::Delete function will not be called on
121 // abnormal process exit. 120 // abnormal process exit.
122 // 121 //
123 // DifferentiatingType is used as a key to differentiate two different 122 // DifferentiatingType is used as a key to differentiate two different
124 // singletons having the same memory allocation functions but serving a 123 // singletons having the same memory allocation functions but serving a
125 // different purpose. This is mainly used for Locks serving different purposes. 124 // different purpose. This is mainly used for Locks serving different purposes.
126 // 125 //
127 // Example usages: (none are preferred, they all result in the same code) 126 // Example usage:
128 // 1. FooClass* ptr = Singleton<FooClass>::get(); 127 //
129 // ptr->Bar(); 128 // In your header:
130 // 2. Singleton<FooClass>()->Bar(); 129 // #include "base/singleton.h"
131 // 3. Singleton<FooClass>::get()->Bar(); 130 // class FooClass {
131 // public:
132 // static FooClass* GetInstance(); <-- See comment below on this.
133 // void Bar() { ... }
134 // private:
135 // FooClass() { ... }
136 // friend struct DefaultSingletonTraits<FooClass>;
137 //
138 // DISALLOW_COPY_AND_ASSIGN(FooClass);
139 // };
140 //
141 // In your source file:
142 // FooClass* FooClass::GetInstance() {
143 // return Singleton<FooClass>::get();
144 // }
145 //
146 // And to call methods on FooClass:
147 // FooClass::GetInstance()->Bar();
148 //
149 // NOTE: The method accessing Singleton<T>::get() has to be named as GetInstance
150 // and it is important that FooClass::GetInstance() is not inlined in the
151 // header. This makes sure that when source files from multiple targets include
152 // this header they don't end up with different copies of the inlined code
153 // creating multiple copies of the singleton.
132 // 154 //
133 // Singleton<> has no non-static members and doesn't need to actually be 155 // Singleton<> has no non-static members and doesn't need to actually be
134 // instantiated. It does no harm to instantiate it and use it as a class member 156 // instantiated.
135 // or at global level since it is acting as a POD type.
136 // 157 //
137 // This class is itself thread-safe. The underlying Type must of course be 158 // This class is itself thread-safe. The underlying Type must of course be
138 // thread-safe if you want to use it concurrently. Two parameters may be tuned 159 // thread-safe if you want to use it concurrently. Two parameters may be tuned
139 // depending on the user's requirements. 160 // depending on the user's requirements.
140 // 161 //
141 // Glossary: 162 // Glossary:
142 // RAE = kRegisterAtExit 163 // RAE = kRegisterAtExit
143 // 164 //
144 // On every platform, if Traits::RAE is true, the singleton will be destroyed at 165 // On every platform, if Traits::RAE is true, the singleton will be destroyed at
145 // process exit. More precisely it uses base::AtExitManager which requires an 166 // process exit. More precisely it uses base::AtExitManager which requires an
146 // object of this type to be instantiated. AtExitManager mimics the semantics 167 // object of this type to be instantiated. AtExitManager mimics the semantics
147 // of atexit() such as LIFO order but under Windows is safer to call. For more 168 // of atexit() such as LIFO order but under Windows is safer to call. For more
148 // information see at_exit.h. 169 // information see at_exit.h.
149 // 170 //
150 // If Traits::RAE is false, the singleton will not be freed at process exit, 171 // If Traits::RAE is false, the singleton will not be freed at process exit,
151 // thus the singleton will be leaked if it is ever accessed. Traits::RAE 172 // thus the singleton will be leaked if it is ever accessed. Traits::RAE
152 // shouldn't be false unless absolutely necessary. Remember that the heap where 173 // shouldn't be false unless absolutely necessary. Remember that the heap where
153 // the object is allocated may be destroyed by the CRT anyway. 174 // the object is allocated may be destroyed by the CRT anyway.
154 // 175 //
155 // If you want to ensure that your class can only exist as a singleton, make
156 // its constructors private, and make DefaultSingletonTraits<> a friend:
157 //
158 // #include "base/singleton.h"
159 // class FooClass {
160 // public:
161 // void Bar() { ... }
162 // private:
163 // FooClass() { ... }
164 // friend struct DefaultSingletonTraits<FooClass>;
165 //
166 // DISALLOW_COPY_AND_ASSIGN(FooClass);
167 // };
168 //
169 // Caveats: 176 // Caveats:
170 // (a) Every call to get(), operator->() and operator*() incurs some overhead 177 // (a) Every call to get(), operator->() and operator*() incurs some overhead
171 // (16ns on my P4/2.8GHz) to check whether the object has already been 178 // (16ns on my P4/2.8GHz) to check whether the object has already been
172 // initialized. You may wish to cache the result of get(); it will not 179 // initialized. You may wish to cache the result of get(); it will not
173 // change. 180 // change.
174 // 181 //
175 // (b) Your factory function must never throw an exception. This class is not 182 // (b) Your factory function must never throw an exception. This class is not
176 // exception-safe. 183 // exception-safe.
177 // 184 //
178 template <typename Type, 185 template <typename Type,
179 typename Traits = DefaultSingletonTraits<Type>, 186 typename Traits = DefaultSingletonTraits<Type>,
180 typename DifferentiatingType = Type> 187 typename DifferentiatingType = Type>
181 class Singleton { 188 class Singleton {
182 public: 189 private:
190 // Classes using the Singleton<T> pattern should declare a GetInstance()
191 // method and call Singleton::get() from within that.
192 friend Type* Type::GetInstance();
193
183 // This class is safe to be constructed and copy-constructed since it has no 194 // This class is safe to be constructed and copy-constructed since it has no
184 // member. 195 // member.
185 196
186 // Return a pointer to the one true instance of the class. 197 // Return a pointer to the one true instance of the class.
187 static Type* get() { 198 static Type* get() {
188 if (!Traits::kAllowedToAccessOnNonjoinableThread) 199 if (!Traits::kAllowedToAccessOnNonjoinableThread)
189 base::ThreadRestrictions::AssertSingletonAllowed(); 200 base::ThreadRestrictions::AssertSingletonAllowed();
190 201
191 // Our AtomicWord doubles as a spinlock, where a value of 202 // Our AtomicWord doubles as a spinlock, where a value of
192 // kBeingCreatedMarker means the spinlock is being held for creation. 203 // kBeingCreatedMarker means the spinlock is being held for creation.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 if (value != kBeingCreatedMarker) 244 if (value != kBeingCreatedMarker)
234 break; 245 break;
235 PlatformThread::YieldCurrentThread(); 246 PlatformThread::YieldCurrentThread();
236 } 247 }
237 248
238 // See the corresponding HAPPENS_BEFORE above. 249 // See the corresponding HAPPENS_BEFORE above.
239 ANNOTATE_HAPPENS_AFTER(&instance_); 250 ANNOTATE_HAPPENS_AFTER(&instance_);
240 return reinterpret_cast<Type*>(value); 251 return reinterpret_cast<Type*>(value);
241 } 252 }
242 253
243 // Shortcuts.
244 Type& operator*() {
245 return *get();
246 }
247
248 Type* operator->() {
249 return get();
250 }
251
252 private:
253 // Adapter function for use with AtExit(). This should be called single 254 // Adapter function for use with AtExit(). This should be called single
254 // threaded, so don't use atomic operations. 255 // threaded, so don't use atomic operations.
255 // Calling OnExit while singleton is in use by other threads is a mistake. 256 // Calling OnExit while singleton is in use by other threads is a mistake.
256 static void OnExit(void* unused) { 257 static void OnExit(void* unused) {
257 // AtExit should only ever be register after the singleton instance was 258 // AtExit should only ever be register after the singleton instance was
258 // created. We should only ever get here with a valid instance_ pointer. 259 // created. We should only ever get here with a valid instance_ pointer.
259 Traits::Delete( 260 Traits::Delete(
260 reinterpret_cast<Type*>(base::subtle::NoBarrier_Load(&instance_))); 261 reinterpret_cast<Type*>(base::subtle::NoBarrier_Load(&instance_)));
261 instance_ = 0; 262 instance_ = 0;
262 } 263 }
263 static base::subtle::AtomicWord instance_; 264 static base::subtle::AtomicWord instance_;
264 }; 265 };
265 266
266 template <typename Type, typename Traits, typename DifferentiatingType> 267 template <typename Type, typename Traits, typename DifferentiatingType>
267 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>:: 268 base::subtle::AtomicWord Singleton<Type, Traits, DifferentiatingType>::
268 instance_ = 0; 269 instance_ = 0;
269 270
270 #endif // BASE_SINGLETON_H_ 271 #endif // BASE_SINGLETON_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698