00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef ACCEPTOR_H
00013 #define ACCEPTOR_H
00014
00015 #include "assa/Logger.h"
00016 #include "assa/EventHandler.h"
00017 #include "assa/Address.h"
00018 #include "assa/Reactor.h"
00019 #include "assa/ServiceHandler.h"
00020
00040 namespace ASSA {
00041
00042 template<class SERVICE_HANDLER, class PEER_ACCEPTOR>
00043 class Acceptor : public virtual EventHandler
00044 {
00045 public:
00049 Acceptor (Reactor* r_);
00050
00054 virtual ~Acceptor ();
00055
00063 virtual int open (const Address& local_addr_);
00064
00068 virtual int close (void);
00069
00079 int handle_read (int fd);
00080
00091 virtual int handle_close (int fd);
00092
00093 protected:
00098 virtual SERVICE_HANDLER* makeServiceHandler (PEER_ACCEPTOR* sock_);
00099
00108 virtual int acceptServiceHandler (PEER_ACCEPTOR*& new_socket_);
00109
00118 virtual int activateServiceHandler (PEER_ACCEPTOR* new_socket_);
00119
00120 protected:
00123 PEER_ACCEPTOR m_listenSocket;
00124
00125 private:
00126
00129 Reactor* m_reactor;
00130 };
00131
00132
00133
00134 #define SH SERVICE_HANDLER
00135 #define PA PEER_ACCEPTOR
00136
00137
00138
00139
00140
00141 template<class SH, class PA>
00142 inline
00143 Acceptor<SH, PA>::
00144 Acceptor (Reactor* r_)
00145 : m_reactor (r_)
00146 {
00147 trace("Acceptor::Acceptor");
00148 }
00149
00150 template<class SH, class PA>
00151 inline
00152 Acceptor<SH, PA>::
00153 ~Acceptor ()
00154 {
00155 trace("Acceptor::~Acceptor");
00156 }
00157
00158 template<class SH, class PA>
00159 inline int
00160 Acceptor<SH, PA>::
00161 close (void)
00162 {
00163 trace("Acceptor::close");
00164 m_listenSocket.close ();
00165 return 0;
00166 }
00167
00168 template<class SH, class PA>
00169 inline int
00170 Acceptor<SH, PA>::
00171 handle_close (int )
00172 {
00173 trace("Acceptor::handle_close");
00174
00175
00176
00177
00178
00179
00180 DL ((REACT,"Deleted acceptor \"%s\"\n", get_id ().c_str ()));
00181 delete this;
00182 return -1;
00183 }
00184
00185 template<class SH, class PA>
00186 inline SERVICE_HANDLER*
00187 Acceptor<SH, PA>::
00188 makeServiceHandler (PEER_ACCEPTOR* sock_)
00189 {
00190 trace("Acceptor<>::makeServiceHandler");
00191
00192 return new SERVICE_HANDLER (sock_);
00193 }
00194
00195 template<class SH, class PA>
00196 inline int
00197 Acceptor<SH, PA>::
00198 acceptServiceHandler (PEER_ACCEPTOR*& new_socket_)
00199 {
00200 trace("Acceptor::acceptServiceHandler");
00201
00202 new_socket_ = m_listenSocket.accept ();
00203 return new_socket_ ? 0 : -1;
00204 }
00205
00206 template<class SH, class PA> int
00207 Acceptor<SH, PA>::
00208 activateServiceHandler (PA* new_socket_)
00209 {
00210 trace("Acceptor::activateServiceHandler");
00211
00212 if (!new_socket_) {
00213 return -1;
00214 }
00215 SH* sh = makeServiceHandler (new_socket_);
00216 sh->open ();
00217 return 0;
00218 }
00219
00220 template<class SH, class PA> int
00221 Acceptor<SH, PA>::
00222 open (const Address& local_addr_)
00223 {
00224 trace("Acceptor::open");
00225
00226 if ( !m_listenSocket.open (local_addr_.getAddress ()->sa_family) ) {
00227 return -1;
00228 }
00229
00230 if ( !m_listenSocket.bind (local_addr_) ) {
00231 return -1;
00232 }
00233
00234 m_reactor->registerIOHandler (
00235 this, m_listenSocket.getHandler (), READ_EVENT);
00236
00237 DL((TRACE,"Opened acceptor for fd=%d\n",
00238 m_listenSocket.getHandler ()));
00239
00240 return 0;
00241 }
00242
00243
00244
00245
00246
00247
00248 template <class SH, class PA> int
00249 Acceptor<SH, PA>::
00250 handle_read (int fd_)
00251 {
00252 trace("Acceptor<>::handle_read");
00253
00254 FdSet mask;
00255 timeval poll = {0, 0};
00256 PA* new_socket = 0;
00257
00258 int fd = m_listenSocket.getHandler ();
00259
00260 if (fd != fd_) {
00261 return -1;
00262 }
00263
00264 do {
00265 if ( acceptServiceHandler (new_socket) == -1 ) {
00266 return -1;
00267 }
00268 if ( !activateServiceHandler (new_socket) == -1 ) {
00269 return -1;
00270 }
00271 mask.reset ();
00272 mask.setFd (fd);
00273 }
00274 while ((::select (fd+1, &mask, NULL, NULL, &poll) == 1));
00275
00276 return 0;
00277 }
00278
00279 }
00280
00281 #endif