/home/vlg/develop/libASSA/libassa/assa/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>::
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 /* fd */) 
00172 {
00173     trace("Acceptor::handle_close");
00174     
00175     // Reactor::get_instance ()->removeHandler (this->id());
00176     
00177     // NOT IMPLEMENTED: This spot requires validation
00178     // whether Acceptor is created on the heap or in
00179     // automatic memory.
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 // Accept all connections waiting in listen queue at once. This avoids going 
00245 // through Reactor's event loop for each new connection.
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 } // end namespace ASSA
00280 
00281 #endif /* ACCEPTOR_H */  

Generated on Sun Aug 13 15:08:00 2006 for libassa by  doxygen 1.4.6