summaryrefslogtreecommitdiff
path: root/ACE/ace/Connector.h
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/ace/Connector.h')
-rw-r--r--ACE/ace/Connector.h573
1 files changed, 573 insertions, 0 deletions
diff --git a/ACE/ace/Connector.h b/ACE/ace/Connector.h
new file mode 100644
index 00000000000..516fc8a775d
--- /dev/null
+++ b/ACE/ace/Connector.h
@@ -0,0 +1,573 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Connector.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_CONNECTOR_H
+#define ACE_CONNECTOR_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/Service_Object.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+#include "ace/Strategies_T.h"
+#include "ace/Synch_Options.h"
+#include "ace/Unbounded_Set.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Connector_Base
+ *
+ * @brief This base interface allows ACE_NonBlocking_Connect_Handler
+ * to only care about the SVC_HANDLER template parameter of the
+ * ACE_Connector. Otherwise, ACE_NonBlocking_Connect_Handler would
+ * have to be configured with all the template parameters that
+ * ACE_Connector is configured with.
+ */
+template <class SVC_HANDLER>
+class ACE_Connector_Base
+{
+public:
+
+ virtual ~ACE_Connector_Base (void) {}
+
+ /// Initialize the Svc_Handler.
+ virtual void initialize_svc_handler (ACE_HANDLE handle,
+ SVC_HANDLER *svc_handler) = 0;
+
+ /// Return the handle set representing the non-blocking connects in
+ /// progress.
+ virtual ACE_Unbounded_Set<ACE_HANDLE> &non_blocking_handles (void) = 0;
+};
+
+/**
+ * @class ACE_NonBlocking_Connect_Handler
+ *
+ * @brief Performs non-blocking connects on behalf of the Connector.
+ */
+template <class SVC_HANDLER>
+class ACE_NonBlocking_Connect_Handler : public ACE_Event_Handler
+{
+public:
+
+ // Constructor.
+ ACE_NonBlocking_Connect_Handler (ACE_Connector_Base<SVC_HANDLER> &connector,
+ SVC_HANDLER *,
+ long timer_id);
+
+ /// Close up and return underlying SVC_HANDLER through @c sh.
+ /**
+ * If the return value is true the close was performed succesfully,
+ * implying that this object was removed from the reactor and thereby
+ * (by means of reference counting decremented to 0) deleted.
+ * If the return value is false, the close was not successful.
+ * The @c sh does not have any connection to the return
+ * value. The argument will return a valid svc_handler object if a
+ * valid one exists within the object. Returning a valid svc_handler
+ * pointer also invalidates the svc_handler contained in this
+ * object.
+ */
+ bool close (SVC_HANDLER *&sh);
+
+ /// Get SVC_HANDLER.
+ SVC_HANDLER *svc_handler (void);
+
+ // = Get/set handle.
+ /// Get handle.
+ ACE_HANDLE handle (void);
+
+ /// Set handle.
+ void handle (ACE_HANDLE);
+
+ // = Set/get timer id.
+ /// Get timer id.
+ long timer_id (void);
+
+ /// Set timer id.
+ void timer_id (long timer_id);
+
+ /// Called by ACE_Reactor when asynchronous connections fail.
+ virtual int handle_input (ACE_HANDLE);
+
+ /// Called by ACE_Reactor when asynchronous connections succeed.
+ virtual int handle_output (ACE_HANDLE);
+
+ /// Called by ACE_Reactor when asynchronous connections suceeds (on
+ /// some platforms only).
+ virtual int handle_exception (ACE_HANDLE fd);
+
+ /// This method is called if a connection times out before
+ /// completing.
+ virtual int handle_timeout (const ACE_Time_Value &tv,
+ const void *arg);
+
+ /// Should Reactor resume us if we have been suspended before the
+ /// upcall?
+ virtual int resume_handler (void);
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+private:
+
+ /// Connector base.
+ ACE_Connector_Base<SVC_HANDLER> &connector_;
+
+ /// Associated SVC_HANDLER.
+ SVC_HANDLER *svc_handler_;
+
+ /// Associated timer id.
+ long timer_id_;
+};
+
+/**
+ * @class ACE_Connector
+ *
+ * @brief Generic factory for actively connecting clients and creating
+ * service handlers (SVC_HANDLERs).
+ *
+ * Implements the strategy for actively establishing connections with
+ * clients. An ACE_Connector is parameterized by concrete types that
+ * conform to the interfaces of PEER_CONNECTOR and SVC_HANDLER. The
+ * PEER_CONNECTOR is instantiated with a transport mechanism that
+ * actively establishes connections. The SVC_HANDLER is instantiated
+ * with a concrete type that performs the application-specific
+ * service. Both blocking and non-blocking connects are supported.
+ * Further, non-blocking connects support timeouts.
+ */
+template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
+class ACE_Connector : public ACE_Connector_Base<SVC_HANDLER>, public ACE_Service_Object
+{
+public:
+
+ // Useful STL-style traits.
+ typedef ACE_TYPENAME SVC_HANDLER::addr_type addr_type;
+ typedef ACE_PEER_CONNECTOR connector_type;
+ typedef SVC_HANDLER handler_type;
+ typedef ACE_TYPENAME SVC_HANDLER::stream_type stream_type;
+
+ // typedef ACE_TYPENAME ACE_PEER_CONNECTOR_ADDR PEER_ADDR;
+#if defined (ACE_HAS_TYPENAME_KEYWORD)
+ typedef ACE_PEER_CONNECTOR_ADDR ACE_PEER_ADDR_TYPEDEF;
+#endif /* ACE_HAS_TYPENAME_KEYWORD */
+
+ typedef ACE_TYPENAME _ACE_PEER_CONNECTOR::PEER_ADDR
+ ACE_TYPENAME_ACE_PEER_CONNECTOR_PEER_ADDR;
+
+ /**
+ * Initialize a connector. @a flags indicates how <SVC_HANDLER>'s
+ * should be initialized prior to being activated. Right now, the
+ * only flag that is processed is ACE_NONBLOCK, which enabled
+ * non-blocking I/O on the <SVC_HANDLER> when it is opened.
+ */
+ ACE_Connector (ACE_Reactor *r = ACE_Reactor::instance (),
+ int flags = 0);
+
+ /**
+ * Initialize a connector. @a flags indicates how <SVC_HANDLER>'s
+ * should be initialized prior to being activated. Right now, the
+ * only flag that is processed is ACE_NONBLOCK, which enabled
+ * non-blocking I/O on the <SVC_HANDLER> when it is opened.
+ */
+ virtual int open (ACE_Reactor *r = ACE_Reactor::instance (),
+ int flags = 0);
+
+ /// Shutdown a connector and release resources.
+ virtual ~ACE_Connector (void);
+
+ // = Connection establishment methods.
+
+ /**
+ * Initiate connection of <svc_handler> to peer at <remote_addr>
+ * using <synch_options>. If the caller wants to designate the
+ * selected <local_addr> they can (and can also insist that the
+ * <local_addr> be reused by passing a value <reuse_addr> ==
+ * 1). @a flags and <perms> can be used to pass any flags that are
+ * needed to perform specific operations such as opening a file
+ * within connect with certain permissions. If the connection fails
+ * the <close> hook on the <svc_handler> will be called
+ * automatically to prevent resource leaks.
+ */
+ virtual int connect (SVC_HANDLER *&svc_handler,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr
+ = (ACE_TYPENAME_ACE_PEER_CONNECTOR_PEER_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY,
+ int reuse_addr = 0,
+ int flags = O_RDWR,
+ int perms = 0);
+
+ /**
+ * This is a variation on the previous <connect> method. On cached
+ * connectors the <svc_handler_hint> variable can be used as a hint
+ * for future lookups. Since this variable is modified in the
+ * context of the internal cache its use is thread-safe. But the
+ * actual svc_handler for the current connection is returned in the
+ * second parameter <svc_handler>. If the connection fails the
+ * <close> hook on the <svc_handler> will be called automatically to
+ * prevent resource leaks.
+ */
+ virtual int connect (SVC_HANDLER *&svc_handler_hint,
+ SVC_HANDLER *&svc_handler,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr
+ = (ACE_TYPENAME_ACE_PEER_CONNECTOR_PEER_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY,
+ int reuse_addr = 0,
+ int flags = O_RDWR,
+ int perms = 0);
+
+ /**
+ * Initiate connection of <n> <svc_handlers> to peers at
+ * <remote_addrs> using <synch_options>. Returns -1 if failure
+ * occurs and 0 otherwise. If <failed_svc_handlers> is non-NULL, a
+ * 1 is placed in the corresponding index of <failed_svc_handler>
+ * for each <svc_handlers[i]> that failed to connect, else a 0 is
+ * placed in that index.
+ */
+ virtual int connect_n (size_t n,
+ SVC_HANDLER *svc_handlers[],
+ ACE_PEER_CONNECTOR_ADDR remote_addrs[],
+ ACE_TCHAR *failed_svc_handlers = 0,
+ const ACE_Synch_Options &synch_options =
+ ACE_Synch_Options::defaults);
+
+ /**
+ * Cancel a <svc_handler> that was started asynchronously. Note that
+ * this is the only case when the Connector does not actively close
+ * the <svc_handler>. It is left up to the caller of <cancel> to
+ * decide the fate of the <svc_handler>.
+ */
+ virtual int cancel (SVC_HANDLER *svc_handler);
+
+ /// Close down the Connector. All pending non-blocking connects are
+ /// canceled and the corresponding svc_handler is closed.
+ virtual int close (void);
+
+ /// Return the underlying PEER_CONNECTOR object.
+ virtual ACE_PEER_CONNECTOR &connector (void) const;
+
+ /// Initialize Svc_Handler.
+ virtual void initialize_svc_handler (ACE_HANDLE handle,
+ SVC_HANDLER *svc_handler);
+
+ /// Set Reactor.
+ virtual void reactor (ACE_Reactor *reactor);
+
+ /// Get Reactor.
+ virtual ACE_Reactor *reactor (void) const;
+
+ /// Dump the state of an object.
+ void dump (void) const;
+
+ /// Declare the dynamic allocation hooks.
+ ACE_ALLOC_HOOK_DECLARE;
+
+protected:
+ // = Helpful typedefs.
+ typedef ACE_NonBlocking_Connect_Handler<SVC_HANDLER> NBCH;
+
+ // = The following two methods define the Connector's strategies for
+ // creating, connecting, and activating SVC_HANDLER's, respectively.
+
+ /**
+ * Bridge method for creating a SVC_HANDLER. The default is to
+ * create a new SVC_HANDLER only if <sh> == 0, else <sh> is
+ * unchanged. However, subclasses can override this policy to
+ * perform SVC_HANDLER creation in any way that they like (such as
+ * creating subclass instances of SVC_HANDLER, using a singleton,
+ * dynamically linking the handler, etc.). Returns -1 if failure,
+ * else 0.
+ */
+ virtual int make_svc_handler (SVC_HANDLER *&sh);
+
+ /**
+ * Bridge method for connecting the <svc_handler> to the
+ * <remote_addr>. The default behavior delegates to the
+ * <PEER_CONNECTOR::connect>.
+ */
+ virtual int connect_svc_handler (SVC_HANDLER *&svc_handler,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms);
+ virtual int connect_svc_handler (SVC_HANDLER *&svc_handler,
+ SVC_HANDLER *&sh_copy,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms);
+
+ /**
+ * Bridge method for activating a <svc_handler> with the appropriate
+ * concurrency strategy. The default behavior of this method is to
+ * activate the SVC_HANDLER by calling its <open> method (which
+ * allows the SVC_HANDLER to define its own concurrency strategy).
+ * However, subclasses can override this strategy to do more
+ * sophisticated concurrency activations (such as creating the
+ * SVC_HANDLER as an "active object" via multi-threading or
+ * multi-processing).
+ */
+ virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
+
+ /// Creates and registers ACE_NonBlocking_Connect_Handler.
+ int nonblocking_connect (SVC_HANDLER *,
+ const ACE_Synch_Options &);
+
+ /// Implementation the <connect> methods.
+ virtual int connect_i (SVC_HANDLER *&svc_handler,
+ SVC_HANDLER **sh_copy,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ const ACE_Synch_Options &synch_options,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms);
+
+ /// Return the handle set representing the non-blocking connects in
+ /// progress.
+ ACE_Unbounded_Set<ACE_HANDLE> &non_blocking_handles (void);
+
+ // = Dynamic linking hooks.
+ /// Default version does no work and returns -1. Must be overloaded
+ /// by application developer to do anything meaningful.
+ virtual int init (int argc, ACE_TCHAR *argv[]);
+
+ /// Calls <handle_close> to shutdown the Connector gracefully.
+ virtual int fini (void);
+
+ /// Default version returns address info in <buf>.
+ virtual int info (ACE_TCHAR **, size_t) const;
+
+ // = Service management hooks.
+ /// Default version does no work and returns -1. Must be overloaded
+ /// by application developer to do anything meaningful.
+ virtual int suspend (void);
+
+ /// Default version does no work and returns -1. Must be overloaded
+ /// by application developer to do anything meaningful.
+ virtual int resume (void);
+
+private:
+ /// This is the peer connector factory.
+ ACE_PEER_CONNECTOR connector_;
+
+ /**
+ * Flags that indicate how <SVC_HANDLER>'s should be initialized
+ * prior to being activated. Right now, the only flag that is
+ * processed is ACE_NONBLOCK, which enabled non-blocking I/O on
+ * the <SVC_HANDLER> when it is opened.
+ */
+ int flags_;
+
+ /// Pointer to the Reactor.
+ ACE_Reactor *reactor_;
+
+ /// Handle set representing the non-blocking connects in progress.
+ ACE_Unbounded_Set<ACE_HANDLE> non_blocking_handles_;
+
+};
+
+/**
+ * @class ACE_Strategy_Connector
+ *
+ * @brief Abstract factory for creating a service handler
+ * (SVC_HANDLER), connecting the SVC_HANDLER, and activating the
+ * SVC_HANDLER.
+ *
+ * Implements a flexible and extensible set of strategies for
+ * actively establishing connections with clients. There are
+ * three main strategies: (1) creating a SVC_HANDLER, (2)
+ * actively initiating a new connection from the client,
+ * and (3) activating the SVC_HANDLER with a
+ * particular concurrency mechanism after the connection is established.
+ */
+template <class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
+class ACE_Strategy_Connector
+ : public ACE_Connector <SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+{
+public:
+
+ // Useful STL-style traits.
+ typedef ACE_Creation_Strategy<SVC_HANDLER>
+ creation_strategy_type;
+ typedef ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+ connect_strategy_type;
+ typedef ACE_Concurrency_Strategy<SVC_HANDLER>
+ concurrency_strategy_type;
+ typedef ACE_Connector <SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+ base_type;
+
+ // = Define some useful (old style) traits.
+ typedef ACE_Creation_Strategy<SVC_HANDLER>
+ CREATION_STRATEGY;
+ typedef ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+ CONNECT_STRATEGY;
+ typedef ACE_Concurrency_Strategy<SVC_HANDLER>
+ CONCURRENCY_STRATEGY;
+ typedef ACE_Connector <SVC_HANDLER, ACE_PEER_CONNECTOR_2>
+ SUPER;
+
+ /**
+ * Initialize a connector. @a flags indicates how <SVC_HANDLER>'s
+ * should be initialized prior to being activated. Right now, the
+ * only flag that is processed is ACE_NONBLOCK, which enabled
+ * non-blocking I/O on the <SVC_HANDLER> when it is opened.
+ */
+ ACE_Strategy_Connector (ACE_Reactor *r = ACE_Reactor::instance (),
+ ACE_Creation_Strategy<SVC_HANDLER> * = 0,
+ ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> * = 0,
+ ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
+ int flags = 0);
+
+ /**
+ * Initialize a connector. @a flags indicates how <SVC_HANDLER>'s
+ * should be initialized prior to being activated. Right now, the
+ * only flag that is processed is ACE_NONBLOCK, which enabled
+ * non-blocking I/O on the <SVC_HANDLER> when it is opened.
+ * Default strategies would be created and used.
+ */
+ virtual int open (ACE_Reactor *r,
+ int flags);
+
+ /**
+ * Initialize a connector. @a flags indicates how <SVC_HANDLER>'s
+ * should be initialized prior to being activated. Right now, the
+ * only flag that is processed is ACE_NONBLOCK, which enabled
+ * non-blocking I/O on the <SVC_HANDLER> when it is opened.
+ */
+ virtual int open (ACE_Reactor *r = ACE_Reactor::instance (),
+ ACE_Creation_Strategy<SVC_HANDLER> * = 0,
+ ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> * = 0,
+ ACE_Concurrency_Strategy<SVC_HANDLER> * = 0,
+ int flags = 0);
+
+ /// Shutdown a connector and release resources.
+ virtual ~ACE_Strategy_Connector (void);
+
+ /// Close down the Connector
+ virtual int close (void);
+
+ // = Strategies accessors
+ virtual ACE_Creation_Strategy<SVC_HANDLER> *creation_strategy (void) const;
+ virtual ACE_Connect_Strategy<SVC_HANDLER, ACE_PEER_CONNECTOR_2> *connect_strategy (void) const;
+ virtual ACE_Concurrency_Strategy<SVC_HANDLER> *concurrency_strategy (void) const;
+
+protected:
+ // = The following three methods define the <Connector>'s strategies
+ // for creating, connecting, and activating <SVC_HANDLER>'s,
+ // respectively.
+
+ /**
+ * Bridge method for creating a <SVC_HANDLER>. The strategy for
+ * creating a <SVC_HANDLER> are configured into the Connector via
+ * it's <creation_strategy_>. The default is to create a new
+ * <SVC_HANDLER> only if <sh> == 0, else <sh> is unchanged.
+ * However, subclasses can override this policy to perform
+ * <SVC_HANDLER> creation in any way that they like (such as
+ * creating subclass instances of <SVC_HANDLER>, using a singleton,
+ * dynamically linking the handler, etc.). Returns -1 if failure,
+ * else 0.
+ */
+ virtual int make_svc_handler (SVC_HANDLER *&sh);
+
+ /**
+ * Bridge method for connecting the new connection into the
+ * <SVC_HANDLER>. The default behavior delegates to the
+ * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
+ */
+ virtual int connect_svc_handler (SVC_HANDLER *&sh,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms);
+
+ /**
+ * Bridge method for connecting the new connection into the
+ * <SVC_HANDLER>. The default behavior delegates to the
+ * <PEER_CONNECTOR::connect> in the <Connect_Strategy>.
+ * <sh_copy> is used to obtain a copy of the <sh> pointer, but that
+ * can be kept in the stack; the motivation is a bit too long to
+ * include here, but basically we want to modify <sh> safely, using
+ * the internal locks in the Connect_Strategy, while saving a TSS
+ * copy in <sh_copy>, usually located in the stack.
+ */
+ virtual int connect_svc_handler (SVC_HANDLER *&sh,
+ SVC_HANDLER *&sh_copy,
+ const ACE_PEER_CONNECTOR_ADDR &remote_addr,
+ ACE_Time_Value *timeout,
+ const ACE_PEER_CONNECTOR_ADDR &local_addr,
+ int reuse_addr,
+ int flags,
+ int perms);
+
+ /**
+ * Bridge method for activating a <SVC_HANDLER> with the appropriate
+ * concurrency strategy. The default behavior of this method is to
+ * activate the <SVC_HANDLER> by calling its <open> method (which
+ * allows the <SVC_HANDLER> to define its own concurrency strategy).
+ * However, subclasses can override this strategy to do more
+ * sophisticated concurrency activations (such as creating the
+ * <SVC_HANDLER> as an "active object" via multi-threading or
+ * multi-processing).
+ */
+ virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
+
+ // = Strategy objects.
+
+ /// Creation strategy for an <Connector>.
+ CREATION_STRATEGY *creation_strategy_;
+
+ /// 1 if <Connector> created the creation strategy and thus should
+ /// delete it, else 0.
+ int delete_creation_strategy_;
+
+ /// Connect strategy for a <Connector>.
+ CONNECT_STRATEGY *connect_strategy_;
+
+ /// 1 if <Connector> created the connect strategy and thus should
+ /// delete it, else 0.
+ int delete_connect_strategy_;
+
+ /// Concurrency strategy for an <Connector>.
+ CONCURRENCY_STRATEGY *concurrency_strategy_;
+
+ /// 1 if <Connector> created the concurrency strategy and thus should
+ /// delete it, else 0.
+ int delete_concurrency_strategy_;
+};
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Connector.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Connector.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+
+#endif /* ACE_CONNECTOR_H */