00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Framework_Component.h 00006 * 00007 * $Id: Framework_Component.h 78460 2007-05-23 13:33:56Z johnnyw $ 00008 * 00009 * A prototype mechanism that allows framework components, singletons 00010 * such as ACE_Reactor, ACE_Proactor, etc, to be registered with a 00011 * central repository managed by the ACE_Object_Manager or 00012 * ACE_Service_Config that will handle destruction. 00013 * 00014 * This technique obviates changing ACE_Object_Manager and 00015 * ACE_Service_Config everytime a new framework is added. Which also 00016 * means that unused framework components don't need to linked into 00017 * the final application which is important for applications with 00018 * stringent footprint requirements. 00019 * 00020 * Framework components need only provide a static method, 00021 * close_singleton() and add the ACE_REGISTER_FRAMEWORK_COMPONENT macro 00022 * call to their instance() methods in order to participate. Components 00023 * that don't have a close_singleton() method can also participate via 00024 * template specialization of ACE_Framework_Component_T. 00025 * 00026 * This design uses the External Polymorphism pattern to avoid having 00027 * to derive all framework components from a common base class that 00028 * has virtual methods (this is crucial to avoid unnecessary overhead), 00029 * and is based on the dump debugging implementation found in 00030 * <ace/Dump.h>. 00031 * 00032 * @author Don Hinton <dhinton@ieee.org>. 00033 */ 00034 //============================================================================= 00035 00036 #ifndef ACE_FRAMEWORK_COMPONENT_H 00037 #define ACE_FRAMEWORK_COMPONENT_H 00038 #include /**/ "ace/pre.h" 00039 00040 #include /**/ "ace/ACE_export.h" 00041 00042 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00043 # pragma once 00044 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00045 00046 #include "ace/os_include/os_signal.h" 00047 #include "ace/Thread_Mutex.h" 00048 00049 #define ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE 1024 00050 00051 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00052 00053 /** 00054 * @class ACE_Framework_Component 00055 * 00056 * @brief Base class that defines a uniform interface for all managed 00057 * framework components. 00058 */ 00059 class ACE_Export ACE_Framework_Component 00060 { 00061 public: 00062 friend class ACE_Framework_Repository; 00063 00064 /// Constructor. 00065 ACE_Framework_Component (void *_this, 00066 const ACE_TCHAR *dll_name = 0, 00067 const ACE_TCHAR *name = 0); 00068 00069 /// Close the contained singleton. 00070 virtual void close_singleton (void) = 0; 00071 00072 protected: 00073 /// Destructor. 00074 virtual ~ACE_Framework_Component (void); 00075 00076 private: 00077 // No copy possible 00078 ACE_Framework_Component (const ACE_Framework_Component &); 00079 void operator= (const ACE_Framework_Component &); 00080 00081 private: 00082 /// Pointer to the actual component. 00083 const void *this_; 00084 00085 /// Library associated with this component 00086 const ACE_TCHAR *dll_name_; 00087 00088 /// Component name 00089 const ACE_TCHAR *name_; 00090 }; 00091 00092 /** 00093 * @class ACE_Framework_Repository 00094 * 00095 * @brief Contains all framework components used by an application. 00096 * 00097 * This class contains a vector of ACE_Framework_Component *'s. On 00098 * destruction, framework components are destroyed in the reverse order 00099 * that they were added originally. 00100 */ 00101 class ACE_Export ACE_Framework_Repository 00102 { 00103 public: 00104 // This is just to silence a compiler warning about no public ctors 00105 friend class ACE_Framework_Component; 00106 00107 enum 00108 { 00109 DEFAULT_SIZE = ACE_DEFAULT_FRAMEWORK_REPOSITORY_SIZE 00110 }; 00111 00112 /// Close down the repository and free up dynamically allocated 00113 /// resources. 00114 ~ACE_Framework_Repository (void); 00115 00116 /// Initialize the repository. 00117 int open (int size = DEFAULT_SIZE); 00118 00119 /// Close down the repository and free up dynamically allocated 00120 /// resources, also called by dtor. 00121 int close (void); 00122 00123 /// Get pointer to a process-wide ACE_Framework_Repository. 00124 static ACE_Framework_Repository *instance 00125 (int size = ACE_Framework_Repository::DEFAULT_SIZE); 00126 00127 /// Delete the dynamically allocated Singleton. 00128 static void close_singleton (void); 00129 00130 // = Search structure operations (all acquire locks as necessary). 00131 00132 /// Insert a new component. Returns -1 when the repository is full 00133 /// and 0 on success. 00134 int register_component (ACE_Framework_Component *fc); 00135 00136 /// Remove a component. Returns -1 on error or if component not found 00137 /// and 0 on success. 00138 int remove_component (const ACE_TCHAR *name); 00139 00140 /// Remove all components associated with a particular dll. 00141 int remove_dll_components (const ACE_TCHAR *dll_name); 00142 00143 /// Return the current size of the repository. 00144 int current_size (void) const; 00145 00146 /// Return the total size of the repository. 00147 int total_size (void) const; 00148 00149 /// Dump the state of an object. 00150 void dump (void) const; 00151 00152 /// Declare the dynamic allocation hooks. 00153 ACE_ALLOC_HOOK_DECLARE; 00154 00155 protected: 00156 00157 /// Initialize the repository. 00158 ACE_Framework_Repository (int size = ACE_Framework_Repository::DEFAULT_SIZE); 00159 00160 private: 00161 00162 /// Actually removes the dll components, must be called with locks held. 00163 int remove_dll_components_i (const ACE_TCHAR *dll_name); 00164 00165 /// Compact component_vector_ after components have been removed__maintains 00166 /// order. 00167 void compact (void); 00168 00169 /// Disallow copying and assignment. 00170 ACE_Framework_Repository (const ACE_Framework_Repository &); 00171 ACE_Framework_Repository &operator= (const ACE_Framework_Repository &); 00172 00173 private: 00174 00175 /// Contains all the framework components. 00176 ACE_Framework_Component **component_vector_; 00177 00178 /// Current number of components. 00179 int current_size_; 00180 00181 /// Maximum number of components. 00182 int total_size_; 00183 00184 /// Pointer to a process-wide ACE_Framework_Repository. 00185 static ACE_Framework_Repository *repository_; 00186 00187 /// Flag set when repository is the process of shutting down. This 00188 /// is necessary to keep from self-deadlocking since some of 00189 /// the components might make calls back to the repository to 00190 /// unload their components, e.g., ACE_DLL_Manager. 00191 static sig_atomic_t shutting_down_; 00192 00193 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00194 /// Synchronization variable for the MT_SAFE Repository 00195 ACE_Thread_Mutex lock_; 00196 #endif /* ACE_MT_SAFE */ 00197 00198 }; 00199 00200 ACE_END_VERSIONED_NAMESPACE_DECL 00201 00202 #if defined (__ACE_INLINE__) 00203 #include "ace/Framework_Component.inl" 00204 #endif /* __ACE_INLINE__ */ 00205 00206 // Include the templates classes at this point. 00207 #include "ace/Framework_Component_T.h" 00208 00209 #include /**/ "ace/post.h" 00210 #endif /* ACE_FRAMEWORK_COMPONENT_H */