libassa 3.5.0
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions

ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR > Class Template Reference

Connector is a template class for initialization of communication services. More...

#include <Connector.h>

Inheritance diagram for ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >:
ASSA::EventHandler

List of all members.

Public Member Functions

 Connector ()
 Constructor. Do-nothing.
virtual ~Connector ()
 Destructor. Do-nothing.
virtual int open (const TimeVal &tv_=TimeVal(5.0), ConnectMode mode_=sync, Reactor *r_=(Reactor *) NULL)
 Configure Connector.
virtual int close (void)
 Do-nothing close.
virtual int connect (SERVICE_HANDLER *sh_, Address &addr_, int protocol_=AF_INET)
 Define strategy for establishing connection.
virtual int handle_write (int fd)
 Handle connection completion.
virtual int handle_timeout (TimerId tid)
 Handler connection timeout.

Protected Types

enum  ProgressState { idle, waiting, conned, failed }
 

state.

More...

Protected Member Functions

virtual SERVICE_HANDLER * makeServiceHandler (SERVICE_HANDLER *sh_)
 Defines creation strategy for ServiceHandler.
virtual int connectServiceHandler (Address &addr, int protocol)
 Default strategy is to make synchronous connection with no timeouts.
virtual int activateServiceHandler ()
 Activate handler by calling its open() method.

Protected Attributes

TimeVal m_timeout
 Timeout.
TimerId m_tid
 Timer id.
Reactorm_reactor
 Reference to Reactor (for async)
ProgressState m_state
 Connection progress state.
int m_flags
 Socket flags (obsolete)
SERVICE_HANDLER * m_sh
 Reference to ServiceHandler.
int m_fd
 Socket file descriptor.
ConnectMode m_mode
 Mode (sync/async)

Private Member Functions

void doAsync (void)
 Setup for asynchronous mode completion.
int doSync (void)
 Synchronous mode completion.

Detailed Description

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
class ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >

Connector is a template class for initialization of communication services.

This template class implements the generic strategy for actively
initializing communication services.

SERVICE_HANDLER is the type of service. It shall be a type derived from ServiceHandler interface class.

PEER_CONNECTOR is the type of concrete Socket class - particular transport mechanism used by the Connector to actively establish the connection. It should be derived from Socket interface class.

Definition at line 63 of file Connector.h.


Member Enumeration Documentation

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
enum ASSA::Connector::ProgressState [protected]

state.

Connection state.

Enumerator:
idle 

Initialized.

waiting 

Asynchronously waiting on connection completion.

conned 

Connected.

failed 

Failed to connect.

Definition at line 131 of file Connector.h.


Constructor & Destructor Documentation

template<class SH , class PEER_CONNECTOR >
ASSA::Connector< SH, PEER_CONNECTOR >::Connector ( )

Constructor. Do-nothing.

Definition at line 205 of file Connector.h.

References ASSA::EventHandler::set_id(), ASSA::SOCKTRACE, and trace_with_mask.

    : m_tid (0), m_reactor (0), m_state (idle),
      m_flags (0), m_sh ((SERVICE_HANDLER*)NULL), m_fd (-1), m_mode (sync)
{
    trace_with_mask("Connector::Connector",SOCKTRACE);
    set_id ("Connector");
}
template<class SH , class PEER_CONNECTOR >
ASSA::Connector< SH, PEER_CONNECTOR >::~Connector ( ) [virtual]

Destructor. Do-nothing.

Definition at line 215 of file Connector.h.

References ASSA::SOCKTRACE, and trace_with_mask.

{
    trace_with_mask("Connector::~Connector",SOCKTRACE);
    // If I created SERVICE_HANDLER, should I delete it too?
}

Member Function Documentation

template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::activateServiceHandler ( ) [protected, virtual]

Activate handler by calling its open() method.

Returns:
0 on success, -1 on error.

Definition at line 323 of file Connector.h.

References ASSA::SOCKTRACE, and trace_with_mask.

{
    trace_with_mask("Connector::activateServiceHandler",SOCKTRACE);

    return m_sh->open ();
}
template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::close ( void  ) [virtual]

Do-nothing close.

Derive classes can change this strategy by overloading this method.

Returns:
0 on success, -1 on error.

Definition at line 237 of file Connector.h.

References ASSA::SOCKTRACE, and trace_with_mask.

{
    trace_with_mask("Connector::close",SOCKTRACE);
    return 0;
}
template<class SERVICE_HANDLER, class PEER_CONNECTOR>
virtual int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::connect ( SERVICE_HANDLER *  sh_,
Address addr_,
int  protocol_ = AF_INET 
) [virtual]

Define strategy for establishing connection.

Default is to connect synchronously to the remote peer. In sync mode connection either will be established or failed when returned from Connector::connect() call.

In async mode, call to Connector::connect() returns immediately reporting only immediate error. Later on connection is completed asynchronously.

