Acceptor.h

Go to the documentation of this file.
00001 // -*- c++ -*-
00002 //------------------------------------------------------------------------
00003 //                            Acceptor.h
00004 //------------------------------------------------------------------------
00005 //  Copyright (C) 1999  Vladislav Grinchenko
00006 //
00007 //  This library is free software; you can redistribute it and/or
00008 //  modify it under the terms of the GNU Library General Public
00009 //  License as published by the Free Software Foundation; either
00010 //  version 2 of the License, or (at your option) any later version.
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 // Convenience definitions
00133 
00134 #define SH SERVICE_HANDLER
00135 #define PA PEER_ACCEPTOR
00136 
00137 //------------------------------------------------------------------------------
00138 // Template member functions definitions
00139 //------------------------------------------------------------------------------
00140 
00141 template<class SH, class PA>
00142 inline
00143 Acceptor<SH, PA>::Acceptor (Reactor* r_) 
00144     : m_reactor (r_)
00145 {
00146     trace("Acceptor::Acceptor");
00147 }
00148 
00149 template<class SH, class PA>
00150 inline
00151 Acceptor<SH, PA>::~Acceptor () 
00152 {
00153     trace("Acceptor::~Acceptor");
00154 }
00155 
00156 template<class SH, class PA> 
00157 inline int 
00158 Acceptor<SH, PA>::close (void) 
00159 {
00160     trace("Acceptor::close");
00161     m_listenSocket.close ();
00162     return 0;
00163 }
00164 
00165 template<class SH, class PA> 
00166 inline int 
00167 Acceptor<SH, PA>::handle_close (int /* fd */) 
00168 {
00169     trace("Acceptor::handle_close");
00170     
00171     // Reactor::get_instance ()->removeHandler (this->id());
00172     
00173     // NOT IMPLEMENTED: This spot requires validation
00174     // whether Acceptor is created on the heap or
00175     // automatic memory.
00176     
00177     delete this;
00178     return -1;
00179 }
00180 
00181 template<class SH, class PA> 
00182 inline SERVICE_HANDLER* 
00183 Acceptor<SH, PA>::makeServiceHandler (PEER_ACCEPTOR* sock_) 
00184 {
00185     trace("Acceptor<>::makeServiceHandler");
00186     
00187     return new SERVICE_HANDLER (sock_);
00188 }
00189 
00190 template<class SH, class PA> 
00191 inline int 
00192 Acceptor<SH, PA>::acceptServiceHandler (PEER_ACCEPTOR*& new_socket_) 
00193 {
00194     trace("Acceptor::acceptServiceHandler");
00195     
00196     new_socket_ = m_listenSocket.accept ();
00197     return new_socket_ ? 0 : -1;
00198 }
00199 
00200 template<class SH, class PA> int 
00201 Acceptor<SH, PA>::activateServiceHandler (PA* new_socket_) 
00202 {
00203     trace("Acceptor::activateServiceHandler");
00204 
00205     if (!new_socket_) {
00206         return -1;
00207     }
00208     SH* sh = makeServiceHandler (new_socket_);
00209     sh->open ();
00210     return 0;
00211 }
00212 
00213 template<class SH, class PA> int
00214 Acceptor<SH, PA>::open (const Address& local_addr_)
00215 {
00216     trace("Acceptor::open");
00217     
00218     if ( !m_listenSocket.open (local_addr_.getAddress ()->sa_family) ) {
00219         return -1;
00220     }
00221 
00222     if ( !m_listenSocket.bind (local_addr_) ) {
00223         return -1;
00224     }
00225 
00226     m_reactor->registerIOHandler (
00227         this, m_listenSocket.getHandler (), READ_EVENT);
00228     
00229     DL((TRACE,"Acceptor on FD - %d\n", m_listenSocket.getHandler ()));
00230     return 0;
00231 }
00232 
00233 //------------------------------------------------------------------------------
00234 // Accept all connections waiting in listen queue at once. This avoids going 
00235 // through Reactor's event loop for each new connection.
00236 //------------------------------------------------------------------------------
00237 
00238 template <class SH, class PA> int
00239 Acceptor<SH, PA>::handle_read (int fd_)
00240 {
00241     trace("Acceptor<>::handle_read");
00242 
00243     int fd = m_listenSocket.getHandler ();
00244 
00245     if (fd != fd_) return -1;
00246 
00247     FdSet mask;
00248     timeval poll = {0, 0};
00249     PA* new_socket;
00250 
00251     do {
00252         if ( acceptServiceHandler (new_socket) == -1 ) {
00253             return -1;
00254         }
00255         if ( !activateServiceHandler (new_socket) == -1 ) {
00256             return -1;
00257         }
00258         mask.reset ();
00259         mask.setFd (fd);
00260     }
00261     while ( (::select (fd+1, &mask, NULL, NULL, &poll) == 1) );
00262 
00263     return 0;
00264 }
00265 
00266 } // end namespace ASSA
00267 
00268 #endif /* ACCEPTOR_H */  

Generated on Mon Dec 19 16:20:18 2005 for libassa by  doxygen 1.4.5