libassa  3.5.1
Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
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

Public Member Functions

 Connector ()
 Constructor. Do-nothing. More...
 
virtual ~Connector ()
 Destructor. Do-nothing. More...
 
virtual int open (const TimeVal &tv_=TimeVal(5.0), ConnectMode mode_=sync, Reactor *r_=(Reactor *) NULL)
 Configure Connector. More...
 
virtual int close (void)
 Do-nothing close. More...
 
virtual int connect (SERVICE_HANDLER *sh_, Address &addr_, int protocol_=AF_INET)
 Define strategy for establishing connection. More...
 
virtual int handle_write (int fd)
 Handle connection completion. More...
 
virtual int handle_timeout (TimerId tid)
 Handler connection timeout. More...
 
- Public Member Functions inherited from ASSA::EventHandler
 EventHandler ()
 Constructor. More...
 
virtual ~EventHandler ()
 Virtual destructor. More...
 
virtual int handle_read (int fd)
 Read event callback. More...
 
virtual int handle_except (int fd)
 Exception handler callback. More...
 
virtual int handle_signal (int signum_)
 Signal handler callback. More...
 
virtual int handle_close (int fd)
 EOF on peer socket handler callback. More...
 
virtual void resetState (void)
 A hook for derived class to reset internal state as needed. More...
 
void set_id (const std::string &id_)
 Set EventHandler ID. More...
 
std::string get_id () const
 Retrieve EventHandler ID. More...
 

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. More...
 
virtual int connectServiceHandler (Address &addr, int protocol)
 Default strategy is to make synchronous connection with no timeouts. More...
 
virtual int activateServiceHandler ()
 Activate handler by calling its open() method. More...
 

Protected Attributes

TimeVal m_timeout
 Timeout. More...
 
TimerId m_tid
 Timer id. More...
 
Reactorm_reactor
 Reference to Reactor (for async) More...
 
ProgressState m_state
 Connection progress state. More...
 
int m_flags
 Socket flags (obsolete) More...
 
SERVICE_HANDLER * m_sh
 Reference to ServiceHandler. More...
 
int m_fd
 Socket file descriptor. More...
 
ConnectMode m_mode
 Mode (sync/async) More...
 
- Protected Attributes inherited from ASSA::EventHandler
std::string m_id
 

Private Member Functions

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

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

◆ ProgressState

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.

131  {
132  idle,
133  waiting,
134  conned,
135  failed
136  };
@ idle
Initialized.
Definition: Connector.h:132
@ failed
Failed to connect.
Definition: Connector.h:135
@ conned
Connected.
Definition: Connector.h:134
@ waiting
Asynchronously waiting on connection completion.
Definition: Connector.h:133

Constructor & Destructor Documentation

◆ Connector()

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

Constructor. Do-nothing.

Definition at line 204 of file Connector.h.

206  : m_tid (0), m_reactor (0), m_state (idle),
207  m_flags (0), m_sh ((SERVICE_HANDLER*)NULL), m_fd (-1), m_mode (sync)
208 {
209  trace_with_mask("Connector::Connector",SOCKTRACE);
210  set_id ("Connector");
211 }
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
int m_flags
Socket flags (obsolete)
Definition: Connector.h:173
ConnectMode m_mode
Mode (sync/async)
Definition: Connector.h:182
ProgressState m_state
Connection progress state.
Definition: Connector.h:170
SERVICE_HANDLER * m_sh
Reference to ServiceHandler.
Definition: Connector.h:176
TimerId m_tid
Timer id.
Definition: Connector.h:164
int m_fd
Socket file descriptor.
Definition: Connector.h:179
Reactor * m_reactor
Reference to Reactor (for async)
Definition: Connector.h:167
void set_id(const std::string &id_)
Set EventHandler ID.
Definition: EventHandler.h:153
@ SOCKTRACE
Extended Socket & friends messages
Definition: LogMask.h:42
@ sync
Synchronous connection mode.
Definition: Connector.h:44

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

◆ ~Connector()

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

Destructor. Do-nothing.

Definition at line 214 of file Connector.h.

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

References ASSA::SOCKTRACE, and trace_with_mask.

Member Function Documentation

◆ activateServiceHandler()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::activateServiceHandler
protectedvirtual

Activate handler by calling its open() method.

Returns
0 on success, -1 on error.

Definition at line 322 of file Connector.h.

324 {
325  trace_with_mask("Connector::activateServiceHandler",SOCKTRACE);
326 
327  return m_sh->open ();
328 }

References ASSA::SOCKTRACE, and trace_with_mask.

◆ close()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, 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 236 of file Connector.h.

238 {
239  trace_with_mask("Connector::close",SOCKTRACE);
240  return 0;
241 }

References ASSA::SOCKTRACE, and trace_with_mask.

◆ connect()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
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.

Definition at line 244 of file Connector.h.

246 {
247  /*
248  * We restore socket to its original mode only on
249  * successful connection. If error occured, client would have
250  * to close socket anyway.
251  *
252  * NOTE: If sh_==0, then result is dangling pointer
253  * new_sh produced ! Destructor should determine whether
254  * SERVICE_HANDLER has been created dynamically and if so, delete
255  * it.
256  */
257  trace_with_mask("Connector::connect",SOCKTRACE);
258  errno = 0;
259 
260  m_sh = makeServiceHandler (sh_);
261  PEER_CONNECTOR& s = *m_sh;
262 
263  if (addr_.bad ()) {
264  set_errno (EFAULT); // Bad address
265  EL((ASSA::ASSAERR,"Bad address (errno %d)\n", errno));
266  return -1;
267  }
268 
269  if (connectServiceHandler (addr_, protocol_family_) == -1)
270  {
271  int e = get_errno ();
272  if (e == EINPROGRESS || e == EWOULDBLOCK)
273  {
274  if (async == m_mode) {
275  doAsync ();
276  return 0;
277  }
278 
279  return doSync ();
280  }
281  return -1;
282  }
283 
284  return activateServiceHandler ();
285 }
#define EL(X)
A macro for writing error message to the Logger.
Definition: Logger.h:285
void doAsync(void)
Setup for asynchronous mode completion.
Definition: Connector.h:332
virtual int connectServiceHandler(Address &addr, int protocol)
Default strategy is to make synchronous connection with no timeouts.
Definition: Connector.h:303
virtual int activateServiceHandler()
Activate handler by calling its open() method.
Definition: Connector.h:323
virtual SERVICE_HANDLER * makeServiceHandler(SERVICE_HANDLER *sh_)
Defines creation strategy for ServiceHandler.
Definition: Connector.h:289
int doSync(void)
Synchronous mode completion.
Definition: Connector.h:349
void set_errno(int new_errno_)
Set error number in a portable way.
Definition: Logger_Impl.h:128
@ ASSAERR
ASSA and system errors
Definition: LogMask.h:34
int get_errno()
Fetch error number in a portable way.
Definition: Logger_Impl.h:115
@ async
Asynchronous connection mode.
Definition: Connector.h:45

References ASSA::ASSAERR, ASSA::async, ASSA::Address::bad(), EL, ASSA::get_errno(), ASSA::set_errno(), ASSA::SOCKTRACE, and trace_with_mask.

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

◆ connectServiceHandler()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::connectServiceHandler ( Address addr,
int  protocol 
)
protectedvirtual

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 302 of file Connector.h.

304 {
305  trace_with_mask("Connector::connectServiceHandler",SOCKTRACE);
306 
307  PEER_CONNECTOR& s = *m_sh;
308 
309  if ( !s.open (protocol_family_) ) {
310  EL((ASSA::ASSAERR,"Socket::open (protocol=%d) failed\n",
311  protocol_family_));
312  return -1;
313  }
314 
315  m_fd = s.getHandler ();
316  s.setOption (ASSA::Socket::nonblocking, 1);
317 
318  return (s.connect (addr_) ? 0 : -1);
319 }
@ nonblocking
Set Socket to a non-blocking mode (O_RDWR|O_NONBLOCK).
Definition: Socket.h:115

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

◆ doAsync()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
void ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::doAsync ( void  )
private

Setup for asynchronous mode completion.

Definition at line 331 of file Connector.h.

333 {
334  trace_with_mask("Connector::doAsync",SOCKTRACE);
335 
336  /* We are doing async and 3-way handshake is in
337  * progress - hook up with Reactor and wait on timer.
338  * Write event will be our indicator whether connection
339  * was completed or not.
340  */
342 
343  m_tid = m_reactor->registerTimerHandler (this, m_timeout, "ASYNC Connect");
344  m_state = waiting;
345 }
TimeVal m_timeout
Timeout.
Definition: Connector.h:161
bool registerIOHandler(EventHandler *eh_, handler_t fd_, EventType et_=RWE_EVENTS)
Register I/O Event handler with Reactor.
Definition: Reactor.cpp:93
TimerId registerTimerHandler(EventHandler *eh_, const TimeVal &tv_, const std::string &name_="<unknown>")
Register Timer Event handler with Reactor.
Definition: Reactor.cpp:67
@ WRITE_EVENT
Notify when there will be room for at least 1 byte to be written to IO channel without blocking.
Definition: EventHandler.h:39

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

◆ doSync()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::doSync ( void  )
private

Synchronous mode completion.

Returns
0 on success; -1 if error.

Definition at line 348 of file Connector.h.

350 {
351  trace_with_mask("Connector::doSync",SOCKTRACE);
352 
353  m_reactor = new Reactor;
354 
356  m_reactor->registerTimerHandler (this, m_timeout, "SYNC Connect");
357  m_state = waiting;
358  m_reactor->waitForEvents (&m_timeout); // Let the ball rolling ...
359  m_reactor->removeHandler (this); // Remove all handlers.
360 
361  delete m_reactor;
362  m_reactor = 0;
363 
364  if (conned == m_state)
365  {
366  DL((SOCKTRACE,"Synchronous connect() succeeded.\n"));
367  return 0;
368  }
369 
370  EL((ASSA::ASSAERR,"Synchronous connect() timed out.\n"));
371  set_errno (ETIMEDOUT);
372 
373  return -1;
374 }
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
void waitForEvents(void)
Main waiting loop that blocks indefinitely processing events.
Definition: Reactor.cpp:470
bool removeHandler(EventHandler *eh_, EventType et_=ALL_EVENTS)
Remove Event handler from reactor for either all I/O events or timeout event or both.
Definition: Reactor.cpp:173

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

◆ handle_timeout()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::handle_timeout ( TimerId  tid)
virtual

Handler connection timeout.

Reimplemented from ASSA::EventHandler.

Definition at line 473 of file Connector.h.

475 {
476  trace_with_mask("Connector::handle_timeout",SOCKTRACE);
477 
478  m_state = failed;
479  set_errno (ETIMEDOUT); // Connection timed out
480 
481  if (async == m_mode) {
483  }
484  return -1; // Remove Timer Handler
485 }

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

◆ handle_write()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::handle_write ( int  fd)
virtual

Handle connection completion.

Always remove IO handler first.

Reimplemented from ASSA::EventHandler.

Definition at line 377 of file Connector.h.

379 {
380  trace_with_mask("Connector::handle_write",SOCKTRACE);
381 
382  /* Precondition
383  */
384  if (fd_ != m_fd) {
385  return -1;
386  }
387 
388  /* This method serves both sync and async modes - thus the
389  * differences. For async we remove Timer here. sync runs
390  * its own private Reactor and handler termination is
391  * handled in doSync().
392  */
393 
394  if (async == m_mode) { // Complete SH activation
396  m_tid = 0;
397  }
398 
399  /*
400  * Although SUN and Linux man pages on connect(3) claims that
401  * "upon asynchronous establishement of connection, select(3)
402  * will indicate that the file descriptor for the socket is ready
403  * for writing", as discussed in W.S.Stevens "UNIX network
404  * programming", Vol I, 2nd edition, BSD-derived systems also
405  * mark file descriptor both readable and writable when the
406  * connection establishment encouters an error.
407  *
408  * Therefore we need an extra step to find out what really happened.
409  * One way to do so is to look at socket pending errors...
410  */
411 
412  int error;
413  int ret;
414  error = ret = errno = 0;
415  socklen_t n = sizeof (error);
416 
420 
421 #if defined(__CYGWIN32__)
422  ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, (int*)&n);
423 #elif defined (WIN32)
424  ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, (int*)&n);
425 #else
426  ret = getsockopt (m_fd, SOL_SOCKET, SO_ERROR, (void*)&error, &n);
427 #endif
428 
429  if (ret == 0) {
430  if (error == 0)
431  {
432  if (activateServiceHandler () == 0) {
433  DL((SOCKTRACE,"Nonblocking connect() completed\n"));
434  m_state = conned;
435  }
436  else {
437  DL((SOCKTRACE,"Nonblocking connect() failed\n"));
438  m_state = failed;
439  }
440  return (0); // return value doesn't really matter
441  }
442  /* Socket pending error - propagate it via errno. */
443 
444  EL((ASSA::ASSAERR,"Socket pending error: %d\n",error));
445  set_errno (error);
446  }
447  else { /* Solaris pending error. */
448  EL((ASSA::ASSAERR,"getsockopt(3) = %d\n", ret));
449  EL((ASSA::ASSAERR,"Solaris pending error!\n"));
450  }
451  m_state = failed;
452 
453  EL((ASSA::ASSAERR,"Nonblocking connect (2) failed\n"));
454 
455  if (get_errno () == ECONNREFUSED)
456  {
457  EL((ASSA::ASSAERR,"Try to compare port "
458  "numbers on client and service hosts.\n"));
459  }
460  /* This is the only way to tell SH that we failed to connect.
461  */
462  if (async == m_mode) {
463  m_sh->close ();
464  }
465 
466  /* Don't alter fd mask - SERVICE_HANDLER::open() could have changed
467  * it already for application processing needs.
468  */
469  return 0;
470 }
bool removeTimerHandler(TimerId id_)
Remove Timer event from the queue.
Definition: Reactor.cpp:152

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

◆ makeServiceHandler()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
SERVICE_HANDLER * ASSA::Connector< SERVICE_HANDLER, PEER_CONNECTOR >::makeServiceHandler ( SERVICE_HANDLER *  sh_)
protectedvirtual

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 288 of file Connector.h.

290 {
291  trace_with_mask("Connector::makeServiceHandler",SOCKTRACE);
292 
293  SERVICE_HANDLER* new_sh = sh_;
294 
295  if (sh_ == 0) {
296  new_sh = new SERVICE_HANDLER;
297  }
298  return new_sh;
299 }

References ASSA::SOCKTRACE, and trace_with_mask.

◆ open()

template<class SERVICE_HANDLER , class PEER_CONNECTOR >
int ASSA::Connector< SERVICE_HANDLER, 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 222 of file Connector.h.

224 {
225  trace_with_mask("Connector::open", SOCKTRACE);
226 
227  m_timeout = tv_;
228  if (async == mode_ && (Reactor*) NULL == r_)
229  return -1;
230  m_mode = mode_;
231  m_reactor = r_;
232  return 0;
233 }

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

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

Member Data Documentation

◆ m_fd

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.

◆ m_flags

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.

◆ m_mode

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.

◆ m_reactor

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.

◆ m_sh

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.

◆ m_state

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.

◆ m_tid

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.

◆ m_timeout

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: