00001 // -*- C++ -*- 00002 00003 //============================================================================= 00004 /** 00005 * @file Service_Repository.h 00006 * 00007 * $Id: Service_Repository.h 91016 2010-07-06 11:29:50Z johnnyw $ 00008 * 00009 * @author Douglas C. Schmidt <schmidt@cs.wustl.edu> 00010 */ 00011 //============================================================================= 00012 00013 #ifndef ACE_SERVICE_REPOSITORY_H 00014 #define ACE_SERVICE_REPOSITORY_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include /**/ "ace/ACE_export.h" 00019 00020 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00021 # pragma once 00022 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00023 00024 #include "ace/Default_Constants.h" 00025 #include "ace/Recursive_Thread_Mutex.h" 00026 #include "ace/Array_Map.h" 00027 00028 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00029 00030 class ACE_Service_Type; 00031 class ACE_DLL; 00032 00033 #define ACE_Component_Repository ACE_Service_Repository 00034 /** 00035 * @class ACE_Service_Repository 00036 * 00037 * @brief Contains all the services offered by a Service 00038 * Configurator-based application. 00039 * 00040 * This class contains a vector of ACE_Service_Types *'s and 00041 * allows an administrative entity to centrally manage and 00042 * control the behavior of application services. Note that if 00043 * services are removed from the middle of the repository the 00044 * order won't necessarily be maintained since the @a remove 00045 * method performs compaction. However, the common case is not 00046 * to remove services, so typically they are deleted in the 00047 * reverse order that they were added originally. 00048 */ 00049 class ACE_Export ACE_Service_Repository 00050 { 00051 public: 00052 friend class ACE_Service_Repository_Iterator; 00053 00054 enum 00055 { 00056 DEFAULT_SIZE = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE 00057 }; 00058 00059 // = Initialization and termination methods. 00060 /// Initialize the repository. 00061 ACE_Service_Repository (size_t size = DEFAULT_SIZE); 00062 00063 /// Initialize the repository. 00064 int open (size_t size = DEFAULT_SIZE); 00065 00066 /// Close down the repository and free up dynamically allocated 00067 /// resources. 00068 ~ACE_Service_Repository (void); 00069 00070 /// Close down the repository and free up dynamically allocated 00071 /// resources. 00072 int close (void); 00073 00074 /// Finalize all the services by calling fini() and deleting 00075 /// dynamically allocated services. 00076 int fini (void); 00077 00078 /// Get pointer to a process-wide ACE_Service_Repository. 00079 static ACE_Service_Repository * instance 00080 (size_t size = ACE_Service_Repository::DEFAULT_SIZE); 00081 00082 /// Set pointer to a process-wide ACE_Service_Repository and return 00083 /// existing pointer. 00084 static ACE_Service_Repository *instance (ACE_Service_Repository *); 00085 00086 /// Delete the dynamically allocated Singleton. 00087 static void close_singleton (void); 00088 00089 // = Search structure operations (all acquire locks as necessary). 00090 00091 /// Insert a new service record. Returns -1 when the service repository 00092 /// is full and 0 on success. 00093 int insert (const ACE_Service_Type *sr); 00094 00095 /** 00096 * Locate a named entry in the service table, optionally ignoring 00097 * suspended entries. 00098 * 00099 * @param name The name of the service to search for. 00100 * @param srp Optional; if not 0, it is a pointer to a location 00101 * to receive the ACE_Service_Type pointer for the 00102 * located service. Meaningless if this method 00103 * returns -1. 00104 * @param ignore_suspended If true, the search ignores suspended services. 00105 * 00106 * @retval 0 Named service was located. 00107 * @retval -1 Named service was not found. 00108 * @retval -2 Named service was found, but is suspended and 00109 * @a ignore_suspended is true. 00110 */ 00111 int find (const ACE_TCHAR name[], 00112 const ACE_Service_Type **srp = 0, 00113 bool ignore_suspended = true) const; 00114 00115 /// Remove an existing service record. If @a sr == 0, the service record 00116 /// is deleted before control is returned to the caller. If @a sr != 0, 00117 /// the service's record is removed from the repository, but not deleted; 00118 /// *sr receives the service record pointer and the caller is responsible 00119 /// for properly disposing of it. 00120 int remove (const ACE_TCHAR name[], ACE_Service_Type **sr = 0); 00121 00122 // = Liveness control 00123 /// Resume a service record. 00124 int resume (const ACE_TCHAR name[], const ACE_Service_Type **srp = 0); 00125 00126 /// Suspend a service record. 00127 int suspend (const ACE_TCHAR name[], const ACE_Service_Type **srp = 0); 00128 00129 /// Return the current size of the repository. 00130 size_t current_size (void) const; 00131 00132 /// Dump the state of an object. 00133 void dump (void) const; 00134 00135 /// Declare the dynamic allocation hooks. 00136 ACE_ALLOC_HOOK_DECLARE; 00137 00138 protected: 00139 00140 friend class ACE_Service_Type_Dynamic_Guard; 00141 00142 /// Remove an existing service record. It requires @a sr != 0, which 00143 /// receives the service record pointer and the caller is 00144 /// responsible for properly disposing of it. 00145 int remove_i (const ACE_TCHAR[], ACE_Service_Type **sr); 00146 00147 /** 00148 * Locate a named entry in the service table, optionally ignoring 00149 * suspended entries. 00150 * 00151 * @param service_name The name of the service to search for. 00152 * @param slot Receives the position index of the service if it 00153 * is found. Contents are meaningless if this method 00154 * returns -1. 00155 * @param srp Optional; if not 0, it is a pointer to a location 00156 * to receive the ACE_Service_Type pointer for the 00157 * located service. Meaningless if this method 00158 * returns -1. 00159 * @param ignore_suspended If true, the search ignores suspended services. 00160 * 00161 * @retval 0 Named service was located; index in the table is set in 00162 * @a slot. 00163 * @retval -1 Named service was not found. 00164 * @retval -2 Named service was found, but is suspended and 00165 * @a ignore_suspended is true. 00166 */ 00167 int find_i (const ACE_TCHAR service_name[], 00168 size_t &slot, 00169 const ACE_Service_Type **srp = 0, 00170 bool ignore_suspended = true) const; 00171 00172 /// @brief Relocate (static) services to another DLL. 00173 /// 00174 /// If any have been registered in the context of a "forward 00175 /// declaration" guard, those really aren't static services. Their 00176 /// code is in the DLL's code segment, or in one of the dependent 00177 /// DLLs. Therefore, such services need to be associated with the 00178 /// proper DLL in order to prevent failures upon finalization. The 00179 /// method locks the repo. 00180 /// 00181 /// Works by having the service type keep a reference to a specific 00182 /// DLL. No locking, caller makes sure calling it is safe. You can 00183 /// forcefully relocate any DLLs in the given range, not only the 00184 /// static ones - but that will cause Very Bad Things (tm) to happen. 00185 int relocate_i (size_t begin, 00186 size_t end, 00187 const ACE_DLL &adll); 00188 00189 /// The typedef of the array used to store the services. 00190 typedef ACE_Array_Map <size_t, const ACE_Service_Type*> array_type; 00191 00192 /// Contains all the configured services. 00193 array_type service_array_; 00194 00195 /// Pointer to a process-wide ACE_Service_Repository. 00196 static ACE_Service_Repository *svc_rep_; 00197 00198 /// Must delete the @c svc_rep_ if true. 00199 static bool delete_svc_rep_; 00200 00201 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0) 00202 /// Synchronization variable for the MT_SAFE Repository 00203 mutable ACE_Recursive_Thread_Mutex lock_; 00204 #endif /* ACE_MT_SAFE */ 00205 }; 00206 00207 /** 00208 * @class ACE_Service_Repository_Iterator 00209 * 00210 * @brief Iterate through the ACE_Service_Repository. 00211 * 00212 * Make sure not to delete entries as the iteration is going on 00213 * since this class is not designed as a robust iterator. 00214 */ 00215 class ACE_Export ACE_Service_Repository_Iterator 00216 { 00217 public: 00218 // = Initialization and termination methods. 00219 /// Constructor initializes the iterator. 00220 ACE_Service_Repository_Iterator (ACE_Service_Repository &sr, 00221 bool ignored_suspended = true); 00222 00223 /// Destructor. 00224 ~ACE_Service_Repository_Iterator (void); 00225 00226 00227 public: 00228 // = Iteration methods. 00229 00230 /// Pass back the @a next_item that hasn't been seen in the repository. 00231 /// Returns 0 when all items have been seen, else 1. 00232 int next (const ACE_Service_Type *&next_item); 00233 00234 /// Returns 1 when all items have been seen, else 0. 00235 int done (void) const; 00236 00237 /// Move forward by one element in the repository. Returns 0 when all the 00238 /// items in the set have been seen, else 1. 00239 int advance (void); 00240 00241 /// Dump the state of an object. 00242 void dump (void) const; 00243 00244 /// Declare the dynamic allocation hooks. 00245 ACE_ALLOC_HOOK_DECLARE; 00246 00247 private: 00248 bool valid (void) const; 00249 00250 private: 00251 ACE_Service_Repository_Iterator (const ACE_Service_Repository_Iterator&); 00252 00253 /// Reference to the Service Repository we are iterating over. 00254 ACE_Service_Repository &svc_rep_; 00255 00256 /// Next index location that we haven't yet seen. 00257 size_t next_; 00258 00259 /// Are we ignoring suspended services? 00260 bool const ignore_suspended_; 00261 }; 00262 00263 ACE_END_VERSIONED_NAMESPACE_DECL 00264 00265 #if defined (__ACE_INLINE__) 00266 #include "ace/Service_Repository.inl" 00267 #endif /* __ACE_INLINE__ */ 00268 00269 #include /**/ "ace/post.h" 00270 00271 #endif /* _SERVICE_REPOSITORY_H */