Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Connector.h
blob2903ad6a750ddf21790f09a212650c766106aa54
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file Connector.h
7 * @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
8 */
9 //=============================================================================
11 #ifndef ACE_CONNECTOR_H
12 #define ACE_CONNECTOR_H
14 #include /**/ "ace/pre.h"
16 #include "ace/Service_Object.h"
18 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 # pragma once
20 #endif /* ACE_LACKS_PRAGMA_ONCE */
22 #include "ace/Strategies_T.h"
23 #include "ace/Synch_Options.h"
24 #include "ace/Unbounded_Set.h"
26 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
28 /**
29 * @class ACE_Connector_Base
31 * @brief This base interface allows ACE_NonBlocking_Connect_Handler
32 * to only care about the SVC_HANDLER template parameter of the
33 * ACE_Connector. Otherwise, ACE_NonBlocking_Connect_Handler would
34 * have to be configured with all the template parameters that
35 * ACE_Connector is configured with.
37 template <class SVC_HANDLER>
38 class ACE_Connector_Base
40 public:
41 virtual ~ACE_Connector_Base () = default;
43 /// Initialize the Svc_Handler.
44 virtual void initialize_svc_handler (ACE_HANDLE handle,
45 SVC_HANDLER *svc_handler) = 0;
47 /// Return the handle set representing the non-blocking connects in
48 /// progress.
49 virtual ACE_Unbounded_Set<ACE_HANDLE> &non_blocking_handles () = 0;
52 /**
53 * @class ACE_NonBlocking_Connect_Handler
55 * @brief Performs non-blocking connects on behalf of the Connector.
57 template <class SVC_HANDLER>
58 class ACE_NonBlocking_Connect_Handler : public ACE_Event_Handler
60 public:
61 /// Constructor.
62 ACE_NonBlocking_Connect_Handler (ACE_Connector_Base<SVC_HANDLER> &connector,
63 SVC_HANDLER *,
64 long timer_id);
66 /// Destructor.
67 ~ACE_NonBlocking_Connect_Handler ();
69 /// Close up and return underlying SVC_HANDLER through @c sh.
70 /**
71 * If the return value is true the close was performed successfully,
72 * implying that this object was removed from the reactor and thereby
73 * (by means of reference counting decremented to 0) deleted.
74 * If the return value is false, the close was not successful.
75 * The @c sh does not have any connection to the return
76 * value. The argument will return a valid svc_handler object if a
77 * valid one exists within the object. Returning a valid svc_handler
78 * pointer also invalidates the svc_handler contained in this
79 * object.
81 bool close (SVC_HANDLER *&sh);
83 /// Get SVC_HANDLER.
84 SVC_HANDLER *svc_handler ();
86 /// Get handle.
87 ACE_HANDLE handle ();
89 /// Set handle.
90 void handle (ACE_HANDLE);
92 /// Get timer id.
93 long timer_id ();
95 /// Set timer id.
96 void timer_id (long timer_id);
98 /// Called by ACE_Reactor when asynchronous connections fail.
99 virtual int handle_input (ACE_HANDLE);
101 /// Called by ACE_Dev_Poll_Reactor when asynchronous connections fail.
102 virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);
104 /// Called by ACE_Reactor when asynchronous connections succeed.
105 virtual int handle_output (ACE_HANDLE);
107 /// Called by ACE_Reactor when asynchronous connections suceeds (on
108 /// some platforms only).
109 virtual int handle_exception (ACE_HANDLE fd);
111 /// This method is called if a connection times out before
112 /// completing.
113 virtual int handle_timeout (const ACE_Time_Value &tv, const void *arg);
115 /// Should Reactor resume us if we have been suspended before the upcall?
116 virtual int resume_handler ();
118 /// Dump the state of an object.
119 void dump () const;
121 /// Declare the dynamic allocation hooks.
122 ACE_ALLOC_HOOK_DECLARE;
124 private:
125 /// Connector base.
126 ACE_Connector_Base<SVC_HANDLER> &connector_;
128 /// Associated SVC_HANDLER.
129 SVC_HANDLER *svc_handler_;
131 /// Same as svc_handler_ if svc_handler_ is reference counted.
132 SVC_HANDLER *cleanup_svc_handler_;
134 /// Associated timer id.
135 long timer_id_;
139 * @class ACE_Connector
141 * @brief Generic factory for actively connecting clients and creating
142 * service handlers (SVC_HANDLERs).
144 * Implements the strategy for actively establishing connections with
145 * clients. Both blocking and non-blocking connects are supported.
146 * Moreover, non-blocking connects support timeouts.
148 * An ACE_Connector is parameterized by concrete types that conform to
149 * the interfaces of SVC_HANDLER and PEER_CONNECTOR described below.
151 * @tparam SVC_HANDLER The name of the concrete type that performs the
152 * application-specific service. The SVC_HANDLER typically
153 * inherits from ACE_Svc_Handler. @see Svc_Handler.h.
155 * @tparam PEER_CONNECTOR The name of the class that implements the
156 * PEER_CONNECTOR endpoint (e.g., ACE_SOCK_Connector) to
157 * passively establish connections. A PEER_CONNECTOR
158 * implementation must provide a PEER_STREAM and PEER_ADDR
159 * trait to identify the type of stream (e.g.,
160 * ACE_SOCK_Stream) and type of address (e.g., ACE_INET_Addr)
161 * used by the endpoint.
163 template <typename SVC_HANDLER, typename PEER_CONNECTOR>
164 class ACE_Connector : public ACE_Connector_Base<SVC_HANDLER>, public ACE_Service_Object
166 public:
167 // Useful STL-style traits.
168 typedef typename SVC_HANDLER::addr_type addr_type;
169 typedef PEER_CONNECTOR connector_type;
170 typedef SVC_HANDLER handler_type;
171 typedef typename SVC_HANDLER::stream_type stream_type;
172 typedef typename PEER_CONNECTOR::PEER_ADDR peer_addr_type;
173 typedef typename PEER_CONNECTOR::PEER_ADDR PEER_ADDR_TYPEDEF;
176 * Initialize a connector. @a flags indicates how SVC_HANDLER's
177 * should be initialized prior to being activated. Right now, the
178 * only flag that is processed is ACE_NONBLOCK, which enabled
179 * non-blocking I/O on the SVC_HANDLER when it is opened.
181 ACE_Connector (ACE_Reactor *r = ACE_Reactor::instance (),
182 int flags = 0);
185 * Initialize a connector. @a flags indicates how SVC_HANDLER's
186 * should be initialized prior to being activated. Right now, the
187 * only flag that is processed is ACE_NONBLOCK, which enabled
188 * non-blocking I/O on the SVC_HANDLER when it is opened.
190 virtual int open (ACE_Reactor *r = ACE_Reactor::instance (),
191 int flags = 0);
193 /// Shutdown a connector and release resources.
194 virtual ~ACE_Connector ();
196 // = Connection establishment methods.
199 * Initiate connection of @a svc_handler to peer at @a remote_addr
200 * using @a synch_options. If the caller wants to designate the
201 * selected @a local_addr they can (and can also insist that the
202 * @a local_addr be reused by passing a value @a reuse_addr ==
203 * 1). @a flags and @a perms can be used to pass any flags that are
204 * needed to perform specific operations such as opening a file
205 * within connect with certain permissions. If the connection fails
206 * the <close> hook on the @a svc_handler will be called
207 * automatically to prevent resource leaks.
209 virtual int connect (SVC_HANDLER *&svc_handler,
210 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
211 const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
212 const typename PEER_CONNECTOR::PEER_ADDR &local_addr
213 = reinterpret_cast<const peer_addr_type &>(peer_addr_type::sap_any),
214 int reuse_addr = 0,
215 int flags = O_RDWR,
216 int perms = 0);
219 * This is a variation on the previous <connect> method. On cached
220 * connectors the @a svc_handler_hint variable can be used as a hint
221 * for future lookups. Since this variable is modified in the
222 * context of the internal cache its use is thread-safe. But the
223 * actual svc_handler for the current connection is returned in the
224 * second parameter @a svc_handler. If the connection fails the
225 * <close> hook on the @a svc_handler will be called automatically to
226 * prevent resource leaks.
228 virtual int connect (SVC_HANDLER *&svc_handler_hint,
229 SVC_HANDLER *&svc_handler,
230 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
231 const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
232 const typename PEER_CONNECTOR::PEER_ADDR &local_addr
233 = reinterpret_cast<const peer_addr_type &>(peer_addr_type::sap_any),
234 int reuse_addr = 0,
235 int flags = O_RDWR,
236 int perms = 0);
239 * Initiate connection of @a n @a svc_handlers to peers at
240 * @a remote_addrs using @a synch_options. Returns -1 if failure
241 * occurs and 0 otherwise. If @a failed_svc_handlers is non-NULL, a
242 * 1 is placed in the corresponding index of @a failed_svc_handlers
243 * for each <svc_handlers[i]> that failed to connect, else a 0 is
244 * placed in that index.
246 virtual int connect_n (size_t n,
247 SVC_HANDLER *svc_handlers[],
248 typename PEER_CONNECTOR::PEER_ADDR remote_addrs[],
249 ACE_TCHAR *failed_svc_handlers = 0,
250 const ACE_Synch_Options &synch_options =
251 ACE_Synch_Options::defaults);
254 * Cancel the @a svc_handler that was started asynchronously. Note that
255 * this is the only case when the Connector does not actively close
256 * the @a svc_handler. It is left up to the caller of <cancel> to
257 * decide the fate of the @a svc_handler.
259 virtual int cancel (SVC_HANDLER *svc_handler);
261 /// Close down the Connector. All pending non-blocking connects are
262 /// canceled and the corresponding svc_handler is closed.
263 virtual int close ();
265 /// Return the underlying PEER_CONNECTOR object.
266 virtual PEER_CONNECTOR &connector () const;
268 /// Initialize Svc_Handler.
269 virtual void initialize_svc_handler (ACE_HANDLE handle,
270 SVC_HANDLER *svc_handler);
272 /// Set Reactor.
273 virtual void reactor (ACE_Reactor *reactor);
275 /// Get Reactor.
276 virtual ACE_Reactor *reactor () const;
278 /// Dump the state of an object.
279 void dump () const;
281 /// Declare the dynamic allocation hooks.
282 ACE_ALLOC_HOOK_DECLARE;
284 protected:
285 // = Helpful typedefs.
286 typedef ACE_NonBlocking_Connect_Handler<SVC_HANDLER> NBCH;
288 // = The following two methods define the Connector's strategies for
289 // creating, connecting, and activating SVC_HANDLER's, respectively.
292 * Bridge method for creating a SVC_HANDLER. The default is to
293 * create a new SVC_HANDLER only if @a sh == 0, else @a sh is
294 * unchanged. However, subclasses can override this policy to
295 * perform SVC_HANDLER creation in any way that they like (such as
296 * creating subclass instances of SVC_HANDLER, using a singleton,
297 * dynamically linking the handler, etc.). Returns -1 if failure,
298 * else 0.
300 virtual int make_svc_handler (SVC_HANDLER *&sh);
303 * Bridge method for connecting the @a svc_handler to the
304 * @a remote_addr. The default behavior delegates to the
305 * <PEER_CONNECTOR::connect>.
307 virtual int connect_svc_handler (SVC_HANDLER *&svc_handler,
308 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
309 ACE_Time_Value *timeout,
310 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
311 int reuse_addr,
312 int flags,
313 int perms);
314 virtual int connect_svc_handler (SVC_HANDLER *&svc_handler,
315 SVC_HANDLER *&sh_copy,
316 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
317 ACE_Time_Value *timeout,
318 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
319 int reuse_addr,
320 int flags,
321 int perms);
324 * Bridge method for activating a @a svc_handler with the appropriate
325 * concurrency strategy. The default behavior of this method is to
326 * activate the SVC_HANDLER by calling its <open> method (which
327 * allows the SVC_HANDLER to define its own concurrency strategy).
328 * However, subclasses can override this strategy to do more
329 * sophisticated concurrency activations (such as creating the
330 * SVC_HANDLER as an "active object" via multi-threading or
331 * multi-processing).
333 virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
335 /// Creates and registers ACE_NonBlocking_Connect_Handler.
336 int nonblocking_connect (SVC_HANDLER *,
337 const ACE_Synch_Options &);
339 /// Implementation of the connect methods.
340 virtual int connect_i (SVC_HANDLER *&svc_handler,
341 SVC_HANDLER **sh_copy,
342 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
343 const ACE_Synch_Options &synch_options,
344 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
345 int reuse_addr,
346 int flags,
347 int perms);
349 /// Return the handle set representing the non-blocking connects in
350 /// progress.
351 ACE_Unbounded_Set<ACE_HANDLE> &non_blocking_handles ();
353 // = Dynamic linking hooks.
354 /// Default version does no work and returns -1. Must be overloaded
355 /// by application developer to do anything meaningful.
356 virtual int init (int argc, ACE_TCHAR *argv[]);
358 /// Calls handle_close() to shutdown the Connector gracefully.
359 virtual int fini ();
361 /// Default version returns address info in @a buf.
362 virtual int info (ACE_TCHAR **strp, size_t length) const;
364 // = Service management hooks.
365 /// Default version does no work and returns -1. Must be overloaded
366 /// by application developer to do anything meaningful.
367 virtual int suspend ();
369 /// Default version does no work and returns -1. Must be overloaded
370 /// by application developer to do anything meaningful.
371 virtual int resume ();
373 private:
374 /// This is the peer connector factory.
375 PEER_CONNECTOR connector_;
378 * Flags that indicate how SVC_HANDLER's should be initialized
379 * prior to being activated. Right now, the only flag that is
380 * processed is ACE_NONBLOCK, which enabled non-blocking I/O on
381 * the SVC_HANDLER when it is opened.
383 int flags_;
385 /// Pointer to the Reactor.
386 ACE_Reactor *reactor_;
388 /// Handle set representing the non-blocking connects in progress.
389 ACE_Unbounded_Set<ACE_HANDLE> non_blocking_handles_;
393 * @class ACE_Strategy_Connector
395 * @brief Abstract factory for creating a service handler
396 * (SVC_HANDLER), connecting the SVC_HANDLER, and activating the
397 * SVC_HANDLER.
399 * Implements a flexible and extensible set of strategies for
400 * actively establishing connections with clients. There are
401 * three main strategies: (1) creating a SVC_HANDLER, (2)
402 * actively initiating a new connection from the client,
403 * and (3) activating the SVC_HANDLER with a
404 * particular concurrency mechanism after the connection is established.
406 template <class SVC_HANDLER, typename PEER_CONNECTOR>
407 class ACE_Strategy_Connector
408 : public ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
410 public:
411 // Useful STL-style traits.
412 typedef ACE_Creation_Strategy<SVC_HANDLER>
413 creation_strategy_type;
414 typedef ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR>
415 connect_strategy_type;
416 typedef ACE_Concurrency_Strategy<SVC_HANDLER>
417 concurrency_strategy_type;
418 typedef ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
419 base_type;
421 // = Define some useful (old style) traits.
422 typedef ACE_Creation_Strategy<SVC_HANDLER>
423 CREATION_STRATEGY;
424 typedef ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR>
425 CONNECT_STRATEGY;
426 typedef ACE_Concurrency_Strategy<SVC_HANDLER>
427 CONCURRENCY_STRATEGY;
428 typedef ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
429 SUPER;
432 * Initialize a connector. @a flags indicates how SVC_HANDLER's
433 * should be initialized prior to being activated. Right now, the
434 * only flag that is processed is ACE_NONBLOCK, which enabled
435 * non-blocking I/O on the SVC_HANDLER when it is opened.
437 ACE_Strategy_Connector (ACE_Reactor *r = ACE_Reactor::instance (),
438 ACE_Creation_Strategy<SVC_HANDLER> * = 0,
439 ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> * = 0,
440 ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
441 int flags = 0);
444 * Initialize a connector. @a flags indicates how SVC_HANDLER's
445 * should be initialized prior to being activated. Right now, the
446 * only flag that is processed is ACE_NONBLOCK, which enabled
447 * non-blocking I/O on the SVC_HANDLER when it is opened.
448 * Default strategies would be created and used.
450 virtual int open (ACE_Reactor *r,
451 int flags);
454 * Initialize a connector. @a flags indicates how SVC_HANDLER's
455 * should be initialized prior to being activated. Right now, the
456 * only flag that is processed is ACE_NONBLOCK, which enabled
457 * non-blocking I/O on the SVC_HANDLER when it is opened.
459 virtual int open (ACE_Reactor *r = ACE_Reactor::instance (),
460 ACE_Creation_Strategy<SVC_HANDLER> * = 0,
461 ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> * = 0,
462 ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
463 int flags = 0);
465 /// Shutdown a connector and release resources.
466 virtual ~ACE_Strategy_Connector ();
468 /// Close down the Connector
469 virtual int close ();
471 // = Strategies accessors
472 virtual ACE_Creation_Strategy<SVC_HANDLER> *creation_strategy () const;
473 virtual ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> *connect_strategy () const;
474 virtual ACE_Concurrency_Strategy<SVC_HANDLER> *concurrency_strategy () const;
476 /// Declare the dynamic allocation hooks.
477 ACE_ALLOC_HOOK_DECLARE;
479 protected:
480 // = The following three methods define the <Connector>'s strategies
481 // for creating, connecting, and activating SVC_HANDLER's,
482 // respectively.
485 * Bridge method for creating a SVC_HANDLER. The strategy for
486 * creating a SVC_HANDLER are configured into the Connector via
487 * it's <creation_strategy_>. The default is to create a new
488 * SVC_HANDLER only if @a sh == 0, else @a sh is unchanged.
489 * However, subclasses can override this policy to perform
490 * SVC_HANDLER creation in any way that they like (such as
491 * creating subclass instances of SVC_HANDLER, using a singleton,
492 * dynamically linking the handler, etc.). Returns -1 if failure,
493 * else 0.
495 virtual int make_svc_handler (SVC_HANDLER *&sh);
498 * Bridge method for connecting the new connection into the
499 * SVC_HANDLER. The default behavior delegates to the
500 * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
502 virtual int connect_svc_handler (SVC_HANDLER *&sh,
503 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
504 ACE_Time_Value *timeout,
505 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
506 int reuse_addr,
507 int flags,
508 int perms);
511 * Bridge method for connecting the new connection into the
512 * SVC_HANDLER. The default behavior delegates to the
513 * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
514 * @a sh_copy is used to obtain a copy of the @a sh pointer, but that
515 * can be kept in the stack; the motivation is a bit too long to
516 * include here, but basically we want to modify @a sh safely, using
517 * the internal locks in the Connect_Strategy, while saving a TSS
518 * copy in @a sh_copy, usually located in the stack.
520 virtual int connect_svc_handler (SVC_HANDLER *&sh,
521 SVC_HANDLER *&sh_copy,
522 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
523 ACE_Time_Value *timeout,
524 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
525 int reuse_addr,
526 int flags,
527 int perms);
530 * Bridge method for activating a SVC_HANDLER with the appropriate
531 * concurrency strategy. The default behavior of this method is to
532 * activate the SVC_HANDLER by calling its <open> method (which
533 * allows the SVC_HANDLER to define its own concurrency strategy).
534 * However, subclasses can override this strategy to do more
535 * sophisticated concurrency activations (such as creating the
536 * SVC_HANDLER as an "active object" via multi-threading or
537 * multi-processing).
539 virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
541 // = Strategy objects.
543 /// Creation strategy for an Connector.
544 CREATION_STRATEGY *creation_strategy_;
546 /// True if Connector created the creation strategy and thus should
547 /// delete it, else false.
548 bool delete_creation_strategy_;
550 /// Connect strategy for a Connector.
551 CONNECT_STRATEGY *connect_strategy_;
553 /// True if Connector created the connect strategy and thus should
554 /// delete it, else false.
555 bool delete_connect_strategy_;
557 /// Concurrency strategy for a Connector.
558 CONCURRENCY_STRATEGY *concurrency_strategy_;
560 /// True if Connector created the concurrency strategy and thus should
561 /// delete it, else false.
562 bool delete_concurrency_strategy_;
565 ACE_END_VERSIONED_NAMESPACE_DECL
567 #include "ace/Connector.cpp"
569 #include /**/ "ace/post.h"
571 #endif /* ACE_CONNECTOR_H */