Use override/default for RTPortableServer
[ACE_TAO.git] / ACE / ace / Service_Gestalt.h
blobc31e0ef1a88861c32e143906cec79f4c2de6b89b
1 // -*- C++ -*-
3 //====================================================================
4 /**
5 * @file Service_Gestalt.h
7 * @author Iliyan Jeliazkov <iliyan@ociweb.com>
8 */
9 //====================================================================
11 #ifndef ACE_SERVICE_GESTALT_H
12 #define ACE_SERVICE_GESTALT_H
14 #include /**/ "ace/pre.h"
16 #include /**/ "ace/config-all.h"
17 #include "ace/Default_Constants.h"
19 #if !defined (ACE_LACKS_PRAGMA_ONCE)
20 # pragma once
21 #endif /* ACE_LACKS_PRAGMA_ONCE */
23 #include "ace/SString.h"
24 #include "ace/Unbounded_Queue.h"
25 #include "ace/Unbounded_Set.h"
26 #include "ace/Service_Repository.h"
27 #include "ace/Singleton.h"
28 #include "ace/OS_NS_signal.h"
29 #include "ace/Synch_Traits.h"
30 #include "ace/Atomic_Op.h"
31 #include "ace/Guard_T.h"
33 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
35 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
36 class ACE_Service_Type_Factory;
37 class ACE_Location_Node;
38 #else
39 class ACE_XML_Svc_Conf;
40 class ACE_DLL;
41 #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */
43 class ACE_Static_Svc_Descriptor;
44 class ACE_Svc_Conf_Param;
46 /**
47 * @class ACE_Service_Gestalt
49 * @brief Supplies common server operations for dynamic and static
50 * configuration of services.
52 * The Gestalt embodies the concept of configuration context. On one
53 * hand, it is a flat namespace, where names correspond to a Service
54 * Object instance. A Gestalt owns the Service Repository instance,
55 * which in turn owns the Service Object instances.
57 * Another aspect of a Gestalt is its responsibility for
58 * record-keeping and accounting for the meta-data, necessary for
59 * locating, removing or instantiating a service.
61 * A repository underlies an instance of a gestalt and its lifetime
62 * may or may not be bounded by the lifetime of the gestalt, that owns
63 * it. This feature is important for the derived classes and the
64 * Service Config in particular.
66 class ACE_Export ACE_Service_Gestalt : private ACE_Copy_Disabled
68 public:
69 enum
71 MAX_SERVICES = ACE_DEFAULT_SERVICE_REPOSITORY_SIZE
74 enum
76 DEFAULT_SIZE = ACE_DEFAULT_SERVICE_GESTALT_SIZE
79 /// Constructor either associates the instance with the process-wide
80 /// singleton instance of ACE_Service_Repository, or creates and
81 /// manages its own instance of the specified size.
82 ACE_Service_Gestalt (size_t size = DEFAULT_SIZE,
83 bool svc_repo_is_owned = true,
84 bool no_static_svcs = true);
86 /// Perform user-specified close activities and remove dynamic
87 /// memory.
88 ~ACE_Service_Gestalt ();
90 /// Dump the state of an object.
91 void dump () const;
93 /**
94 * Performs an open without parsing command-line arguments. The
95 * @a logger_key indicates where to write the logging output, which
96 * is typically either a STREAM pipe or a socket address. If
97 * @a ignore_static_svcs is true then static services are not loaded,
98 * otherwise, they are loaded. If @a ignore_default_svc_conf_file is
99 * true then the @c svc.conf configuration file will be ignored.
100 * Returns zero upon success, -1 if the file is not found or cannot
101 * be opened (errno is set accordingly), otherwise returns the
102 * number of errors encountered loading the services in the
103 * specified svc.conf configuration file. If @a ignore_debug_flag is
104 * true then the application is responsible for setting the
105 * ACE_Log_Msg::priority_mask appropriately.
107 int open (const ACE_TCHAR program_name[],
108 const ACE_TCHAR *logger_key = 0,
109 bool ignore_static_svcs = true,
110 bool ignore_default_svc_conf_file = false,
111 bool ignore_debug_flag = false);
114 * This is the primary entry point into the ACE_Service_Config (the
115 * constructor just handles simple initializations). It parses
116 * arguments passed in from @a argc and @a argv parameters. The
117 * arguments that are valid in a call to this method include:
119 * - '-b' Option to indicate that we should be a daemon. Note that when
120 * this option is used, the process will be daemonized before the
121 * service configuration file(s) are read. During daemonization,
122 * (on POSIX systems) the current directory will be changed to "/"
123 * so the caller should either fully specify the file names, or
124 * execute a @c chroot() to the appropriate directory.
125 * @sa ACE::daemonize().
126 * - '-d' Turn on debugging mode
127 * - '-f' Specifies a configuration file name other than the default
128 * svc.conf. Can be specified multiple times to use multiple files.
129 * If any configuration file is provided with this option then
130 * the default svc.conf will be ignored.
131 * - '-k' Specifies the rendezvous point to use for the ACE distributed
132 * logger.
133 * - '-y' Explicitly enables the use of static services. This flag
134 * overrides the @a ignore_static_svcs parameter value.
135 * - '-n' Explicitly disables the use of static services. This flag
136 * overrides the @a ignore_static_svcs parameter value.
137 * - '-p' Specifies a pathname which is used to store the process id.
138 * - '-s' Specifies a signal number other than SIGHUP to trigger reprocessing
139 * of the configuration file(s). Ignored for platforms that do not
140 * have POSIX signals, such as Windows.
141 * - '-S' Specifies a service directive string. Enclose the string in quotes
142 * and escape any embedded quotes with a backslash. This option
143 * specifies service directives without the need for a configuration
144 * file. Can be specified multiple times.
146 * Note: Options '-f' and '-S' complement each other. Directives
147 * from files and from '-S' option are processed together in the
148 * following order. First, the default file "./svc.conf" is
149 * evaluated if not ignored, then all files are processed in the
150 * order they are specified in '-f' @a argv parameter. Finally, all
151 * '-S' directive strings are executed in the order the directives
152 * appear in @a argv parameter.
154 * If no files or directives are added via the '-f' and '-S'
155 * arguments, and the default file is not ignored, it will be
156 * evaluated whether it exists or not, possibly causing a failure
157 * return. If any other directives are added then the default file
158 * will be evaluated only if it exists.
160 * @param argc The number of commandline arguments.
161 * @param argv The array with commandline arguments
162 * @param logger_key Indicates where to write the logging output,
163 * which is typically either a STREAM pipe or a
164 * socket address.
165 * @param ignore_static_svcs If true then static services are not loaded,
166 * otherwise, they are loaded.
167 * @param ignore_default_svc_conf_file If false then the @c ./svc.conf
168 * configuration file will be ignored.
169 * @param ignore_debug_flag If false then the application is responsible
170 * for setting the @c ACE_Log_Msg::priority_mask
171 * appropriately.
173 * @retval -1 A configuration file is not found or cannot
174 * be opened (errno is set accordingly).
175 * @retval 0 Success.
176 * @retval >0 The number of directive errors encountered while processing
177 * the service configuration file(s).
179 int open (int argc,
180 ACE_TCHAR *argv[],
181 const ACE_TCHAR *logger_key = 0,
182 bool ignore_static_svcs = true,
183 bool ignore_default_svc_conf_file = false,
184 bool ignore_debug_flag = false);
186 /// Has it been opened? Returns the difference between the times
187 /// open and close have been called on this instance
188 int is_opened ();
190 /// Declare the dynamic allocation hooks.
191 ACE_ALLOC_HOOK_DECLARE;
193 /// Process one service configuration @a directive, which is passed as
194 /// a string. Returns the number of errors that occurred.
195 int process_directive (const ACE_TCHAR directive[]);
197 /// Process one static service definition.
199 * Load a new static service.
201 * @param ssd Service descriptor, see the document of
202 * ACE_Static_Svc_Descriptor for more details.
204 * @param force_replace If set the new service descriptor replaces
205 * any previous instance in the repository.
207 * @return Returns -1 if the service cannot be 'loaded'.
209 int process_directive (const ACE_Static_Svc_Descriptor &ssd,
210 bool force_replace = false);
212 /// Process a file containing a list of service configuration
213 /// directives.
214 int process_file (const ACE_TCHAR file[]);
217 * Locate an entry with @a name in the table. If @a ignore_suspended
218 * is set then only consider services marked as resumed. If the
219 * caller wants the located entry, pass back a pointer to the
220 * located entry via @a srp. If @a name is not found, -1 is returned.
221 * If @a name is found, but it is suspended and the caller wants to
222 * ignore suspended services a -2 is returned.
224 int find (const ACE_TCHAR name[],
225 const ACE_Service_Type **srp = 0,
226 bool ignore_suspended = true) const;
229 * Handle the command-line options intended for the
230 * ACE_Service_Gestalt. Note that @c argv[0] is assumed to be the
231 * program name.
233 * The arguments that are valid in a call to this method are
234 * - '-d' Turn on debugging mode
235 * - '-f' Option to read in the list of svc.conf file names
236 * - '-k' Option to read a wide string where in the logger output can
237 * be written
238 * - '-y' Turn on the flag for a repository of statically
239 * linked services
240 * - '-n' Need not have a repository of statically linked services
241 * - '-S' Option to read in the list of services on the command-line
242 * Please observe the difference between options '-f' that looks
243 * for a list of files and here a list of services.
245 int parse_args (int argc, ACE_TCHAR *argv[]);
248 * Process (or re-process) service configuration requests that are
249 * provided in the svc.conf file(s). Returns the number of errors
250 * that occurred.
252 int process_directives (bool defunct_option = false);
254 /// Tidy up and perform last rites when ACE_Service_Config is shut
255 /// down. This method calls @c close_svcs. Returns 0.
256 int close ();
258 /// Registers a service descriptor for a static service object
259 int insert (ACE_Static_Svc_Descriptor *stsd);
261 // = Utility methods.
263 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
264 /// Dynamically link the shared object file and retrieve a pointer to
265 /// the designated shared object in this file. Also account for the
266 /// possibility to have static services registered when loading the DLL, by
267 /// ensuring that the dynamic service is registered before any of its
268 /// subordinate static services. Thus avoiding any finalization order
269 /// problems.
270 int initialize (const ACE_Service_Type_Factory *,
271 const ACE_TCHAR *parameters);
272 #endif /* (ACE_USES_CLASSIC_SVC_CONF == 1) */
274 /// Dynamically link the shared object file and retrieve a pointer to
275 /// the designated shared object in this file.
276 /// @deprecated
277 /// @note This is error-prone in the presense of dynamic services,
278 /// which in turn initialize their own static services. This method
279 /// will allow those static services to register *before* the dynamic
280 /// service that owns them. Upon finalization of the static services
281 /// the process will typically crash, because the dynamic service's
282 /// DLL may have been already released, together with the memory in
283 /// which the static services reside. It may not crash, for
284 /// instance, when the first static service to register is the same
285 /// as the dynamic service being loaded. You should be so lucky!
286 int initialize (const ACE_Service_Type *,
287 const ACE_TCHAR *parameters);
289 /// Initialize and activate a statically @a svc_name service.
290 int initialize (const ACE_TCHAR *svc_name,
291 const ACE_TCHAR *parameters);
293 /// Resume a @a svc_name that was previously suspended or has not yet
294 /// been resumed (e.g., a static service).
295 int resume (const ACE_TCHAR svc_name[]);
298 * Suspend @a svc_name. Note that this will not unlink the service
299 * from the daemon if it was dynamically linked, it will mark it as
300 * being suspended in the Service Repository and call the @c suspend()
301 * member function on the appropriate ACE_Service_Object. A
302 * service can be resumed later on by calling the @c resume() member
303 * function...
305 int suspend (const ACE_TCHAR svc_name[]);
307 /// Totally remove @a svc_name from the daemon by removing it
308 /// from the ACE_Reactor, and unlinking it if necessary.
309 int remove (const ACE_TCHAR svc_name[]);
312 * Using the supplied name, finds and (if needed) returns a pointer to a
313 * static service descriptor. Returns 0 for success and -1 for failure
315 int find_static_svc_descriptor (const ACE_TCHAR* name,
316 ACE_Static_Svc_Descriptor **ssd = 0) const;
318 struct Processed_Static_Svc
320 Processed_Static_Svc (const ACE_Static_Svc_Descriptor *);
321 ~Processed_Static_Svc ();
322 ACE_TCHAR * name_;
323 const ACE_Static_Svc_Descriptor *assd_;
324 ACE_ALLOC_HOOK_DECLARE;
327 /// Get the current ACE_Service_Repository held by this object.
328 ACE_Service_Repository* current_service_repository ();
330 protected:
331 int parse_args_i (int, ACE_TCHAR *argv[],
332 bool& ignore_default_svc_conf_file);
335 * Performs an open without parsing command-line arguments. The @a
336 * logger_key indicates where to write the logging output, which is
337 * typically either a STREAM pipe or a socket address. If @a
338 * ignore_default_svc_conf_file is non-0 then the "svc.conf" file
339 * will not be added by default. If @a ignore_debug_flag is non-0
340 * then the application is responsible for setting the @c
341 * ACE_Log_Msg::priority_mask() appropriately. Returns number of
342 * errors that occurred on failure and 0 otherwise.
344 int open_i (const ACE_TCHAR program_name[],
345 const ACE_TCHAR *logger_key = 0,
346 bool ignore_static_svcs = true,
347 bool ignore_default_svc_conf_file = false,
348 bool ignore_debug_flag = false);
350 /// Initialize the @c svc_conf_file_queue_ if necessary.
351 int init_svc_conf_file_queue ();
353 /// Add the default statically-linked services to the
354 /// ACE_Service_Repository.
355 int load_static_svcs ();
357 /// Process service configuration requests that were provided on the
358 /// command-line. Returns the number of errors that occurred.
359 int process_commandline_directives ();
361 /// Process a static directive without also inserting its descriptor
362 /// the global table. This avoids multiple additions when processing
363 /// directives in non-global gestalts.
364 int process_directive_i (const ACE_Static_Svc_Descriptor &ssd,
365 bool force_replace = false);
367 #if (ACE_USES_CLASSIC_SVC_CONF == 1)
368 /// This is the implementation function that process_directives()
369 /// and process_directive() both call. Returns the number of errors
370 /// that occurred.
371 int process_directives_i (ACE_Svc_Conf_Param *param);
372 #else
373 /// Helper function to dynamically link in the XML Service Configurator
374 /// parser.
375 ACE_XML_Svc_Conf* get_xml_svc_conf (ACE_DLL &d);
376 #endif /* ACE_USES_CLASSIC_SVC_CONF == 1 */
378 /// Dynamically link the shared object file and retrieve a pointer to
379 /// the designated shared object in this file.
380 int initialize_i (const ACE_Service_Type *sr, const ACE_TCHAR *parameters);
382 const ACE_Static_Svc_Descriptor* find_processed_static_svc (const ACE_TCHAR*);
383 void add_processed_static_svc (const ACE_Static_Svc_Descriptor *);
385 /// Performs the common initialization tasks for a new or previously
386 /// closed instance. Must not be virtual, as it is called from the
387 /// constructor.
388 int init_i ();
390 protected:
391 /// Maintain a queue of services to be configured from the
392 /// command-line.
393 typedef ACE_Unbounded_Queue<ACE_TString> ACE_SVC_QUEUE;
394 typedef ACE_Unbounded_Queue_Iterator<ACE_TString> ACE_SVC_QUEUE_ITERATOR;
396 /// Maintain a set of the statically linked service descriptors.
397 typedef ACE_Unbounded_Set<ACE_Static_Svc_Descriptor *>
398 ACE_STATIC_SVCS;
400 typedef ACE_Unbounded_Set_Iterator<ACE_Static_Svc_Descriptor *>
401 ACE_STATIC_SVCS_ITERATOR;
403 typedef ACE_Unbounded_Set<Processed_Static_Svc *>
404 ACE_PROCESSED_STATIC_SVCS;
406 typedef ACE_Unbounded_Set_Iterator<Processed_Static_Svc *>
407 ACE_PROCESSED_STATIC_SVCS_ITERATOR;
409 friend class ACE_Dynamic_Service_Base;
410 friend class ACE_Service_Object;
411 friend class ACE_Service_Config;
412 friend class ACE_Service_Config_Guard;
414 protected:
415 /// Do we own the service repository instance, or have only been
416 /// given a ptr to the singleton?
417 bool svc_repo_is_owned_;
419 /// Repository size is necessary, so that we can close (which may
420 /// destroy the repository instance), and then re-open again.
421 size_t svc_repo_size_;
423 /// Keep track of the number of times the instance has been
424 /// initialized (opened). "If so, we can't allow <yyparse> to be called since
425 /// it's not reentrant" is the original motivation, but that does not seem
426 /// to be the case anymore. This variable is incremented by the
427 /// <ACE_Service_Gestalt::open> method and decremented by the
428 /// <ACE_Service_Gestalt::close> method.
429 int is_opened_;
431 /// Indicates where to write the logging output. This is typically
432 /// either a STREAM pipe or a socket
433 const ACE_TCHAR *logger_key_;
435 /// Should we avoid loading the static services?
436 bool no_static_svcs_;
438 /// Queue of services specified on the command-line.
439 ACE_SVC_QUEUE* svc_queue_;
442 * Queue of svc.conf files specified on the command-line.
443 * @@ This should probably be made to handle unicode filenames...
445 ACE_SVC_QUEUE* svc_conf_file_queue_;
447 /// The service repository to hold the services.
448 ACE_Service_Repository* repo_;
450 /// Repository of statically linked services.
451 ACE_STATIC_SVCS* static_svcs_;
453 /// Repository of statically linked services for which process
454 /// directive was called, but the service is not already a member of
455 /// the static_svcs_ list.
456 ACE_PROCESSED_STATIC_SVCS* processed_static_svcs_;
458 /// Support for intrusive reference counting
459 ACE_Atomic_Op<ACE_SYNCH_MUTEX, long> refcnt_;
461 public:
462 static void intrusive_add_ref (ACE_Service_Gestalt*);
463 static void intrusive_remove_ref (ACE_Service_Gestalt*);
464 }; /* class ACE_Service_Gestalt */
468 * @class ACE_Service_Type_Dynamic_Guard
470 * @brief A forward service declaration guard.
472 * Helps to resolve an issue with hybrid services, i.e. dynamic
473 * services, accompanied by static services in the same DLL. Only
474 * automatic instances of this class are supposed to exist. Those are
475 * created during (dynamic) service initialization and serve to:
477 * (a) Ensure the service we are loading is ordered last in the
478 * repository, following any other services it may cause to register,
479 * as part of its own registration. This is a common case when
480 * loading dynamic services from DLLs - there are often static
481 * initializers, which register static services.
483 * (b) The SDG instance destructor detects if the dynamic service
484 * initialized successfully and "fixes-up" all the newly registered
485 * static services to hold a reference to the DLL, from which they
486 * have originated.
488 class ACE_Export ACE_Service_Type_Dynamic_Guard
490 public:
491 ACE_Service_Type_Dynamic_Guard (ACE_Service_Repository &r,
492 ACE_TCHAR const *name);
494 ~ACE_Service_Type_Dynamic_Guard ();
496 private:
497 ACE_Service_Repository & repo_;
498 size_t repo_begin_;
499 ACE_TCHAR const * const name_;
501 #if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
502 // FUZZ: disable check_for_ACE_Guard
503 ACE_Guard< ACE_Recursive_Thread_Mutex > repo_monitor_;
504 // FUZZ: enable check_for_ACE_Guard
505 #endif
508 ACE_END_VERSIONED_NAMESPACE_DECL
510 #if defined (__ACE_INLINE__)
511 #include "ace/Service_Gestalt.inl"
512 #endif /* __ACE_INLINE__ */
515 #include /**/ "ace/post.h"
517 #endif /* ACE_SERVICE_GESTALT_H */