libassa 3.5.0

/builddir/build/BUILD/libassa-3.5.0/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     if (sh->open () < 0) {
00217         sh->close ();
00218     }
00219     return 0;
00220 }
00221 
00222 template<class SH, class PA> int
00223 Acceptor<SH, PA>::
00224 open (const Address& local_addr_)
00225 {
00226     trace("Acceptor::open");
00227     
00228     if ( !m_listenSocket.open (local_addr_.getAddress ()->sa_family) ) {
00229         return -1;
00230     }
00231 
00232     if ( !m_listenSocket.bind (local_addr_) ) {
00233         return -1;
00234     }
00235 
00236     m_reactor->registerIOHandler (
00237         this, m_listenSocket.getHandler (), READ_EVENT);
00238     
00239     DL((TRACE,"Opened acceptor for fd=%d\n", 
00240         m_listenSocket.getHandler ()));
00241 
00242     return 0;
00243 }
00244 
00245 //------------------------------------------------------------------------------
00246 // Accept all connections waiting in listen queue at once. This avoids going 
00247 // through Reactor's event loop for each new connection.
00248 //------------------------------------------------------------------------------
00249 
00250 template <class SH, class PA> int
00251 Acceptor<SH, PA>::
00252 handle_read (int fd_)
00253 {
00254     trace("Acceptor<>::handle_read");
00255 
00256     FdSet mask;
00257     timeval poll = {0, 0};
00258     PA* new_socket = 0;
00259 
00260     int fd = m_listenSocket.getHandler ();
00261 
00262     if (fd != fd_) {
00263         return -1;
00264     }
00265 
00266     do {
00267         if ( acceptServiceHandler (new_socket) == -1 ) {
00268             return -1;
00269         }
00270         if ( !activateServiceHandler (new_socket) == -1 ) {
00271             return -1;
00272         }
00273         mask.reset ();
00274         mask.setFd (fd);
00275     }
00276     while ((::select (fd+1, &mask, NULL, NULL, &poll) == 1));
00277 
00278     return 0;
00279 }
00280 
00281 } // end namespace ASSA
00282 
00283 #endif /* ACCEPTOR_H */  
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines