libassa  3.5.1
Acceptor.h
Go to the documentation of this file.
1 // -*- c++ -*-
2 //------------------------------------------------------------------------
3 // Acceptor.h
4 //------------------------------------------------------------------------
5 // Copyright (C) 1999 Vladislav Grinchenko
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Library General Public
9 // License as published by the Free Software Foundation; either
10 // version 2 of the License, or (at your option) any later version.
11 //------------------------------------------------------------------------
12 #ifndef ACCEPTOR_H
13 #define ACCEPTOR_H
14 
15 #include "assa/Logger.h"
16 #include "assa/EventHandler.h"
17 #include "assa/Address.h"
18 #include "assa/Reactor.h"
19 #include "assa/ServiceHandler.h"
20 
40 namespace ASSA {
41 
42 template<class SERVICE_HANDLER, class PEER_ACCEPTOR>
43 class Acceptor : public virtual EventHandler
44 {
45 public:
49  Acceptor (Reactor* r_);
50 
54  virtual ~Acceptor ();
55 
63  virtual int open (const Address& local_addr_);
64 
68  virtual int close (void);
69 
79  int handle_read (int fd);
80 
91  virtual int handle_close (int fd);
92 
93 protected:
98  virtual SERVICE_HANDLER* makeServiceHandler (PEER_ACCEPTOR* sock_);
99 
108  virtual int acceptServiceHandler (PEER_ACCEPTOR*& new_socket_);
109 
118  virtual int activateServiceHandler (PEER_ACCEPTOR* new_socket_);
119 
120 protected:
123  PEER_ACCEPTOR m_listenSocket;
124 
125 private:
126 
130 };
131 
132 // Convenience definitions
133 
134 #define SH SERVICE_HANDLER
135 #define PA PEER_ACCEPTOR
136 
137 //------------------------------------------------------------------------------
138 // Template member functions definitions
139 //------------------------------------------------------------------------------
140 
141 template<class SH, class PA>
142 inline
144 Acceptor (Reactor* r_)
145  : m_reactor (r_)
146 {
147  trace("Acceptor::Acceptor");
148 }
149 
150 template<class SH, class PA>
151 inline
153 ~Acceptor ()
154 {
155  trace("Acceptor::~Acceptor");
156 }
157 
158 template<class SH, class PA>
159 inline int
161 close (void)
162 {
163  trace("Acceptor::close");
164  m_listenSocket.close ();
165  return 0;
166 }
167 
168 template<class SH, class PA>
169 inline int
171 handle_close (int /* fd */)
172 {
173  trace("Acceptor::handle_close");
174 
175  // Reactor::get_instance ()->removeHandler (this->id());
176 
177  // NOT IMPLEMENTED: This spot requires validation
178  // whether Acceptor is created on the heap or in
179  // automatic memory.
180  DL ((REACT,"Deleted acceptor \"%s\"\n", get_id ().c_str ()));
181  delete this;
182  return -1;
183 }
184 
185 template<class SH, class PA>
186 inline SERVICE_HANDLER*
188 makeServiceHandler (PEER_ACCEPTOR* sock_)
189 {
190  trace("Acceptor<>::makeServiceHandler");
191 
192  return new SERVICE_HANDLER (sock_);
193 }
194 
195 template<class SH, class PA>
196 inline int
198 acceptServiceHandler (PEER_ACCEPTOR*& new_socket_)
199 {
200  trace("Acceptor::acceptServiceHandler");
201 
202  new_socket_ = m_listenSocket.accept ();
203  return new_socket_ ? 0 : -1;
204 }
205 
206 template<class SH, class PA> int
208 activateServiceHandler (PA* new_socket_)
209 {
210  trace("Acceptor::activateServiceHandler");
211 
212  if (!new_socket_) {
213  return -1;
214  }
215  SH* sh = makeServiceHandler (new_socket_);
216  if (sh->open () < 0) {
217  sh->close ();
218  }
219  return 0;
220 }
221 
222 template<class SH, class PA> int
224 open (const Address& local_addr_)
225 {
226  trace("Acceptor::open");
227 
228  if ( !m_listenSocket.open (local_addr_.getAddress ()->sa_family) ) {
229  return -1;
230  }
231 
232  if ( !m_listenSocket.bind (local_addr_) ) {
233  return -1;
234  }
235 
236  m_reactor->registerIOHandler (
237  this, m_listenSocket.getHandler (), READ_EVENT);
238 
239  DL((TRACE,"Opened acceptor for fd=%d\n",
240  m_listenSocket.getHandler ()));
241 
242  return 0;
243 }
244 
245 //------------------------------------------------------------------------------
246 // Accept all connections waiting in listen queue at once. This avoids going
247 // through Reactor's event loop for each new connection.
248 //------------------------------------------------------------------------------
249 
250 template <class SH, class PA> int
252 handle_read (int fd_)
253 {
254  trace("Acceptor<>::handle_read");
255 
256  FdSet mask;
257  timeval poll = {0, 0};
258  PA* new_socket = 0;
259 
260  int fd = m_listenSocket.getHandler ();
261 
262  if (fd != fd_) {
263  return -1;
264  }
265 
266  do {
267  if ( acceptServiceHandler (new_socket) == -1 ) {
268  return -1;
269  }
270  if ( !activateServiceHandler (new_socket) == -1 ) {
271  return -1;
272  }
273  mask.reset ();
274  mask.setFd (fd);
275  }
276  while ((::select (fd+1, &mask, NULL, NULL, &poll) == 1));
277 
278  return 0;
279 }
280 
281 } // end namespace ASSA
282 
283 #endif /* ACCEPTOR_H */
#define SH
Definition: Acceptor.h:134
#define PA
Definition: Acceptor.h:135
Address is an abstraction for INET or UNIX-domain address data type.
An abstract interface for handling I/O events, timers, and such.
An abstraction to message logging facility.
#define trace(s)
trace() is used to trace function call chain in C++ program.
Definition: Logger.h:429
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
An implementation of Reactor pattern.
This abstract class provides generic interface for processing services.
virtual int acceptServiceHandler(PEER_ACCEPTOR *&new_socket_)
Default strategy is to accept new connection.
Definition: Acceptor.h:198
PEER_ACCEPTOR m_listenSocket
Underlying communication stream.
Definition: Acceptor.h:123
int handle_read(int fd)
Callback invoked by Reactor when new connection requests is detected.
Definition: Acceptor.h:252
virtual SERVICE_HANDLER * makeServiceHandler(PEER_ACCEPTOR *sock_)
Defines creation strategy for ServiceHandler.
Definition: Acceptor.h:188
virtual int handle_close(int fd)
Callback invoked by Reactor if PEER_ACCEPTOR stream went bad, or Reactor has been commanded to stop e...
Definition: Acceptor.h:171
Reactor * m_reactor
Reactor to use.
Definition: Acceptor.h:129
virtual int close(void)
Close PEER_ACCEPTOR stream.
Definition: Acceptor.h:161
virtual ~Acceptor()
Do-nothing destructor.
Definition: Acceptor.h:153
Acceptor(Reactor *r_)
Default constructor.
Definition: Acceptor.h:144
virtual int activateServiceHandler(PEER_ACCEPTOR *new_socket_)
Defines the concurrency strategy.
Definition: Acceptor.h:208
virtual int open(const Address &local_addr_)
Initialize listener endpoint and Acceptor with Reactor.
Definition: Acceptor.h:224
virtual SA * getAddress() const =0
Retrieve pointer to the address structure.
EventHandler class.
Definition: EventHandler.h:103
Class FdSet.
Definition: FdSet.h:52
void reset()
Reset every bit in the set (OFF).
Definition: FdSet.cpp:90
bool setFd(handler_t fd_)
Set flag (ON) for the argument fd.
Definition: FdSet.cpp:20
Definition: Acceptor.h:40
@ READ_EVENT
Notify when there will be at least 1 byte available for reading from IO channel without blocking .
Definition: EventHandler.h:36
@ REACT
Class Reactor/PrioriyQueue messages
Definition: LogMask.h:39
@ TRACE
Function call trace
Definition: LogMask.h:26