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