00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Singleton.h 00006 * 00007 * $Id: Singleton.h 84273 2009-01-30 12:55:25Z johnnyw $ 00008 * 00009 * @brief 00010 * 00011 * @author Tim Harrison <harrison@cs.wustl.edu> 00012 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00013 * @author Chris Lahey 00014 * @author Rich Christy 00015 * @author David Levine <levine@cs.wustl.edu> 00016 */ 00017 //============================================================================= 00018 00019 #ifndef ACE_SINGLETON_H 00020 #define ACE_SINGLETON_H 00021 #include /**/ "ace/pre.h" 00022 00023 #include /**/ "ace/config-all.h" 00024 #include "ace/TSS_T.h" 00025 #include "ace/Cleanup.h" 00026 00027 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00028 # pragma once 00029 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00030 00031 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00032 00033 /** 00034 * @class ACE_Singleton 00035 * 00036 * @brief A Singleton Adapter uses the Adapter pattern to turn ordinary 00037 * classes into Singletons optimized with the Double-Checked 00038 * Locking optimization pattern. 00039 * 00040 * This implementation is a slight variation on the GoF 00041 * Singleton pattern. In particular, a single 00042 * <ACE_Singleton<TYPE, ACE_LOCK> > instance is allocated here, 00043 * not a <TYPE> instance. The reason for this is to allow 00044 * registration with the ACE_Object_Manager, so that the 00045 * Singleton can be cleaned up when the process exits. For this 00046 * scheme to work, a (static) cleanup() function must be 00047 * provided. ACE_Singleton provides one so that TYPE doesn't 00048 * need to. 00049 * If you want to make sure that only the singleton instance of 00050 * <T> is created, and that users cannot create their own 00051 * instances of <T>, do the following to class <T>: 00052 * (a) Make the constructor of <T> private (or protected) 00053 * (b) Make Singleton a friend of <T> 00054 * Here is an example: 00055 * @verbatim 00056 * class foo 00057 * { 00058 * friend class ACE_Singleton<foo, ACE_Null_Mutex>; 00059 * private: 00060 * foo () { cout << "foo constructed" << endl; } 00061 * ~foo () { cout << "foo destroyed" << endl; } 00062 * }; 00063 * typedef ACE_Singleton<foo, ACE_Null_Mutex> FOO; 00064 * @endverbatim 00065 * 00066 * @note The best types to use for ACE_LOCK are 00067 * ACE_Recursive_Thread_Mutex and ACE_Null_Mutex. 00068 * ACE_Recursive_Thread_Mutex should be used in multi-threaded 00069 * programs in which it is possible for more than one thread to 00070 * access the <ACE_Singleton<TYPE, ACE_LOCK>> instance. 00071 * ACE_Null_Mutex can be used otherwise. The reason that these 00072 * types of locks are best has to do with their allocation by 00073 * the ACE_Object_Manager. Single ACE_Recursive_Thread_Mutex 00074 * and ACE_Null_Mutex instances are used for all ACE_Singleton 00075 * instantiations. However, other types of locks are allocated 00076 * per ACE_Singleton instantiation. 00077 */ 00078 template <class TYPE, class ACE_LOCK> 00079 class ACE_Singleton : public ACE_Cleanup 00080 { 00081 public: 00082 /// Global access point to the Singleton. 00083 static TYPE *instance (void); 00084 00085 /// Cleanup method, used by @c ace_cleanup_destroyer to destroy the 00086 /// ACE_Singleton. 00087 virtual void cleanup (void *param = 0); 00088 00089 /// Explicitly delete the Singleton instance. 00090 static void close (void); 00091 00092 /// Dump the state of the object. 00093 static void dump (void); 00094 00095 protected: 00096 /// Default constructor. 00097 ACE_Singleton (void); 00098 00099 /// Contained instance. 00100 TYPE instance_; 00101 00102 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00103 /// Pointer to the Singleton (ACE_Cleanup) instance. 00104 static ACE_Singleton<TYPE, ACE_LOCK> *singleton_; 00105 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00106 00107 /// Get pointer to the Singleton instance. 00108 static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00109 }; 00110 00111 /** 00112 * @class ACE_Unmanaged_Singleton 00113 * 00114 * @brief Same as ACE_Singleton, except does _not_ register with 00115 * ACE_Object_Manager for destruction. 00116 * 00117 * This version of ACE_Singleton can be used if, for example, 00118 * its DLL will be unloaded before the ACE_Object_Manager 00119 * destroys the instance. Unlike with ACE_Singleton, the 00120 * application is responsible for explicitly destroying the 00121 * instance after it is no longer needed (if it wants to avoid 00122 * memory leaks, at least). The close() static member function 00123 * must be used to explicitly destroy the Singleton. 00124 * Usage is the same as for ACE_Singleton, but note that if you 00125 * you declare a friend, the friend class must still be an 00126 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton. 00127 */ 00128 template <class TYPE, class ACE_LOCK> 00129 class ACE_Unmanaged_Singleton : public ACE_Singleton <TYPE, ACE_LOCK> 00130 { 00131 public: 00132 /// Global access point to the Singleton. 00133 static TYPE *instance (void); 00134 00135 /// Explicitly delete the Singleton instance. 00136 static void close (void); 00137 00138 /// Dump the state of the object. 00139 static void dump (void); 00140 00141 protected: 00142 /// Default constructor. 00143 ACE_Unmanaged_Singleton (void); 00144 00145 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00146 /// Pointer to the Singleton (ACE_Cleanup) instance. 00147 static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *singleton_; 00148 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00149 00150 /// Get pointer to the Singleton instance. 00151 static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00152 }; 00153 00154 /** 00155 * @class ACE_TSS_Singleton 00156 * 00157 * @brief This class uses the Adapter pattern to turn ordinary classes 00158 * into Thread-specific Singletons optimized with the 00159 * Double-Checked Locking optimization pattern. 00160 * 00161 * This implementation is another variation on the GoF Singleton 00162 * pattern. In this case, a single <ACE_TSS_Singleton<TYPE, 00163 * LOCK> > instance is allocated here, not a <TYPE> instance. 00164 * Each call to the <instance> static method returns a Singleton 00165 * whose pointer resides in thread-specific storage. As with 00166 * ACE_Singleton, we use the ACE_Object_Manager so that the 00167 * Singleton can be cleaned up when the process exits. For this 00168 * scheme to work, a (static) cleanup() function must be 00169 * provided. ACE_Singleton provides one so that TYPE doesn't 00170 * need to. 00171 */ 00172 template <class TYPE, class ACE_LOCK> 00173 class ACE_TSS_Singleton : public ACE_Cleanup 00174 { 00175 public: 00176 /// Global access point to the singleton. 00177 static TYPE *instance (void); 00178 00179 /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the 00180 /// singleton. 00181 virtual void cleanup (void *param = 0); 00182 00183 /// Dump the state of the object. 00184 static void dump (void); 00185 00186 protected: 00187 /// Default constructor. 00188 ACE_TSS_Singleton (void); 00189 00190 /// Contained instance. 00191 ACE_TSS_TYPE (TYPE) instance_; 00192 00193 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &)) 00194 ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Singleton (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &)) 00195 00196 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00197 /// Pointer to the Singleton (ACE_Cleanup) instance. 00198 static ACE_TSS_Singleton<TYPE, ACE_LOCK> *singleton_; 00199 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00200 00201 /// Get pointer to the TSS Singleton instance. 00202 static ACE_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00203 }; 00204 00205 /** 00206 * @class ACE_Unmanaged_TSS_Singleton 00207 * 00208 * @brief Same as ACE_TSS_Singleton, except does _not_ register with 00209 * ACE_Object_Manager for destruction. 00210 * 00211 * This version of ACE_TSS_Singleton can be used if, for example, its DLL will 00212 * be unloaded before the ACE_Object_Manager destroys the instance. Unlike with 00213 * ACE_Singleton, the application is responsible for explicitly destroying the 00214 * instance after it is no longer needed (if it wants to avoid memory leaks, 00215 * at least). The close() static member function must be used to explicitly 00216 * destroy the Singleton. 00217 */ 00218 template <class TYPE, class ACE_LOCK> 00219 class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton <TYPE, ACE_LOCK> 00220 { 00221 public: 00222 /// Global access point to the singleton. 00223 static TYPE *instance (void); 00224 00225 /// Explicitly delete the singleton instance. 00226 static void close (void); 00227 00228 /// Dump the state of the object. 00229 static void dump (void); 00230 00231 protected: 00232 /// Default constructor. 00233 ACE_Unmanaged_TSS_Singleton (void); 00234 00235 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00236 /// Pointer to the Singleton (ACE_Cleanup) instance. 00237 static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *singleton_; 00238 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00239 00240 /// Get pointer to the Singleton instance. 00241 static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00242 }; 00243 00244 /** 00245 * @class ACE_DLL_Singleton_T 00246 * 00247 * @brief Same as ACE_Singleton, except that it registers for 00248 * destruction with the ACE_Framework_Repository instead of 00249 * with the ACE_Object_Manager directly. 00250 * 00251 * This version of ACE_Singleton should be used for singletons 00252 * that live in a dll loaded either directly by ACE_DLL or indirectly 00253 * by the ACE Service Configuration framework. Whenever ACE_DLL is ready 00254 * to actually unload the dll, ACE_DLL_Singleton based dlls associated 00255 * with that dll will be destroyed first. In fact, any singleton can 00256 * safely use ACE_DLL_Singleton, even those that don't live in dlls. In 00257 * that case, the singleton will be destroyed at normal program shutdown. 00258 * 00259 * The only additional requirement is that the contained class 00260 * export name() and dll_name() methods. See ACE_DLL_Singleton_Adapter_T 00261 * below for a convenient example of how to satisfy this 00262 * requirement for the dll_name(). 00263 * 00264 * Usage is the same as for ACE_Singleton, but note that if you 00265 * you declare a friend, the friend class must still be an 00266 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton. 00267 */ 00268 template <class TYPE, class ACE_LOCK> 00269 class ACE_DLL_Singleton_T 00270 { 00271 public: 00272 //void cleanup (void *param = 0); 00273 00274 /// Global access point to the Singleton. 00275 static TYPE *instance (void); 00276 00277 /// Explicitly delete the Singleton instance. 00278 static void close (void); 00279 00280 static void close_singleton (void); 00281 00282 /// Dump the state of the object. 00283 static void dump (void); 00284 00285 const ACE_TCHAR *dll_name (void); 00286 00287 const ACE_TCHAR *name (void); 00288 00289 protected: 00290 /// Default constructor. 00291 ACE_DLL_Singleton_T (void); 00292 00293 /// Destructor. 00294 ~ACE_DLL_Singleton_T (void); 00295 00296 /// Contained instance. 00297 TYPE instance_; 00298 00299 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00300 /// Pointer to the Singleton instance. 00301 static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *singleton_; 00302 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00303 00304 /// Get pointer to the singleton instance. 00305 static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&instance_i (void); 00306 }; 00307 00308 template <class TYPE> 00309 class ACE_DLL_Singleton_Adapter_T : public TYPE 00310 { 00311 public: 00312 const ACE_TCHAR *dll_name (void); 00313 }; 00314 00315 ACE_END_VERSIONED_NAMESPACE_DECL 00316 00317 #if defined (__ACE_INLINE__) 00318 #include "ace/Singleton.inl" 00319 #endif /* __ACE_INLINE__ */ 00320 00321 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00322 #include "ace/Singleton.cpp" 00323 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00324 00325 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00326 #pragma implementation ("Singleton.cpp") 00327 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00328 00329 #include /**/ "ace/post.h" 00330 #endif /* ACE_SINGLETON_H */