Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Asynch_Acceptor.cpp

Go to the documentation of this file.
00001 /* -*- C++ -*- */
00002 // $Id: Asynch_Acceptor.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00003 
00004 #ifndef ACE_ASYNCH_ACCEPTOR_C
00005 #define ACE_ASYNCH_ACCEPTOR_C
00006 
00007 #include "ace/Asynch_Acceptor.h"
00008 
00009 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00010 # pragma once
00011 #endif /* ACE_LACKS_PRAGMA_ONCE */
00012 
00013 ACE_RCSID(ace, Asynch_Acceptor, "$Id: Asynch_Acceptor.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $")
00014 
00015 #if defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)
00016 // This only works on platforms that support async i/o.
00017 
00018 #include "ace/OS.h"
00019 #include "ace/Log_Msg.h"
00020 #include "ace/Message_Block.h"
00021 #include "ace/INET_Addr.h"
00022 #include "ace/SOCK_Stream.h"
00023 #include "ace/Sock_Connect.h"
00024 #include "ace/Trace.h"
00025 
00026 template <class HANDLER>
00027 ACE_Asynch_Acceptor<HANDLER>::ACE_Asynch_Acceptor (void)
00028   : listen_handle_ (ACE_INVALID_HANDLE),
00029     pass_addresses_ (0),
00030     validate_new_connection_ (0),
00031     reissue_accept_ (1),
00032     bytes_to_read_ (0)
00033 {
00034 }
00035 
00036 template <class HANDLER>
00037 ACE_Asynch_Acceptor<HANDLER>::~ACE_Asynch_Acceptor (void)
00038 {
00039   //this->asynch_accept_.close ();
00040 
00041   // Close down the listen socket
00042   // if (this->listen_handle_ != ACE_INVALID_HANDLE)
00043   //   ACE_OS::closesocket (this->listen_handle_);
00044 }
00045 
00046 template <class HANDLER> int
00047 ACE_Asynch_Acceptor<HANDLER>::open (const ACE_INET_Addr &address,
00048                                     size_t bytes_to_read,
00049                                     int pass_addresses,
00050                                     int backlog,
00051                                     int reuse_addr,
00052                                     ACE_Proactor *proactor,
00053                                     int validate_new_connection,
00054                                     int reissue_accept,
00055                                     int number_of_initial_accepts)
00056 {
00057   ACE_TRACE ("ACE_Asynch_Acceptor<>::open");
00058 
00059   this->proactor (proactor);
00060   this->pass_addresses_ = pass_addresses;
00061   this->bytes_to_read_ = bytes_to_read;
00062   this->validate_new_connection_ = validate_new_connection;
00063   this->reissue_accept_ = reissue_accept;
00064 
00065   // Create the listener socket
00066   this->listen_handle_ = ACE_OS::socket (address.get_type (), SOCK_STREAM, 0);
00067   if (this->listen_handle_ == ACE_INVALID_HANDLE)
00068     ACE_ERROR_RETURN ((LM_ERROR,
00069                        ACE_LIB_TEXT ("%p\n"),
00070                        ACE_LIB_TEXT ("ACE_OS::socket")),
00071                       -1);
00072   // Initialize the ACE_Asynch_Accept
00073   if (this->asynch_accept_.open (*this,
00074                                  this->listen_handle_,
00075                                  0,
00076                                  this->proactor ()) == -1)
00077     ACE_ERROR_RETURN ((LM_ERROR,
00078                        ACE_LIB_TEXT ("%p\n"),
00079                        ACE_LIB_TEXT ("ACE_Asynch_Accept::open")),
00080                       -1);
00081   if (reuse_addr)
00082     {
00083       // Reuse the address
00084       int one = 1;
00085       if (ACE_OS::setsockopt (this->listen_handle_,
00086                               SOL_SOCKET,
00087                               SO_REUSEADDR,
00088                               (const char*) &one,
00089                               sizeof one) == -1)
00090         ACE_ERROR_RETURN ((LM_ERROR,
00091                            ACE_LIB_TEXT ("%p\n"),
00092                            ACE_LIB_TEXT ("ACE_OS::setsockopt")),
00093                           -1);
00094     }
00095 
00096   // If port is not specified, bind to any port.
00097   static ACE_INET_Addr sa (ACE_sap_any_cast (const ACE_INET_Addr &));
00098 
00099   if (address == sa &&
00100       ACE_Sock_Connect::bind_port (this->listen_handle_) == -1)
00101     ACE_ERROR_RETURN ((LM_ERROR,
00102                        ACE_LIB_TEXT ("%p\n"),
00103                        ACE_LIB_TEXT ("ACE::bind_port")),
00104                       -1);
00105 
00106   // Bind to the specified port.
00107   if (ACE_OS::bind (this->listen_handle_,
00108                     ACE_reinterpret_cast (sockaddr *,
00109                                           address.get_addr ()),
00110                     address.get_size ()) == -1)
00111     ACE_ERROR_RETURN ((LM_ERROR,
00112                        "%p\n",
00113                        "ACE_OS::bind"),
00114                       -1);
00115 
00116   // Start listening.
00117   if (ACE_OS::listen (this->listen_handle_, backlog) == -1)
00118     ACE_ERROR_RETURN ((LM_ERROR,
00119                        "%p\n",
00120                        "ACE_OS::listen"),
00121                       -1);
00122 
00123   // For the number of <intial_accepts>.
00124   if (number_of_initial_accepts == -1)
00125     number_of_initial_accepts = backlog;
00126 
00127   for (int i = 0; i < number_of_initial_accepts; i++)
00128     // Initiate accepts.
00129     if (this->accept (bytes_to_read) == -1)
00130       ACE_ERROR_RETURN ((LM_ERROR,
00131                          "%p\n",
00132                          "ACE_Asynch_Acceptor::accept"),
00133                         -1);
00134   return 0;
00135 }
00136 
00137 template <class HANDLER> void
00138 ACE_Asynch_Acceptor<HANDLER>::set_handle (ACE_HANDLE listen_handle)
00139 {
00140   ACE_TRACE ("ACE_Asynch_Acceptor<>::set_handle");
00141 
00142   // Take ownership of the <listen_handle>
00143   this->listen_handle_ = listen_handle;
00144 
00145   // Reinitialize the ACE_Asynch_Accept
00146   if (this->asynch_accept_.open (*this,
00147                                  this->listen_handle_,
00148                                  0,
00149                                  this->proactor ()) == -1)
00150     ACE_ERROR ((LM_ERROR,
00151                 ACE_LIB_TEXT ("%p\n"),
00152                 ACE_LIB_TEXT ("ACE_Asynch_Accept::open")));
00153 }
00154 
00155 template <class HANDLER> ACE_HANDLE
00156 ACE_Asynch_Acceptor<HANDLER>::get_handle (void) const
00157 {
00158   return this->listen_handle_;
00159 }
00160 
00161 template <class HANDLER> int
00162 ACE_Asynch_Acceptor<HANDLER>::accept (size_t bytes_to_read, const void *act)
00163 {
00164   ACE_TRACE ("ACE_Asynch_Acceptor<>::accept");
00165 
00166   ACE_Message_Block *message_block = 0;
00167   size_t space_needed = bytes_to_read + 2 * this->address_size ();
00168 
00169   // Create a new message block big enough for the addresses and data
00170   ACE_NEW_RETURN (message_block,
00171                   ACE_Message_Block (space_needed),
00172                   -1);
00173 
00174   // Initiate asynchronous accepts
00175   if (this->asynch_accept_.accept (*message_block,
00176                                    bytes_to_read,
00177                                    ACE_INVALID_HANDLE,
00178                                    act) == -1)
00179     {
00180       // Cleanup on error
00181       message_block->release ();
00182       return -1;
00183     }
00184   return 0;
00185 }
00186 
00187 template <class HANDLER> void
00188 ACE_Asynch_Acceptor<HANDLER>::handle_accept (const ACE_Asynch_Accept::Result &result)
00189 {
00190 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) || defined (ACE_HAS_AIO_CALLS)
00191 
00192   ACE_TRACE ("ACE_Asynch_Acceptor<>::handle_accept");
00193 
00194   // Variable for error tracking
00195   int error = 0;
00196 
00197   // If the asynchronous accept fails.
00198   if (!result.success () ||
00199       result.accept_handle() == ACE_INVALID_HANDLE )
00200     {
00201       error = 1;
00202     }
00203 
00204 #if !defined (ACE_HAS_AIO_CALLS)
00205   // In order to use accept handle with other Window Sockets 1.1
00206   // functions, we call the setsockopt function with the
00207   // SO_UPDATE_ACCEPT_CONTEXT option. This option initializes the
00208   // socket so that other Windows Sockets routines to access the
00209   // socket correctly.
00210   if (!error &&
00211       ACE_OS::setsockopt (result.accept_handle (),
00212                           SOL_SOCKET,
00213                           SO_UPDATE_ACCEPT_CONTEXT,
00214                           (char *) &this->listen_handle_,
00215                           sizeof (this->listen_handle_)) == -1)
00216     {
00217       error = 1;
00218     }
00219 #endif /* ACE_HAS_AIO_CALLS */
00220 
00221   // Parse address.
00222   ACE_INET_Addr local_address;
00223   ACE_INET_Addr remote_address;
00224   if (!error &&
00225       (this->validate_new_connection_ || this->pass_addresses_))
00226     // Parse the addresses.
00227     this->parse_address (result,
00228                          remote_address,
00229                          local_address);
00230 
00231   // Validate remote address
00232   if (!error &&
00233       this->validate_new_connection_ &&
00234       (this->validate_connection (result, remote_address, local_address) == -1
00235        || this->validate_new_connection (remote_address) == -1))
00236     {
00237       error = 1;
00238     }
00239 
00240   HANDLER *new_handler = 0;
00241   if (!error)
00242     {
00243       // The Template method
00244       new_handler = this->make_handler ();
00245       if (new_handler == 0)
00246         {
00247           error = 1;
00248         }
00249     }
00250 
00251   // If no errors
00252   if (!error)
00253     {
00254       // Update the Proactor.
00255       new_handler->proactor (this->proactor ());
00256 
00257       // Pass the addresses
00258       if (this->pass_addresses_)
00259         new_handler->addresses (remote_address,
00260                                 local_address);
00261 
00262       // Pass the ACT
00263       if (result.act () != 0)
00264         new_handler->act (result.act ());
00265 
00266       // Set up the handler's new handle value
00267       new_handler->handle (result.accept_handle ());
00268 
00269       // Initiate the handler
00270       new_handler->open (result.accept_handle (),
00271                          result.message_block ());
00272     }
00273 
00274   // On failure, no choice but to close the socket
00275   if (error &&
00276       result.accept_handle() != ACE_INVALID_HANDLE )
00277     ACE_OS::closesocket (result.accept_handle ());
00278 
00279   // Delete the dynamically allocated message_block
00280   result.message_block ().release ();
00281 
00282   // Start off another asynchronous accept to keep the backlog going
00283   if (this->should_reissue_accept ())
00284     this->accept (this->bytes_to_read_);
00285 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) || defined (ACE_HAS_AIO_CALLS */
00286 }
00287 
00288 template <class HANDLER> int
00289 ACE_Asynch_Acceptor<HANDLER>::validate_connection
00290   (const ACE_Asynch_Accept::Result& /* result */,
00291    const ACE_INET_Addr& /* remote */,
00292    const ACE_INET_Addr& /* local */)
00293 {
00294   // Default implementation always validates the remote address.
00295   return 0;
00296 }
00297 
00298 template <class HANDLER> int
00299 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (const ACE_INET_Addr&)
00300 {
00301   // Default implementation always validates the remote address.
00302   return 0;
00303 }
00304 
00305 template <class HANDLER> int
00306 ACE_Asynch_Acceptor<HANDLER>::cancel (void)
00307 {
00308   ACE_TRACE ("ACE_Asynch_Acceptor<>::cancel");
00309 
00310   // All I/O operations that are canceled will complete with the error
00311   // ERROR_OPERATION_ABORTED. All completion notifications for the I/O
00312   // operations will occur normally.
00313 #if (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) \
00314     && (   (defined (_MSC_VER) && (_MSC_VER > 1020)) \
00315         || (defined (__BORLANDC__) && (__BORLANDC__ >= 0x530)))
00316   return (int) ::CancelIo (this->listen_handle_);
00317 #else
00318   //ACE_NOTSUP_RETURN (-1);
00319   // Supported now
00320   return this->asynch_accept_.cancel();
00321 
00322 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) && ((defined (_MSC_VER) && (_MSC_VER > 1020)) || (defined (__BORLANDC__) && (__BORLANDC__ >= 0x530))) */
00323 }
00324 
00325 template <class HANDLER> void
00326 ACE_Asynch_Acceptor<HANDLER>::parse_address (const
00327                                              ACE_Asynch_Accept::Result &result,
00328                                              ACE_INET_Addr &remote_address,
00329                                              ACE_INET_Addr &local_address)
00330 {
00331   ACE_TRACE ("ACE_Asynch_Acceptor<>::parse_address");
00332 
00333 #if defined (ACE_HAS_AIO_CALLS)
00334 
00335   // Use an ACE_SOCK to get the addresses - it knows how to deal with
00336   // ACE_INET_Addr objects and get IPv4/v6 addresses.
00337   ACE_SOCK_Stream str (result.accept_handle ());
00338   str.get_local_addr (local_address);
00339   str.get_remote_addr (remote_address);
00340 
00341 #elif (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0))
00342 
00343   ACE_Message_Block &message_block = result.message_block ();
00344 
00345   sockaddr *local_addr = 0;
00346   sockaddr *remote_addr = 0;
00347   int local_size = 0;
00348   int remote_size = 0;
00349 
00350   ::GetAcceptExSockaddrs (message_block.rd_ptr (),
00351                           ACE_static_cast (DWORD, this->bytes_to_read_),
00352                           ACE_static_cast (DWORD, this->address_size ()),
00353                           ACE_static_cast (DWORD, this->address_size ()),
00354                           &local_addr,
00355                           &local_size,
00356                           &remote_addr,
00357                           &remote_size);
00358 
00359   local_address.set (ACE_reinterpret_cast (sockaddr_in *, local_addr),
00360                      local_size);
00361   remote_address.set (ACE_reinterpret_cast (sockaddr_in *, remote_addr),
00362                       remote_size);
00363 #else
00364   // just in case
00365   errno = ENOTSUP;
00366 #endif /* (defined (ACE_HAS_WINNT4) && (ACE_HAS_WINNT4 != 0)) || (defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)) */
00367   return;
00368 }
00369 
00370 template <class HANDLER> ACE_HANDLE
00371 ACE_Asynch_Acceptor<HANDLER>::handle (void) const
00372 {
00373   return this->listen_handle_;
00374 }
00375 
00376 template <class HANDLER> void
00377 ACE_Asynch_Acceptor<HANDLER>::handle (ACE_HANDLE h)
00378 {
00379   ACE_Handler::handle (h);
00380 }
00381 
00382 template <class HANDLER> ACE_Asynch_Accept &
00383 ACE_Asynch_Acceptor<HANDLER>::asynch_accept (void)
00384 {
00385   return this->asynch_accept_;
00386 }
00387 
00388 template <class HANDLER> HANDLER *
00389 ACE_Asynch_Acceptor<HANDLER>::make_handler (void)
00390 {
00391   // Default behavior
00392   HANDLER *handler = 0;
00393   ACE_NEW_RETURN (handler,
00394                   HANDLER,
00395                   0);
00396   return handler;
00397 }
00398 
00399 /* static */
00400 template <class HANDLER> size_t
00401 ACE_Asynch_Acceptor<HANDLER>::address_size (void)
00402 {
00403   return sizeof (sockaddr) + sizeof (sockaddr_in);
00404 }
00405 
00406 template <class HANDLER> int
00407 ACE_Asynch_Acceptor<HANDLER>::pass_addresses (void) const
00408 {
00409   return this->pass_addresses_;
00410 }
00411 
00412 template <class HANDLER> void
00413 ACE_Asynch_Acceptor<HANDLER>::pass_addresses (int new_value)
00414 {
00415   this->pass_addresses_ = new_value;
00416 }
00417 
00418 template <class HANDLER> int
00419 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (void) const
00420 {
00421   return this->validate_new_connection_;
00422 }
00423 
00424 template <class HANDLER> void
00425 ACE_Asynch_Acceptor<HANDLER>::validate_new_connection (int new_value)
00426 {
00427   this->validate_new_connection_ = new_value;
00428 }
00429 
00430 template <class HANDLER> int
00431 ACE_Asynch_Acceptor<HANDLER>::reissue_accept (void) const
00432 {
00433   return this->reissue_accept_;
00434 }
00435 
00436 template <class HANDLER> void
00437 ACE_Asynch_Acceptor<HANDLER>::reissue_accept (int new_value)
00438 {
00439   this->reissue_accept_ = new_value;
00440 }
00441 
00442 template <class HANDLER> size_t
00443 ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (void) const
00444 {
00445   return this->bytes_to_read_;
00446 }
00447 
00448 template <class HANDLER> void
00449 ACE_Asynch_Acceptor<HANDLER>::bytes_to_read (size_t new_value)
00450 {
00451   this->bytes_to_read_ = new_value;
00452 }
00453 
00454 template <class HANDLER> int
00455 ACE_Asynch_Acceptor<HANDLER>::should_reissue_accept (void)
00456 {
00457   return this->reissue_accept_;
00458 }
00459 
00460 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
00461 #endif /* ACE_ASYNCH_ACCEPTOR_C */

Generated on Mon Jun 16 11:19:04 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002