Geant4  10.02.p01
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 // $Id$
27 //
28 // ---------------------------------------------------------------
29 // GEANT 4 class header file
30 //
31 // Class Description:
32 // This class implements a thread-private "singleton". Being thread
33 // private the singleton is not a singleton in the term, but a different
34 // instance existis for each thread.
35 // This class is a wrapper around the real object that we need to
36 // make singleton.
37 //
38 // Limitation:
39 // The object that is made thread-private singleton, should not
40 // contain any G4ThreadLocal data member. Note that in general,
41 // if object is to be thread-private it is unnecessary to mark
42 // any data-member as G4ThreadLocal.
43 //
44 // Performance issues:
45 // This class uses locks and mutexes.
46 //
47 // Example:
48 // This is the singleton patter often found in G4 (sequential):
49 // class G4Class {
50 // private:
51 // static G4Class* instance;
52 // G4Class() { ... }
53 // public:
54 // static G4Class* GetInstance() {
55 // static G4Class theInstance;
56 // if ( instance == 0 ) 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 // private:
64 // static G4ThreadLocal G4Class* instance;
65 // G4Class() { ... }
66 // public:
67 // static G4Class* GetInstance() {
68 // if ( instance == 0 ) instance = new G4Class;
69 // return instance;
70 // }
71 // };
72 // Note that this class also has a memory leak.
73 //
74 // This class can be used as follows:
75 // class G4Class {
76 // friend class G4ThreadLocalSingleton<G4Class>;
77 // private:
78 // G4Class() { ... }
79 // public:
80 // static G4Class* GetInstance() {
81 // static G4ThreadLocalSingleton<G4Class> instance;
82 // return instance.Instance();
83 // }
84 // };
85 // Each thread has its own instance of G4Class.
86 // Deletion of G4Class instances is done at end of program.
87 // Note the "friend" statement.
88 //
89 // History:
90 // 28 October 2013: A. Dotti - First implementation
91 
92 #ifndef G4TLSSINGLETON_HH
93 #define G4TLSSINGLETON_HH
94 
95 //Debug this code
96 //#define g4tlssdebug 1
97 
98 #include "G4Cache.hh"
99 #include <list>
100 
101 //Forward declaration. See G4AutoDelete.hh
102 namespace G4AutoDelete {
103  template<class T>
104  void Register(T*);
105 }
106 
107 template<class T>
108 class G4ThreadLocalSingleton : private G4Cache<T*> {
109  friend void G4AutoDelete::Register<T>(T*);
110 public:
112  //Creates thread-local singleton manager
113 
115 
116  T* Instance() const;
117  //Returns a pointer to a thread-private instance of T
118 
119 private:
121  void Register(T* i) const;
122 
123  void Clear();
124 
125  mutable std::list<T*> instances;
126  mutable G4Mutex listm;
127 };
128 
129 
130 //=============================================================
131 // Implementation details follow
132 //=============================================================
133 #include "G4AutoLock.hh"
134 template<class T>
137  G4Cache<T*>::Put(static_cast<T*>(0));
138 }
139 
140 template<class T>
142  G4MUTEXDESTROY(listm);
143  Clear();
144 }
145 
146 template<class T>
148  T* instance = G4Cache<T*>::Get();
149  if ( instance == static_cast<T*>(0) ) {
150  instance = new T;
151  G4Cache<T*>::Put( instance );
152  Register(instance);
153  }
154  return instance;
155  }
156 
157 template<class T>
159 template<class T>
161  G4AutoLock l(&listm);
162  instances.push_back(i);
163 }
164 
165 
166 template<class T>
168  G4AutoLock l(&listm);
169  while ( ! instances.empty() )
170  {
171  T* thisinst = instances.front();
172  instances.pop_front();
173  if ( thisinst != 0 ) delete thisinst;
174  }
175  }
176 
177 #endif //G4TLSSINGLETON_HH
void Clear(Node *)
value_type & Get() const
Definition: G4Cache.hh:282
#define G4MUTEXINIT(mutex)
Definition: G4Threading.hh:177
void Register(T *inst)
Definition: G4AutoDelete.hh:65
G4int G4Mutex
Definition: G4Threading.hh:173
static MCTruthManager * instance
void Put(const value_type &val) const
Definition: G4Cache.hh:286
#define G4MUTEXDESTROY(mutex)
Definition: G4Threading.hh:178