Default timeout on connection waiting is 10 seconds. Timeout can be configured by passing TimeVal parameter to the Connector::open() member function.

If connetion failed, caller should definitely close PEER_CONNECTOR communication point.

Parameters:
sh_Pointer to class object derived from ServiceHandler.
addr_Reference to the address to connect to.
protocol_AF_INET for internet socket, AF_UNIX for the UNIX Domain socket (defaults to AF_INET).
Returns:
0 on success, -1 on error.

Referenced by ASSA::Logger::log_open().

template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::connectServiceHandler ( Address addr,
int  protocol 
) [protected, virtual]

Default strategy is to make synchronous connection with no timeouts.

Derived class can change this strategy by overloading this method.

Returns:
0 on success, -1 on error.

Definition at line 303 of file Connector.h.

References ASSA::ASSAERR, EL, ASSA::Socket::nonblocking, ASSA::SOCKTRACE, and trace_with_mask.

{
    trace_with_mask("Connector::connectServiceHandler",SOCKTRACE);

    PEER_CONNECTOR& s = *m_sh;
    
    if ( !s.open (protocol_family_) ) {
        EL((ASSA::ASSAERR,"Socket::open (protocol=%d) failed\n",
            protocol_family_));
        return -1;
    }
    
    m_fd = s.getHandler ();
    s.setOption (ASSA::Socket::nonblocking, 1);

    return (s.connect (addr_) ? 0 : -1);
}
template<class SH , class PEER_CONNECTOR >
void ASSA::Connector< SH, PEER_CONNECTOR >::doAsync ( void  ) [private]

Setup for asynchronous mode completion.

Definition at line 332 of file Connector.h.

References ASSA::SOCKTRACE, trace_with_mask, and ASSA::WRITE_EVENT.

{
    trace_with_mask("Connector::doAsync",SOCKTRACE);

    /* We are doing async and 3-way handshake is in
     * progress - hook up with Reactor and wait on timer.
     * Write event will be our indicator whether connection
     * was completed or not.
     */
    m_reactor->registerIOHandler (this, m_fd, WRITE_EVENT);

    m_tid = m_reactor->registerTimerHandler (this, m_timeout, "ASYNC Connect");
    m_state = waiting;
}
template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::doSync ( void  ) [private]

Synchronous mode completion.

Returns:
0 on success; -1 if error.

Definition at line 349 of file Connector.h.

References ASSA::ASSAERR, DL, EL, ASSA::Reactor::registerIOHandler(), ASSA::set_errno(), ASSA::SOCKTRACE, trace_with_mask, and ASSA::WRITE_EVENT.

{
    trace_with_mask("Connector::doSync",SOCKTRACE);

    m_reactor = new Reactor;

    m_reactor->registerIOHandler    (this, m_fd, WRITE_EVENT);
    m_reactor->registerTimerHandler (this, m_timeout, "SYNC Connect");
    m_state = waiting;
    m_reactor->waitForEvents (&m_timeout); // Let the ball rolling ...
    m_reactor->removeHandler (this);    // Remove all handlers.

    delete m_reactor;
    m_reactor = 0;

    if (conned == m_state) 
    {
        DL((SOCKTRACE,"Synchronous connect() succeeded.\n"));
        return 0;
    }

    EL((ASSA::ASSAERR,"Synchronous connect() timed out.\n"));
    set_errno (ETIMEDOUT);

    return -1;
}
template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::handle_timeout ( TimerId  tid) [virtual]

Handler connection timeout.

Reimplemented from ASSA::EventHandler.

Definition at line 474 of file Connector.h.

References ASSA::async, ASSA::set_errno(), ASSA::SOCKTRACE, trace_with_mask, and ASSA::WRITE_EVENT.

{
    trace_with_mask("Connector::handle_timeout",SOCKTRACE);

    m_state = failed;
    set_errno (ETIMEDOUT);  // Connection timed out

    if (async == m_mode) {
        m_reactor->removeHandler (this, WRITE_EVENT);
    }
    return -1;      // Remove Timer Handler
}
template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::handle_write ( int  fd) [virtual]

Handle connection completion.

Always remove IO handler first.

Reimplemented from ASSA::EventHandler.

Definition at line 378 of file Connector.h.

References ASSA::ASSAERR, ASSA::async, DL, EL, ASSA::get_errno(), ASSA::set_errno(), ASSA::SOCKTRACE, trace_with_mask, and ASSA::WRITE_EVENT.

