00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Singleton.h 00006 * 00007 * $Id: Singleton.h 80826 2008-03-04 14:51:23Z wotte $ 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 <ace_cleanup_destroyer> to destroy the 00086 /// ACE_Singleton. 00087 virtual void cleanup (void *param = 0); 00088 00089 /// Dump the state of the object. 00090 static void dump (void); 00091 00092 protected: 00093 /// Default constructor. 00094 ACE_Singleton (void); 00095 00096 /// Contained instance. 00097 TYPE instance_; 00098 00099 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00100 /// Pointer to the Singleton (ACE_Cleanup) instance. 00101 static ACE_Singleton<TYPE, ACE_LOCK> *singleton_; 00102 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00103 00104 /// Get pointer to the Singleton instance. 00105 static ACE_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00106 }; 00107 00108 /** 00109 * @class ACE_Unmanaged_Singleton 00110 * 00111 * @brief Same as ACE_Singleton, except does _not_ register with 00112 * ACE_Object_Manager for destruction. 00113 * 00114 * This version of ACE_Singleton can be used if, for example, 00115 * its DLL will be unloaded before the ACE_Object_Manager 00116 * destroys the instance. Unlike with ACE_Singleton, the 00117 * application is responsible for explicitly destroying the 00118 * instance after it is no longer needed (if it wants to avoid 00119 * memory leaks, at least). The close() static member function 00120 * must be used to explicitly destroy the Singleton. 00121 * Usage is the same as for ACE_Singleton, but note that if you 00122 * you declare a friend, the friend class must still be an 00123 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton. 00124 */ 00125 template <class TYPE, class ACE_LOCK> 00126 class ACE_Unmanaged_Singleton : public ACE_Singleton <TYPE, ACE_LOCK> 00127 { 00128 public: 00129 /// Global access point to the Singleton. 00130 static TYPE *instance (void); 00131 00132 /// Explicitly delete the Singleton instance. 00133 static void close (void); 00134 00135 /// Dump the state of the object. 00136 static void dump (void); 00137 00138 protected: 00139 /// Default constructor. 00140 ACE_Unmanaged_Singleton (void); 00141 00142 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00143 /// Pointer to the Singleton (ACE_Cleanup) instance. 00144 static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *singleton_; 00145 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00146 00147 /// Get pointer to the Singleton instance. 00148 static ACE_Unmanaged_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00149 }; 00150 00151 /** 00152 * @class ACE_TSS_Singleton 00153 * 00154 * @brief This class uses the Adapter pattern to turn ordinary classes 00155 * into Thread-specific Singletons optimized with the 00156 * Double-Checked Locking optimization pattern. 00157 * 00158 * This implementation is another variation on the GoF Singleton 00159 * pattern. In this case, a single <ACE_TSS_Singleton<TYPE, 00160 * LOCK> > instance is allocated here, not a <TYPE> instance. 00161 * Each call to the <instance> static method returns a Singleton 00162 * whose pointer resides in thread-specific storage. As with 00163 * ACE_Singleton, we use the ACE_Object_Manager so that the 00164 * Singleton can be cleaned up when the process exits. For this 00165 * scheme to work, a (static) cleanup() function must be 00166 * provided. ACE_Singleton provides one so that TYPE doesn't 00167 * need to. 00168 */ 00169 template <class TYPE, class ACE_LOCK> 00170 class ACE_TSS_Singleton : public ACE_Cleanup 00171 { 00172 public: 00173 /// Global access point to the singleton. 00174 static TYPE *instance (void); 00175 00176 /// Cleanup method, used by <ace_cleanup_destroyer> to destroy the 00177 /// singleton. 00178 virtual void cleanup (void *param = 0); 00179 00180 /// Dump the state of the object. 00181 static void dump (void); 00182 00183 protected: 00184 /// Default constructor. 00185 ACE_TSS_Singleton (void); 00186 00187 /// Contained instance. 00188 ACE_TSS_TYPE (TYPE) instance_; 00189 00190 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &)) 00191 ACE_UNIMPLEMENTED_FUNC (ACE_TSS_Singleton (const ACE_TSS_Singleton<TYPE,ACE_LOCK> &)) 00192 00193 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00194 /// Pointer to the Singleton (ACE_Cleanup) instance. 00195 static ACE_TSS_Singleton<TYPE, ACE_LOCK> *singleton_; 00196 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00197 00198 /// Get pointer to the TSS Singleton instance. 00199 static ACE_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00200 }; 00201 00202 /** 00203 * @class ACE_Unmanaged_TSS_Singleton 00204 * 00205 * @brief Same as ACE_TSS_Singleton, except does _not_ register with 00206 * ACE_Object_Manager for destruction. 00207 * 00208 * This version of ACE_TSS_Singleton can be used if, for example, its DLL will 00209 * be unloaded before the ACE_Object_Manager destroys the instance. Unlike with 00210 * ACE_Singleton, the application is responsible for explicitly destroying the 00211 * instance after it is no longer needed (if it wants to avoid memory leaks, 00212 * at least). The close() static member function must be used to explicitly 00213 * destroy the Singleton. 00214 */ 00215 template <class TYPE, class ACE_LOCK> 00216 class ACE_Unmanaged_TSS_Singleton : public ACE_TSS_Singleton <TYPE, ACE_LOCK> 00217 { 00218 public: 00219 /// Global access point to the singleton. 00220 static TYPE *instance (void); 00221 00222 /// Explicitly delete the singleton instance. 00223 static void close (void); 00224 00225 /// Dump the state of the object. 00226 static void dump (void); 00227 00228 protected: 00229 /// Default constructor. 00230 ACE_Unmanaged_TSS_Singleton (void); 00231 00232 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00233 /// Pointer to the Singleton (ACE_Cleanup) instance. 00234 static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *singleton_; 00235 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00236 00237 /// Get pointer to the Singleton instance. 00238 static ACE_Unmanaged_TSS_Singleton<TYPE, ACE_LOCK> *&instance_i (void); 00239 }; 00240 00241 /** 00242 * @class ACE_DLL_Singleton_T 00243 * 00244 * @brief Same as ACE_Singleton, except that it registers for 00245 * destruction with the ACE_Framework_Repository instead of 00246 * with the ACE_Object_Manager directly. 00247 * 00248 * This version of ACE_Singleton should be used for singletons 00249 * that live in a dll loaded either directly by ACE_DLL or indirectly 00250 * by the ACE Service Configuration framework. Whenever ACE_DLL is ready 00251 * to actually unload the dll, ACE_DLL_Singleton based dlls associated 00252 * with that dll will be destroyed first. In fact, any singleton can 00253 * safely use ACE_DLL_Singleton, even those that don't live in dlls. In 00254 * that case, the singleton will be destroyed at normal program shutdown. 00255 * 00256 * The only additional requirement is that the contained class 00257 * export name() and dll_name() methods. See ACE_DLL_Singleton_Adapter_T 00258 * below for a convenient example of how to satisfy this 00259 * requirement for the dll_name(). 00260 * 00261 * Usage is the same as for ACE_Singleton, but note that if you 00262 * you declare a friend, the friend class must still be an 00263 * *ACE_Singleton*<T, [ACE_LOCK]>, not an ACE_Unmanaged_Singleton. 00264 */ 00265 template <class TYPE, class ACE_LOCK> 00266 class ACE_DLL_Singleton_T 00267 { 00268 public: 00269 //void cleanup (void *param = 0); 00270 00271 /// Global access point to the Singleton. 00272 static TYPE *instance (void); 00273 00274 /// Explicitly delete the Singleton instance. 00275 static void close (void); 00276 00277 static void close_singleton (void); 00278 00279 /// Dump the state of the object. 00280 static void dump (void); 00281 00282 const ACE_TCHAR *dll_name (void); 00283 00284 const ACE_TCHAR *name (void); 00285 00286 protected: 00287 /// Default constructor. 00288 ACE_DLL_Singleton_T (void); 00289 00290 /// Destructor. 00291 ~ACE_DLL_Singleton_T (void); 00292 00293 /// Contained instance. 00294 TYPE instance_; 00295 00296 #if !defined (ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES) 00297 /// Pointer to the Singleton instance. 00298 static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *singleton_; 00299 #endif /* ACE_LACKS_STATIC_DATA_MEMBER_TEMPLATES */ 00300 00301 /// Get pointer to the singleton instance. 00302 static ACE_DLL_Singleton_T<TYPE, ACE_LOCK> *&instance_i (void); 00303 }; 00304 00305 template <class TYPE> 00306 class ACE_DLL_Singleton_Adapter_T : public TYPE 00307 { 00308 public: 00309 const ACE_TCHAR *dll_name (void); 00310 }; 00311 00312 ACE_END_VERSIONED_NAMESPACE_DECL 00313 00314 #if defined (__ACE_INLINE__) 00315 #include "ace/Singleton.inl" 00316 #endif /* __ACE_INLINE__ */ 00317 00318 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) 00319 #include "ace/Singleton.cpp" 00320 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ 00321 00322 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00323 #pragma implementation ("Singleton.cpp") 00324 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00325 00326 #include /**/ "ace/post.h" 00327 #endif /* ACE_SINGLETON_H */