Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ThreadLocalSingleton.hh
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4ThreadLocalSingleton
27//
28// Class description:
29//
30// This class implements a thread-private "singleton". Being thread
31// private the singleton is not a singleton in the term, but a different
32// instance exists for each thread.
33// This class is a wrapper around the real object that we need to
34// make singleton.
35//
36// Limitation:
37// The object that is made thread-private singleton should not
38// contain any thread-local data member. Note that in general,
39// if an object is to be thread-private it is unnecessary to mark
40// any data-member as G4ThreadLocal.
41//
42// Performance issues:
43// This class uses locks and mutexes.
44//
45// Example:
46// This is the singleton pattern often found in Geant4 (sequential):
47// class G4Class
48// {
49// private:
50// static G4Class* instance;
51// G4Class() { ... }
52// public:
53// static G4Class* GetInstance()
54// {
55// static G4Class theInstance;
56// if ( instance == nullptr ) instance = &theInstance;
57// return instance;
58// }
59// };
60// This is transformed to the following to implement a thread-local
61// singleton:
62// class G4Class
63// {
64// private:
65// static G4ThreadLocal G4Class* instance;
66// G4Class() { ... }
67// public:
68// static G4Class* GetInstance()
69// {
70// if ( instance == nullptr ) instance = new G4Class;
71// return instance;
72// }
73// };
74// Note that this class also has a memory leak.
75//
76// This class can be used as follows:
77// class G4Class
78// {
79// friend class G4ThreadLocalSingleton<G4Class>;
80// private:
81// G4Class() { ... }
82// public:
83// static G4Class* GetInstance()
84// {
85// static G4ThreadLocalSingleton<G4Class> instance;
86// return instance.Instance();
87// }
88// };
89// Each thread has its own instance of G4Class.
90// Deletion of G4Class instances is done at end of program.
91// Note the "friend" statement.
92
93// Author: A.Dotti, 28 October 2013
94// --------------------------------------------------------------------
95#ifndef G4TLSSINGLETON_HH
96#define G4TLSSINGLETON_HH 1
97
98#include <list>
99
100#include "G4AutoLock.hh"
101#include "G4Cache.hh"
102
103// Forward declaration. See G4AutoDelete.hh
104//
105namespace G4AutoDelete
106{
107 template <class T>
108 void Register(T*);
109}
110
111template <class T>
113{
114 friend void G4AutoDelete::Register<T>(T*);
115
116 public:
118 // Creates thread-local singleton manager
119
121
122 T* Instance() const;
123 // Returns a pointer to a thread-private instance of T
124
125 private:
127 void Register(T* i) const;
128
129 void Clear();
130
131 mutable std::list<T*> instances;
132 mutable G4Mutex listm;
133};
134
135//=============================================================
136// Inline methods implementation
137//=============================================================
138
139template <class T>
141 : G4Cache<T*>()
142{
143 G4MUTEXINIT(listm);
144 G4Cache<T*>::Put(static_cast<T*>(0));
145}
146
147template <class T>
149{
150 Clear();
151 G4MUTEXDESTROY(listm);
152}
153
154template <class T>
156{
157 T* instance = G4Cache<T*>::Get();
158 if(instance == static_cast<T*>(0))
159 {
160 instance = new T;
161 G4Cache<T*>::Put(instance);
162 Register(instance);
163 }
164 return instance;
165}
166
167template <class T>
169{}
170
171template <class T>
173{
174 G4AutoLock l(&listm);
175 instances.push_back(i);
176}
177
178template <class T>
180{
181 G4AutoLock l(&listm);
182 while(!instances.empty())
183 {
184 T* thisinst = instances.front();
185 instances.pop_front();
186 delete thisinst;
187 }
188}
189
190#endif
#define G4MUTEXDESTROY(mutex)
Definition: G4Threading.hh:90
std::mutex G4Mutex
Definition: G4Threading.hh:81
#define G4MUTEXINIT(mutex)
Definition: G4Threading.hh:87
value_type & Get() const
Definition: G4Cache.hh:315
void Put(const value_type &val) const
Definition: G4Cache.hh:321
friend void G4AutoDelete::Register(T *)
void Register(T *inst)
Definition: G4AutoDelete.hh:65