{
    trace_with_mask("Connector::handle_write",SOCKTRACE);

    /* Precondition 
     */
    if (fd_ != m_fd) {
        return -1;
    }

    /* This method serves both sync and async modes - thus the
     * differences. For async we remove Timer here. sync runs
     * its own private Reactor and handler termination is 
     * handled in doSync().
     */

    if (async == m_mode) { // Complete SH activation
        m_reactor->removeTimerHandler (m_tid);
        m_tid = 0;
    }

    /*
     * Although SUN and Linux man pages on connect(3) claims that
     * "upon asynchronous establishement of connection, select(3)
     * will indicate that the file descriptor for the socket is ready
     * for writing", as discussed in W.S.Stevens "UNIX network
     * programming", Vol I, 2nd edition, BSD-derived systems also
     * mark file descriptor both readable and writable when the
     * connection establishment encouters an error.
     *
     * Therefore we need an extra step to find out what really happened.
     * One way to do so is to look at socket pending errors...
     */

    int error;
    int ret;
    error = ret = errno = 0;
    socklen_t n = sizeof (error);

    m_reactor->removeHandler (this, WRITE_EVENT);   

#if defined(__CYGWIN32__) 
    ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, (int*)&n);
#elif defined (WIN32)
    ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, (int*)&n);
#else
    ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &n);
#endif

    if (ret == 0) {
        if (error == 0) 
        {
            if (activateServiceHandler () == 0) {
                DL((SOCKTRACE,"Nonblocking connect() completed\n"));
                m_state = conned;
            }
            else {
                DL((SOCKTRACE,"Nonblocking connect() failed\n"));
                m_state = failed;
            }
            return (0);         // return value doesn't really matter
        }
        /* Socket pending error - propagate it via errno. */

        EL((ASSA::ASSAERR,"Socket pending error: %d\n",error));
        set_errno (error);
    }
    else {  /* Solaris pending error. */
        EL((ASSA::ASSAERR,"getsockopt(3) = %d\n", ret));
        EL((ASSA::ASSAERR,"Solaris pending error!\n"));
    }
    m_state = failed;

    EL((ASSA::ASSAERR,"Nonblocking connect (2) failed\n"));

    if (get_errno () == ECONNREFUSED) 
    {
        EL((ASSA::ASSAERR,"Try to compare port "
             "numbers on client and service hosts.\n"));
    }
        /* This is the only way to tell SH that we failed to connect. 
     */
    if (async == m_mode) {
        m_sh->close (); 
    }

    /* Don't alter fd mask - SERVICE_HANDLER::open() could have changed 
     * it already for application processing needs.
     */
    return 0;
}
template<class SH , class PEER_CONNECTOR >
SERVICE_HANDLER * ASSA::Connector< SH, PEER_CONNECTOR >::makeServiceHandler ( SERVICE_HANDLER *  sh_) [protected, virtual]

Defines creation strategy for ServiceHandler.

Default is to dynamically allocate new SERVICE_HANDLER, if one is not given as an argument.

Parameters:
sh_pointer to SERVICE_HANDLER, or NULL, if it is expected to be created here
Returns:
pointer to SERVICE_HANDLER

Definition at line 289 of file Connector.h.

References ASSA::SOCKTRACE, and trace_with_mask.

{
    trace_with_mask("Connector::makeServiceHandler",SOCKTRACE);

    SERVICE_HANDLER* new_sh = sh_;

    if (sh_ == 0) {
        new_sh = new SERVICE_HANDLER;
    }
    return new_sh;
}
template<class SH , class PEER_CONNECTOR >
int ASSA::Connector< SH, PEER_CONNECTOR >::open ( const TimeVal tv_ = TimeVal (5.0),
ConnectMode  mode_ = sync,
Reactor r_ = (Reactor*)NULL 
) [virtual]

Configure Connector.

Timeout will be used to timeout connection operation. If mode_ is async, then Reactor r_ ought to be specified for handling asynchronous event processing. Derive classes can change this strategy by overloading this method.

Parameters:
tv_Time for connection timeout (Default = 5.0 secs.)
mode_Synchronous or Asynchronous mode.
r_Reactor to work with (for async mode).
Returns:
0 on success, -1 on error.

Definition at line 223 of file Connector.h.

References ASSA::async, ASSA::SOCKTRACE, and trace_with_mask.

Referenced by ASSA::Logger::log_open().

{
    trace_with_mask("Connector::open", SOCKTRACE);

    m_timeout = tv_;
    if (async == mode_ && (Reactor*) NULL == r_) 
        return -1;
    m_mode = mode_;
    m_reactor = r_;
    return 0;
}

Member Data Documentation

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_fd [protected]

Socket file descriptor.

Definition at line 179 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_flags [protected]

Socket flags (obsolete)

Definition at line 173 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
ConnectMode ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_mode [protected]

Mode (sync/async)

Definition at line 182 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
Reactor* ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_reactor [protected]

Reference to Reactor (for async)

Definition at line 167 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
SERVICE_HANDLER* ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_sh [protected]

Reference to ServiceHandler.

Definition at line 176 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
ProgressState ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_state [protected]

Connection progress state.

Definition at line 170 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
TimerId ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_tid [protected]

Timer id.

Definition at line 164 of file Connector.h.

template<class SERVICE_HANDLER, class PEER_CONNECTOR>
TimeVal ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::m_timeout [protected]

Timeout.

Definition at line 161 of file Connector.h.


The documentation for this class was generated from the following file:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines