libassa 3.5.1
Loading...
Searching...
No Matches
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.
 
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.
 
- Public Member Functions inherited from ASSA::EventHandler
 EventHandler ()
 Constructor.
 
virtual ~EventHandler ()
 Virtual destructor.
 
virtual int handle_read (int fd)
 Read event callback.
 
virtual int handle_except (int fd)
 Exception handler callback.
 
virtual int handle_signal (int signum_)
 Signal handler callback.
 
virtual int handle_close (int fd)
 EOF on peer socket handler callback.
 
virtual void resetState (void)
 A hook for derived class to reset internal state as needed.
 
void set_id (const std::string &id_)
 Set EventHandler ID.
 
std::string get_id () const
 Retrieve EventHandler ID.
 

Protected Types

enum  ProgressState { idle , waiting , conned , failed }
 state. More...
 

Protected Member Functions

virtual SERVICE_HANDLERmakeServiceHandler (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_HANDLERm_sh
 Reference to ServiceHandler.
 
int m_fd
 Socket file descriptor.
 
ConnectMode m_mode
 Mode (sync/async)
 
- Protected Attributes inherited from ASSA::EventHandler
std::string m_id
 

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

◆ ProgressState

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

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.
@ 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()

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

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

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

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.
@ ASSAERR
ASSA and system errors
Definition LogMask.h:34
int get_errno()
Fetch error number in a portable way.
@ async
Asynchronous connection mode.
Definition Connector.h:45

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

◆ connectServiceHandler()

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

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

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

◆ doSync()

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

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

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

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

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.

Member Data Documentation

◆ m_fd

Socket file descriptor.

Definition at line 179 of file Connector.h.

◆ m_flags

Socket flags (obsolete)

Definition at line 173 of file Connector.h.

◆ m_mode

Mode (sync/async)

Definition at line 182 of file Connector.h.

◆ m_reactor

Reference to Reactor (for async)

Definition at line 167 of file Connector.h.

◆ m_sh

Reference to ServiceHandler.

Definition at line 176 of file Connector.h.

◆ m_state

Connection progress state.

Definition at line 170 of file Connector.h.

◆ m_tid

Timer id.

Definition at line 164 of file Connector.h.

◆ m_timeout

Timeout.

Definition at line 161 of file Connector.h.


The documentation for this class was generated from the following file: