00001 // -*- C++ -*- 00002 00003 //==================================================================== 00004 /** 00005 * @file Service_Gestalt.h 00006 * 00007 * Service_Gestalt.h,v 4.9 2006/06/06 21:57:21 shuston Exp 00008 * 00009 * @author Iliyan Jeliazkov <iliyan@ociweb.com> 00010 */ 00011 //==================================================================== 00012 00013 #ifndef ACE_SERVICE_GESTALT_H 00014 #define ACE_SERVICE_GESTALT_H 00015 00016 #include /**/ "ace/pre.h" 00017 00018 #include "ace/config-all.h" 00019 #include "ace/Default_Constants.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Auto_Ptr.h" 00026 #include "ace/SString.h" 00027 #include "ace/Unbounded_Queue.h" 00028 #include "ace/Service_Repository.h" 00029 #include "ace/Singleton.h" 00030 #include "ace/OS_NS_signal.h" 00031 #include "ace/Synch_Traits.h" 00032 00033 ACE_BEGIN_VERSIONED_NAMESPACE_DECL 00034 00035 class ACE_Service_Type_Factory; 00036 class ACE_Static_Svc_Descriptor; 00037 class ACE_Svc_Conf_Param; 00038 00039 class ACE_Service_Gestalt; 00040 00041 /** 00042 * @class ACE_Service_Gestalt 00043 * 00044 * @brief Supplies common server operations for dynamic and static 00045 * configuration of services. 00046 */ 00047 class ACE_Export ACE_Service_Gestalt 00048 { 00049 private: 00050 /** 00051 * Not implemented to enforce no copying 00052 */ 00053 ACE_UNIMPLEMENTED_FUNC (ACE_Service_Gestalt(const ACE_Service_Gestalt&)) 00054 ACE_UNIMPLEMENTED_FUNC (ACE_Service_Gestalt& operator=(const ACE_Service_Gestalt&)) 00055 00056 public: 00057 enum 00058 { 00059 MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE 00060 }; 00061 00062 /// Constructor either associates the instance with the process-wide 00063 /// singleton instance of ACE_Service_Repository, or creates and 00064 /// manages its own instance of the specified size. 00065 ACE_Service_Gestalt (size_t size, 00066 bool svc_repo_is_owned = true, 00067 bool no_static_svcs = true); 00068 00069 /// Perform user-specified close activities and remove dynamic 00070 /// memory. 00071 virtual ~ACE_Service_Gestalt (void); 00072 00073 /// Dump the state of an object. 00074 void dump (void) const; 00075 00076 /** 00077 * Performs an open without parsing command-line arguments. The 00078 * @a logger_key indicates where to write the logging output, which 00079 * is typically either a STREAM pipe or a socket address. If 00080 * @a ignore_static_svcs is 1 then static services are not loaded, 00081 * otherwise, they are loaded. If @a ignore_default_svc_conf_file is 00082 * non-0 then the <svc.conf> configuration file will be ignored. 00083 * Returns zero upon success, -1 if the file is not found or cannot 00084 * be opened (errno is set accordingly), otherwise returns the 00085 * number of errors encountered loading the services in the 00086 * specified svc.conf configuration file. If @a ignore_debug_flag is 00087 * non-0 then the application is responsible for setting the 00088 * <ACE_Log_Msg::priority_mask> appropriately. 00089 */ 00090 int open (const ACE_TCHAR program_name[], 00091 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, 00092 int ignore_static_svcs = 1, 00093 int ignore_default_svc_conf_file = 0, 00094 int ignore_debug_flag = 0); 00095 00096 /** 00097 * This is the primary entry point into the ACE_Service_Config (the 00098 * constructor just handles simple initializations). It parses 00099 * arguments passed in from @a argc and @a argv parameters. The 00100 * arguments that are valid in a call to this method include: 00101 * 00102 * - '-b' Option to indicate that we should be a daemon. Note that when 00103 * this option is used, the process will be daemonized before the 00104 * service configuration file(s) are read. During daemonization, 00105 * (on POSIX systems) the current directory will be changed to "/" 00106 * so the caller should either fully specify the file names, or 00107 * execute a @c chroot() to the appropriate directory. 00108 * @sa ACE::daemonize(). 00109 * - '-d' Turn on debugging mode 00110 * - '-f' Specifies a configuration file name other than the default 00111 * svc.conf. Can be specified multiple times to use multiple files. 00112 * - '-k' Specifies the rendezvous point to use for the ACE distributed 00113 * logger. 00114 * - '-y' Explicitly enables the use of static services. This flag 00115 * overrides the @a ignore_static_svcs parameter value. 00116 * - '-n' Explicitly disables the use of static services. This flag 00117 * overrides the @a ignore_static_svcs parameter value. 00118 * - '-p' Specifies a pathname which is used to store the process id. 00119 * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing 00120 * of the configuration file(s). Ignored for platforms that do not 00121 * have POSIX signals, such as Windows. 00122 * - '-S' Specifies a service directive string. Enclose the string in quotes 00123 * and escape any embedded quotes with a backslash. This option 00124 * specifies service directives without the need for a configuration 00125 * file. 00126 * 00127 * @param argc The number of commandline arguments. 00128 * @param argv The array with commandline arguments 00129 * @param logger_key Indicates where to write the logging output, 00130 * which is typically either a STREAM pipe or a 00131 * socket address. 00132 * @param ignore_static_svcs If 1 then static services are not loaded, 00133 * otherwise, they are loaded. 00134 * @param ignore_default_svc_conf_file If non-0 then the @c svc.conf 00135 * configuration file will be ignored. 00136 * @param ignore_debug_flag If non-0 then the application is responsible 00137 * for setting the @c ACE_Log_Msg::priority_mask 00138 * appropriately. 00139 * 00140 * @retval -1 The configuration file is not found or cannot 00141 * be opened (errno is set accordingly). 00142 * @retval 0 Success. 00143 * @retval >0 The number of errors encountered while processing 00144 * the service configuration file(s). 00145 */ 00146 int open (int argc, 00147 ACE_TCHAR *argv[], 00148 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, 00149 int ignore_static_svcs = 1, 00150 int ignore_default_svc_conf_file = 0, 00151 int ignore_debug_flag = 0); 00152 00153 /// Has it been opened? Returns the difference between the times 00154 /// open and close have been called on this instance 00155 int is_opened (void); 00156 00157 /// Declare the dynamic allocation hooks. 00158 ACE_ALLOC_HOOK_DECLARE; 00159 00160 /// Process one service configuration @a directive, which is passed as 00161 /// a string. Returns the number of errors that occurred. 00162 int process_directive (const ACE_TCHAR directive[]); 00163 00164 /// Process one static service definition. 00165 /** 00166 * Load a new static service. 00167 * 00168 * @param ssd Service descriptor, see the document of 00169 * ACE_Static_Svc_Descriptor for more details. 00170 * 00171 * @param force_replace If set the new service descriptor replaces 00172 * any previous instance in the repository. 00173 * 00174 * @return Returns -1 if the service cannot be 'loaded'. 00175 */ 00176 int process_directive (const ACE_Static_Svc_Descriptor &ssd, 00177 int force_replace = 0); 00178 00179 /// Process a file containing a list of service configuration 00180 /// directives. 00181 int process_file (const ACE_TCHAR file[]); 00182 00183 /** 00184 * Locate an entry with <name> in the table. If <ignore_suspended> 00185 * is set then only consider services marked as resumed. If the 00186 * caller wants the located entry, pass back a pointer to the 00187 * located entry via <srp>. If <name> is not found, -1 is returned. 00188 * If <name> is found, but it is suspended and the caller wants to 00189 * ignore suspended services a -2 is returned. 00190 */ 00191 int find (const ACE_TCHAR name[], 00192 const ACE_Service_Type **srp = 0, 00193 int ignore_suspended = 1) const; 00194 00195 /** 00196 * Handle the command-line options intended for the 00197 * <ACE_Service_Config>. Note that <argv[0]> is assumed to be the 00198 * program name. 00199 * The arguments that are valid in a call to this method are 00200 * - '-b' Option to indicate that we should be a daemon 00201 * - '-d' Turn on debugging mode 00202 * - '-f' Option to read in the list of svc.conf file names 00203 * - '-k' Option to read a wide string where in the logger output can 00204 * be written 00205 * - '-y' Turn on the flag for a repository of statically 00206 * linked services 00207 * - '-n' Need not have a repository of statically linked services 00208 * - '-S' Option to read in the list of services on the command-line 00209 * Please observe the difference between options '-f' that looks 00210 * for a list of files and here a list of services. 00211 */ 00212 int parse_args (int, ACE_TCHAR *argv[]); 00213 00214 /** 00215 * Process (or re-process) service configuration requests that are 00216 * provided in the svc.conf file(s). Returns the number of errors 00217 * that occurred. 00218 */ 00219 int process_directives (void); 00220 00221 /// Tidy up and perform last rites when ACE_Service_Config is shut 00222 /// down. This method calls <close_svcs>. Returns 0. 00223 int close (void); 00224 00225 00226 // Registers a service descriptor for a static service object 00227 int insert (ACE_Static_Svc_Descriptor *stsd); 00228 00229 // = Utility methods. 00230 /// Dynamically link the shared object file and retrieve a pointer to 00231 /// the designated shared object in this file. Also account for the 00232 /// possiblity to have static services registered when loading the DLL, by 00233 /// ensuring that the dynamic sevice is registered before any of its 00234 /// subordibnate static services. Thus avoiding any finalization order 00235 /// problems. 00236 int initialize (const ACE_Service_Type_Factory *, 00237 const ACE_TCHAR *parameters); 00238 00239 // Dynamically link the shared object file and retrieve a pointer to 00240 // the designated shared object in this file. 00241 // @obsolete 00242 // @note This is error-prone in the presense of dynamic 00243 // services with their own static services. This method will allow those 00244 // static services to register *before* the dynamic service that owns them. 00245 // Upon finalization of the static services the process may crash, because 00246 // the dynamic service's DLL may have been already released, together with 00247 // the memory in which the static services reside. 00248 // It may not crash, for instance, when the first static service to register 00249 // is the same as the dynamic service being loaded. You should be so lucky! 00250 int initialize (const ACE_Service_Type *, 00251 const ACE_TCHAR *parameters); 00252 00253 /// Initialize and activate a statically @a svc_name service. 00254 int initialize (const ACE_TCHAR *svc_name, 00255 const ACE_TCHAR *parameters); 00256 00257 /// Resume a @a svc_name that was previously suspended or has not yet 00258 /// been resumed (e.g., a static service). 00259 int resume (const ACE_TCHAR svc_name[]); 00260 00261 /** 00262 * Suspend @a svc_name. Note that this will not unlink the service 00263 * from the daemon if it was dynamically linked, it will mark it as 00264 * being suspended in the Service Repository and call the <suspend> 00265 * member function on the appropriate <ACE_Service_Object>. A 00266 * service can be resumed later on by calling the <RESUME> member 00267 * function... 00268 */ 00269 int suspend (const ACE_TCHAR svc_name[]); 00270 00271 /// Totally remove @a svc_name from the daemon by removing it 00272 /// from the ACE_Reactor, and unlinking it if necessary. 00273 int remove (const ACE_TCHAR svc_name[]); 00274 00275 /** 00276 * Using the supplied name, finds and (if needed) returns a pointer to a 00277 * static service descriptor. Returns 0 for success and -1 for failure 00278 */ 00279 int find_static_svc_descriptor (const ACE_TCHAR* name, 00280 ACE_Static_Svc_Descriptor **ssd = 0) const; 00281 00282 struct Processed_Static_Svc 00283 { 00284 Processed_Static_Svc (const ACE_Static_Svc_Descriptor *); 00285 ~Processed_Static_Svc (void); 00286 ACE_TCHAR * name_; 00287 const ACE_Static_Svc_Descriptor *assd_; 00288 }; 00289 00290 protected: 00291 00292 /** 00293 * 00294 */ 00295 virtual int parse_args_i (int, ACE_TCHAR *argv[]); 00296 00297 /** 00298 * Performs an open without parsing command-line arguments. The 00299 * @a logger_key indicates where to write the logging output, which 00300 * is typically either a STREAM pipe or a socket address. If 00301 * @a ignore_default_svc_conf_file is non-0 then the "svc.conf" file 00302 * will be ignored. If @a ignore_debug_flag is non-0 then the 00303 * application is responsible for setting the 00304 * @c ACE_Log_Msg::priority_mask() appropriately. Returns number of 00305 * errors that occurred on failure and 0 otherwise. 00306 */ 00307 virtual int open_i (const ACE_TCHAR program_name[], 00308 const ACE_TCHAR *logger_key = ACE_DEFAULT_LOGGER_KEY, 00309 bool ignore_static_svcs = true, 00310 bool ignore_default_svc_conf_file = false, 00311 bool ignore_debug_flag = false); 00312 00313 /// Initialize the <svc_conf_file_queue_> if necessary. 00314 int init_svc_conf_file_queue (void); 00315 00316 /// Add the default statically-linked services to the 00317 /// ACE_Service_Repository. 00318 int load_static_svcs (void); 00319 00320 /// Process service configuration requests that were provided on the 00321 /// command-line. Returns the number of errors that occurred. 00322 int process_commandline_directives (void); 00323 00324 /// Process a static directive without also inserting its descriptor 00325 /// the global table. This avoids multiple additions when processing 00326 /// directives in non-global gestalts. 00327 int process_directive_i (const ACE_Static_Svc_Descriptor &ssd, 00328 int force_replace = 0); 00329 00330 #if (ACE_USES_CLASSIC_SVC_CONF == 1) 00331 /// This is the implementation function that process_directives() 00332 /// and process_directive() both call. Returns the number of errors 00333 /// that occurred. 00334 int process_directives_i (ACE_Svc_Conf_Param *param); 00335 #else 00336 /// Helper function to dynamically link in the XML Service Configurator 00337 /// parser. 00338 ACE_XML_Svc_Conf *get_xml_svc_conf (ACE_DLL &d); 00339 #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */ 00340 00341 // Dynamically link the shared object file and retrieve a pointer to 00342 // the designated shared object in this file. 00343 int initialize_i (const ACE_Service_Type *sr, const ACE_TCHAR *parameters); 00344 00345 const ACE_Static_Svc_Descriptor* 00346 find_processed_static_svc (const ACE_TCHAR* ); 00347 00348 void add_processed_static_svc (const ACE_Static_Svc_Descriptor *); 00349 00350 protected: 00351 00352 // Maintain a queue of services to be configured from the 00353 // command-line. 00354 typedef ACE_Unbounded_Queue<ACE_TString> ACE_SVC_QUEUE; 00355 typedef ACE_Unbounded_Queue_Iterator<ACE_TString> ACE_SVC_QUEUE_ITERATOR; 00356 00357 // Maintain a set of the statically linked service descriptors. 00358 typedef ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *> 00359 ACE_STATIC_SVCS; 00360 00361 typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *> 00362 ACE_STATIC_SVCS_ITERATOR; 00363 00364 typedef ACE_Unbounded_Set<Processed_Static_Svc *> 00365 ACE_PROCESSED_STATIC_SVCS; 00366 00367 typedef ACE_Unbounded_Set_Iterator<Processed_Static_Svc *> 00368 ACE_PROCESSED_STATIC_SVCS_ITERATOR; 00369 00370 friend class ACE_Dynamic_Service_Base; 00371 friend class ACE_Service_Object; 00372 friend class ACE_Service_Config_Guard; 00373 00374 protected: 00375 00376 /// Do we own the service repository instance or have only been given a ptr 00377 /// to the singleton one? 00378 bool svc_repo_is_owned_; 00379 00380 /// Keep track of the number of times the instance has been 00381 /// initialized (opened). "If so, we can't allow <yyparse> to be called since 00382 /// it's not reentrant" is the original motivation, but that does not seem 00383 /// to be the case anymore. This variable is incremented by the 00384 /// <ACE_Service_Gestalt::open> method and decremented by the 00385 /// <ACE_Service_Gestalt::close> method. 00386 int is_opened_; 00387 00388 /// Indicates where to write the logging output. This is typically 00389 /// either a STREAM pipe or a socket 00390 const ACE_TCHAR *logger_key_; 00391 00392 /// Should we avoid loading the static services? 00393 int no_static_svcs_; 00394 00395 /// Queue of services specified on the command-line. 00396 ACE_SVC_QUEUE* svc_queue_; 00397 00398 /** Queue of svc.conf files specified on the command-line. 00399 * @@ This should probably be made to handle unicode filenames... 00400 */ 00401 ACE_SVC_QUEUE* svc_conf_file_queue_; 00402 00403 /// The service repository to hold the services. 00404 ACE_Service_Repository* repo_; 00405 00406 /// Repository of statically linked services. 00407 ACE_STATIC_SVCS* static_svcs_; 00408 00409 /// Repository of statically linked services for which process 00410 /// directive was called, but the service is not already a member of 00411 /// the static_svcs_ list. 00412 ACE_PROCESSED_STATIC_SVCS* processed_static_svcs_; 00413 00414 }; /* class ACE_Service_Gestalt */ 00415 00416 00417 class ACE_Location_Node; 00418 00419 // A helper class used to safely register dynamic services, which may contains 00420 // subordinate static services. It is used to capture the necessary data during 00421 // the parsing, but perform the actuall instantiation later. 00422 class ACE_Service_Type_Factory 00423 { 00424 public: 00425 ACE_Service_Type_Factory (ACE_TCHAR const *name, 00426 int type, 00427 ACE_Location_Node *location, 00428 int active); 00429 00430 ~ACE_Service_Type_Factory (void); 00431 00432 ACE_Service_Type *make_service_type (ACE_Service_Gestalt *pcfg) const; 00433 00434 ACE_TCHAR const* name (void) const; 00435 00436 /// Declare the dynamic allocation hooks. 00437 ACE_ALLOC_HOOK_DECLARE; 00438 00439 private: 00440 00441 /** 00442 * Not implemented to enforce no copying 00443 */ 00444 ACE_UNIMPLEMENTED_FUNC 00445 (ACE_Service_Type_Factory(const ACE_Service_Type_Factory&)) 00446 00447 ACE_UNIMPLEMENTED_FUNC 00448 (ACE_Service_Type_Factory& operator=(const ACE_Service_Type_Factory&)) 00449 00450 private: 00451 ACE_TString name_; 00452 int type_; 00453 ACE_Auto_Ptr<ACE_Location_Node> location_; 00454 int is_active_; 00455 }; 00456 00457 00458 ACE_END_VERSIONED_NAMESPACE_DECL 00459 00460 #if defined (__ACE_INLINE__) 00461 #include "ace/Service_Gestalt.inl" 00462 #endif /* __ACE_INLINE__ */ 00463 00464 00465 #include /**/ "ace/post.h" 00466 00467 #endif /* ACE_SERVICE_GESTALT_H */