## NAME

ACE_Connector - Generic factory for actively connecting clients and creating service handlers (SVC_HANDLERs).

## SYNOPSIS

    #include <ace/Connector.h>

    template<class SVC_HANDLER, ACE_PEER_CONNECTOR_1>
    class ACE_Connector : public ACE_Service_Object
    {
      public:
        typedef ACE_PEER_CONNECTOR_ADDR ACE_PEER_ADDR_TYPEDEF;
        ACE_Connector (
            ACE_Reactor *r = ACE_Reactor::instance (),
            int flags = 0
            );
        virtual int open (
            ACE_Reactor *r = ACE_Reactor::instance (),
            int flags = 0
            );
        virtual ~ACE_Connector (void);
        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_PEER_CONNECTOR_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY,
            int reuse_addr = 0,
            int flags = O_RDWR,
            int perms = 0
            );
        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_PEER_CONNECTOR_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY,
            int reuse_addr = 0,
            int flags = O_RDWR,
            int perms = 0
            );
        virtual int connect_n (
            size_t n,
            SVC_HANDLER *svc_handlers[],
            ACE_PEER_CONNECTOR_ADDR remote_addrs[],
            ASYS_TCHAR *failed_svc_handlers = 0,
            const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults
            );
        virtual int cancel (SVC_HANDLER *svc_handler);
        virtual int close (void);
        void dump (void) const;
        ACE_ALLOC_HOOK_DECLARE;
      protected:
        typedef ACE_Svc_Tuple<SVC_HANDLER> AST;
            typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_MANAGER;

            typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_ITERATOR;

            typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> MAP_ENTRY;

        virtual int make_svc_handler (SVC_HANDLER *&sh);
        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
            );
        virtual int activate_svc_handler (SVC_HANDLER *svc_handler);
        virtual int handle_input (ACE_HANDLE);
        virtual int handle_output (ACE_HANDLE);
        virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE);
        virtual int init (int argc, ASYS_TCHAR *argv[]);
        virtual int fini (void);
        virtual int info (ASYS_TCHAR **, size_t) const;
        virtual int handle_close (
            ACE_HANDLE = ACE_INVALID_HANDLE,
            ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK
            );
        virtual int handle_timeout (
            const ACE_Time_Value &tv,
            const void *arg
            );
        virtual int suspend (void);
        virtual int resume (void);
        int create_AST (SVC_HANDLER *, const ACE_Synch_Options &);
        int cleanup_AST (ACE_HANDLE, AST *&);
        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
            );
        MAP_MANAGER handler_map_;
      private:
        ACE_PEER_CONNECTOR connector_;
        char closing_;
        int flags_;
    };

## DESCRIPTION

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 passively establishes connections. The SVC_HANDLER is instantiated with a concrete type that performs the application-specific service. An ACE_Connector inherits from ACE_Service_Object, which in turn inherits from ACE_Event_Handler. This enables the ACE_Reactor to dispatch the ACE_Connector's handle_output method when connections complete asynchronously. The handle_output method performs the connector's active connection establishment and service activation strategy.

## Initialization and termination methods.

typedef ACE_TYPENAME ACE_PEER_CONNECTOR_ADDR PEER_ADDR;

    typedef ACE_PEER_CONNECTOR_ADDR ACE_PEER_ADDR_TYPEDEF;

    ACE_Connector (
        ACE_Reactor *r = ACE_Reactor::instance (),
        int flags = 0
        );

Initialize a connector. `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
        );

Initialize a connector. `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 ~ACE_Connector (void);

Shutdown a connector and release resources.

## Connection establishment methods.

    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_PEER_CONNECTOR_ADDR &) ACE_PEER_CONNECTOR_ADDR_ANY,
        int reuse_addr = 0,
        int flags = O_RDWR,
        int perms = 0
        );

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). `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_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_PEER_CONNECTOR_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_n (
        size_t n,
        SVC_HANDLER *svc_handlers[],
        ACE_PEER_CONNECTOR_ADDR remote_addrs[],
        ASYS_TCHAR *failed_svc_handlers = 0,
        const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults
        );

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 cancel (SVC_HANDLER *svc_handler);

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 close (void);

Close down the Connector

    void dump (void) const;

Dump the state of an object.

    ACE_ALLOC_HOOK_DECLARE;

Declare the dynamic allocation hooks.

## Helpful typedefs.

    typedef ACE_Svc_Tuple<SVC_HANDLER> AST;

        typedef ACE_Map_Manager<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_MANAGER;

        typedef ACE_Map_Iterator<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *, ACE_SYNCH_RW_MUTEX> MAP_ITERATOR;

        typedef ACE_Map_Entry<ACE_HANDLE, ACE_Svc_Tuple<SVC_HANDLER> *> MAP_ENTRY;

## The following two methods define the Connector's strategies for

creating, connecting, and activating SVC_HANDLER's, respectively.

    virtual int make_svc_handler (SVC_HANDLER *&sh);

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 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 connecting the `svc_handler` to the `remote_addr`. The default behavior delegates to the `PEER_CONNECTOR::connect`.

    virtual int activate_svc_handler (SVC_HANDLER *svc_handler);

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 handle_input (ACE_HANDLE);

Called by ACE_Reactor when asynchronous connections fail.

    virtual int handle_output (ACE_HANDLE);

Called by ACE_Reactor when asynchronous connections succeed.

    virtual int handle_exception (ACE_HANDLE fd = ACE_INVALID_HANDLE);

Called by ACE_Reactor when asynchronous connections complete (on some platforms only).

## Dynamic linking hooks.

    virtual int init (int argc, ASYS_TCHAR *argv[]);

Default version does no work and returns -1. Must be overloaded by application developer to do anything meaningful.

    virtual int fini (void);

Calls `handle_close` to shutdown the Connector gracefully.

    virtual int info (ASYS_TCHAR **, size_t) const;

Default version returns address info in `buf`.

## Demultiplexing hooks.

    virtual int handle_close (
        ACE_HANDLE = ACE_INVALID_HANDLE,
        ACE_Reactor_Mask = ACE_Event_Handler::ALL_EVENTS_MASK
        );

Terminate the Client ACE_Connector by iterating over any unconnected ACE_Svc_Handler's and removing them from the ACE_Reactor.

    virtual int handle_timeout (
        const ACE_Time_Value &tv,
        const void *arg
        );

This method is called if a connection times out before completing.

## Service management hooks.

    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);

Default version does no work and returns -1. Must be overloaded by application developer to do anything meaningful.

    int create_AST (SVC_HANDLER *, const ACE_Synch_Options &);

Creates and inserts an ACE_Svc_Tuple into the `handler_map_`. so that we can continue accepting this connection asynchronously.

    int cleanup_AST (ACE_HANDLE, AST *&);

Cleanup the `handler_map_` and returns the appropriate ACE_Svc_Tuple (which is 0 if there is no associated tuple).

    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
        );

Implementation the connect() methods

    MAP_MANAGER handler_map_;

Lookup table that maps an I/O handle to a SVC_HANDLER *.

## AUTHOR

Doug Schmidt

## LIBRARY

ace