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 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
00247
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 }
00282
00283 #endif