Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / ace / Connector.h
blob85ee6894fc59b2264b63572cbb7a26ecf89ca59e
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 (void) {}
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 (void) = 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 (void);
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 (void);
86 /// Get handle.
87 ACE_HANDLE handle (void);
89 /// Set handle.
90 void handle (ACE_HANDLE);
92 /// Get timer id.
93 long timer_id (void);
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 (void);
118 /// Dump the state of an object.
119 void dump (void) 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 (void);
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 (void);
265 /// Return the underlying PEER_CONNECTOR object.
266 virtual PEER_CONNECTOR &connector (void) 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 (void) const;
278 /// Dump the state of an object.
279 void dump (void) 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 (void);
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 (void);
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 (void);
369 /// Default version does no work and returns -1. Must be overloaded
370 /// by application developer to do anything meaningful.
371 virtual int resume (void);
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_;
394 * @class ACE_Strategy_Connector
396 * @brief Abstract factory for creating a service handler
397 * (SVC_HANDLER), connecting the SVC_HANDLER, and activating the
398 * SVC_HANDLER.
400 * Implements a flexible and extensible set of strategies for
401 * actively establishing connections with clients. There are
402 * three main strategies: (1) creating a SVC_HANDLER, (2)
403 * actively initiating a new connection from the client,
404 * and (3) activating the SVC_HANDLER with a
405 * particular concurrency mechanism after the connection is established.
407 template <class SVC_HANDLER, typename PEER_CONNECTOR>
408 class ACE_Strategy_Connector
409 : public ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
411 public:
412 // Useful STL-style traits.
413 typedef ACE_Creation_Strategy<SVC_HANDLER>
414 creation_strategy_type;
415 typedef ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR>
416 connect_strategy_type;
417 typedef ACE_Concurrency_Strategy<SVC_HANDLER>
418 concurrency_strategy_type;
419 typedef ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
420 base_type;
422 // = Define some useful (old style) traits.
423 typedef ACE_Creation_Strategy<SVC_HANDLER>
424 CREATION_STRATEGY;
425 typedef ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR>
426 CONNECT_STRATEGY;
427 typedef ACE_Concurrency_Strategy<SVC_HANDLER>
428 CONCURRENCY_STRATEGY;
429 typedef ACE_Connector <SVC_HANDLER, PEER_CONNECTOR>
430 SUPER;
433 * Initialize a connector. @a flags indicates how SVC_HANDLER's
434 * should be initialized prior to being activated. Right now, the
435 * only flag that is processed is ACE_NONBLOCK, which enabled
436 * non-blocking I/O on the SVC_HANDLER when it is opened.
438 ACE_Strategy_Connector (ACE_Reactor *r = ACE_Reactor::instance (),
439 ACE_Creation_Strategy<SVC_HANDLER> * = 0,
440 ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> * = 0,
441 ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
442 int flags = 0);
445 * Initialize a connector. @a flags indicates how SVC_HANDLER's
446 * should be initialized prior to being activated. Right now, the
447 * only flag that is processed is ACE_NONBLOCK, which enabled
448 * non-blocking I/O on the SVC_HANDLER when it is opened.
449 * Default strategies would be created and used.
451 virtual int open (ACE_Reactor *r,
452 int flags);
455 * Initialize a connector. @a flags indicates how SVC_HANDLER's
456 * should be initialized prior to being activated. Right now, the
457 * only flag that is processed is ACE_NONBLOCK, which enabled
458 * non-blocking I/O on the SVC_HANDLER when it is opened.
460 virtual int open (ACE_Reactor *r = ACE_Reactor::instance (),
461 ACE_Creation_Strategy<SVC_HANDLER> * = 0,
462 ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> * = 0,
463 ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
464 int flags = 0);
466 /// Shutdown a connector and release resources.
467 virtual ~ACE_Strategy_Connector (void);
469 /// Close down the Connector
470 virtual int close (void);
472 // = Strategies accessors
473 virtual ACE_Creation_Strategy<SVC_HANDLER> *creation_strategy (void) const;
474 virtual ACE_Connect_Strategy<SVC_HANDLER, PEER_CONNECTOR> *connect_strategy (void) const;
475 virtual ACE_Concurrency_Strategy<SVC_HANDLER> *concurrency_strategy (void) const;
477 /// Declare the dynamic allocation hooks.
478 ACE_ALLOC_HOOK_DECLARE;
480 protected:
481 // = The following three methods define the <Connector>'s strategies
482 // for creating, connecting, and activating SVC_HANDLER's,
483 // respectively.
486 * Bridge method for creating a SVC_HANDLER. The strategy for
487 * creating a SVC_HANDLER are configured into the Connector via
488 * it's <creation_strategy_>. The default is to create a new
489 * SVC_HANDLER only if @a sh == 0, else @a sh is unchanged.
490 * However, subclasses can override this policy to perform
491 * SVC_HANDLER creation in any way that they like (such as
492 * creating subclass instances of SVC_HANDLER, using a singleton,
493 * dynamically linking the handler, etc.). Returns -1 if failure,
494 * else 0.
496 virtual int make_svc_handler (SVC_HANDLER *&sh);
499 * Bridge method for connecting the new connection into the
500 * SVC_HANDLER. The default behavior delegates to the
501 * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
503 virtual int connect_svc_handler (SVC_HANDLER *&sh,
504 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
505 ACE_Time_Value *timeout,
506 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
507 int reuse_addr,
508 int flags,
509 int perms);
512 * Bridge method for connecting the new connection into the
513 * SVC_HANDLER. The default behavior delegates to the
514 * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
515 * @a sh_copy is used to obtain a copy of the @a sh pointer, but that
516 * can be kept in the stack; the motivation is a bit too long to
517 * include here, but basically we want to modify @a sh safely, using
518 * the internal locks in the Connect_Strategy, while saving a TSS
519 * copy in @a sh_copy, usually located in the stack.
521 virtual int connect_svc_handler (SVC_HANDLER *&sh,
522 SVC_HANDLER *&sh_copy,
523 const typename PEER_CONNECTOR::PEER_ADDR &remote_addr,
524 ACE_Time_Value *timeout,
525 const typename PEER_CONNECTOR::PEER_ADDR &local_addr,
526 int reuse_addr,
527 int flags,
528 int perms);
531 * Bridge method for activating a SVC_HANDLER with the appropriate
532 * concurrency strategy. The default behavior of this method is to
533 * activate the SVC_HANDLER by calling its <open> method (which
534 * allows the SVC_HANDLER to define its own concurrency strategy).
535 * However, subclasses can override this strategy to do more
536 * sophisticated concurrency activations (such as creating the
537 * SVC_HANDLER as an "active object" via multi-threading or
538 * multi-processing).
540 virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
542 // = Strategy objects.
544 /// Creation strategy for an Connector.
545 CREATION_STRATEGY *creation_strategy_;
547 /// True if Connector created the creation strategy and thus should
548 /// delete it, else false.
549 bool delete_creation_strategy_;
551 /// Connect strategy for a Connector.
552 CONNECT_STRATEGY *connect_strategy_;
554 /// True if Connector created the connect strategy and thus should
555 /// delete it, else false.
556 bool delete_connect_strategy_;
558 /// Concurrency strategy for a Connector.
559 CONCURRENCY_STRATEGY *concurrency_strategy_;
561 /// True if Connector created the concurrency strategy and thus should
562 /// delete it, else false.
563 bool delete_concurrency_strategy_;
566 ACE_END_VERSIONED_NAMESPACE_DECL
568 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
569 #include "ace/Connector.cpp"
570 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
572 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
573 #pragma implementation ("Connector.cpp")
574 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
576 #include /**/ "ace/post.h"
578 #endif /* ACE_CONNECTOR_H */