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