Service_Gestalt.h

Go to the documentation of this file.
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 */

Generated on Thu Nov 9 09:42:03 2006 for ACE by doxygen 1.3.6