Asynch_Connector.cpp

Go to the documentation of this file.
00001 // Asynch_Connector.cpp,v 1.14 2005/10/28 16:14:51 ossama Exp
00002 
00003 #ifndef ACE_ASYNCH_CONNECTOR_CPP
00004 #define ACE_ASYNCH_CONNECTOR_CPP
00005 
00006 #include "ace/Asynch_Connector.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #if (defined (ACE_WIN32) || defined (ACE_HAS_AIO_CALLS)) && !defined(ACE_HAS_WINCE)
00013 // This only works on platforms that support async I/O.
00014 
00015 #include "ace/OS_NS_sys_socket.h"
00016 #include "ace/OS_Memory.h"
00017 #include "ace/Flag_Manip.h"
00018 #include "ace/Log_Msg.h"
00019 #include "ace/Message_Block.h"
00020 #include "ace/INET_Addr.h"
00021 
00022 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 template <class HANDLER>
00025 ACE_Asynch_Connector<HANDLER>::ACE_Asynch_Connector (void)
00026   : pass_addresses_ (0),
00027     validate_new_connection_ (0)
00028 {
00029 }
00030 
00031 template <class HANDLER>
00032 ACE_Asynch_Connector<HANDLER>::~ACE_Asynch_Connector (void)
00033 {
00034   //this->asynch_connect_.close ();
00035 }
00036 
00037 template <class HANDLER> int
00038 ACE_Asynch_Connector<HANDLER>::open (int pass_addresses,
00039                                      ACE_Proactor *proactor,
00040                                      int validate_new_connection)
00041 {
00042   this->proactor (proactor);
00043   this->pass_addresses_ = pass_addresses;
00044   this->validate_new_connection_ = validate_new_connection;
00045 
00046   // Initialize the ACE_Asynch_Connect
00047   if (this->asynch_connect_.open (*this,
00048                                   ACE_INVALID_HANDLE,
00049                                   0,
00050                                   this->proactor ()) == -1)
00051     ACE_ERROR_RETURN ((LM_ERROR,
00052                        ACE_LIB_TEXT ("%p\n"),
00053                        ACE_LIB_TEXT ("ACE_Asynch_Connect::open")),
00054                       -1);
00055   return 0;
00056 }
00057 
00058 template <class HANDLER> int
00059 ACE_Asynch_Connector<HANDLER>::connect (const ACE_INET_Addr & remote_sap,
00060                                         const ACE_INET_Addr & local_sap,
00061                                         int reuse_addr,
00062                                         const void *act)
00063 {
00064   // Initiate asynchronous connect
00065   if (this->asynch_connect_.connect (ACE_INVALID_HANDLE,
00066                                      remote_sap,
00067                                      local_sap,
00068                                      reuse_addr,
00069                                      act) == -1)
00070     ACE_ERROR_RETURN ((LM_ERROR,
00071                        ACE_LIB_TEXT ("%p\n"),
00072                        ACE_LIB_TEXT ("ACE_Asynch_Connect::connect")),
00073                       -1);
00074   return 0;
00075 }
00076 
00077 template <class HANDLER> void
00078 ACE_Asynch_Connector<HANDLER>::handle_connect (const ACE_Asynch_Connect::Result &result)
00079 {
00080   // Variable for error tracking
00081   int error = 0;
00082 
00083   // If the asynchronous connect fails.
00084   if (!result.success () ||
00085       result.connect_handle () == ACE_INVALID_HANDLE)
00086     {
00087       error = 1;
00088     }
00089 
00090   if (result.error () != 0)
00091     {
00092       error = 1;
00093     }
00094 
00095   // set blocking mode
00096   if (!error &&
00097       ACE::clr_flags
00098         (result.connect_handle (), ACE_NONBLOCK) != 0)
00099     {
00100       error = 1;
00101       ACE_ERROR ((LM_ERROR,
00102                   ACE_LIB_TEXT ("%p\n"),
00103                   ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Set blocking mode")));
00104     }
00105 
00106   // Parse the addresses.
00107   ACE_INET_Addr local_address;
00108   ACE_INET_Addr remote_address;
00109   if (!error &&
00110       (this->validate_new_connection_ || this->pass_addresses_))
00111     this->parse_address (result,
00112                          remote_address,
00113                          local_address);
00114 
00115   // Call validate_connection even if there was an error - it's the only
00116   // way the application can learn the connect disposition.
00117   if (this->validate_new_connection_ &&
00118       this->validate_connection (result, remote_address, local_address) == -1)
00119     {
00120       error = 1;
00121     }
00122 
00123   HANDLER *new_handler = 0;
00124   if (!error)
00125     {
00126       // The Template method
00127       new_handler = this->make_handler ();
00128       if (new_handler == 0)
00129         {
00130           error = 1;
00131           ACE_ERROR ((LM_ERROR,
00132                       ACE_LIB_TEXT ("%p\n"),
00133                       ACE_LIB_TEXT ("ACE_Asynch_Connector::handle_connect : Making of new handler failed")));
00134         }
00135     }
00136 
00137   // If no errors
00138   if (!error)
00139     {
00140       // Update the Proactor.
00141       new_handler->proactor (this->proactor ());
00142 
00143       // Pass the addresses
00144       if (this->pass_addresses_)
00145         new_handler->addresses (remote_address,
00146                                 local_address);
00147 
00148       // Pass the ACT
00149       if (result.act () != 0)
00150         new_handler->act (result.act ());
00151 
00152       // Set up the handler's new handle value
00153       new_handler->handle (result.connect_handle ());
00154 
00155       ACE_Message_Block  mb;
00156 
00157       // Initiate the handler with empty message block;
00158       new_handler->open (result.connect_handle (), mb);
00159     }
00160 
00161   // On failure, no choice but to close the socket
00162   if (error &&
00163       result.connect_handle() != ACE_INVALID_HANDLE)
00164     ACE_OS::closesocket (result.connect_handle ());
00165 }
00166 
00167 template <class HANDLER> int
00168 ACE_Asynch_Connector<HANDLER>::validate_connection
00169   (const ACE_Asynch_Connect::Result &,
00170    const ACE_INET_Addr & /* remote_address */,
00171    const ACE_INET_Addr & /* local_address */)
00172 {
00173   // Default implementation always validates the remote address.
00174   return 0;
00175 }
00176 
00177 template <class HANDLER> int
00178 ACE_Asynch_Connector<HANDLER>::cancel (void)
00179 {
00180   return this->asynch_connect_.cancel ();
00181 }
00182 
00183 template <class HANDLER> void
00184 ACE_Asynch_Connector<HANDLER>::parse_address (const ACE_Asynch_Connect::Result &result,
00185                                               ACE_INET_Addr &remote_address,
00186                                               ACE_INET_Addr &local_address)
00187 {
00188 #if defined (ACE_HAS_IPV6)
00189   // Getting the addresses.
00190   sockaddr_in6 local_addr;
00191   sockaddr_in6 remote_addr;
00192 #else
00193   // Getting the addresses.
00194   sockaddr_in local_addr;
00195   sockaddr_in remote_addr;
00196 #endif /* ACE_HAS_IPV6 */
00197 
00198   // Get the length.
00199   int local_size = sizeof (local_addr);
00200   int remote_size = sizeof (remote_addr);
00201 
00202   // Get the local address.
00203   if (ACE_OS::getsockname (result.connect_handle (),
00204                            reinterpret_cast<sockaddr *> (&local_addr),
00205                            &local_size) < 0)
00206     ACE_ERROR ((LM_ERROR,
00207                 ACE_LIB_TEXT("%p\n"),
00208                 ACE_LIB_TEXT("ACE_Asynch_Connector::<getsockname> failed")));
00209 
00210   // Get the remote address.
00211   if (ACE_OS::getpeername (result.connect_handle (),
00212                            reinterpret_cast<sockaddr *> (&remote_addr),
00213                            &remote_size) < 0)
00214     ACE_ERROR ((LM_ERROR,
00215                 ACE_LIB_TEXT("%p\n"),
00216                 ACE_LIB_TEXT("ACE_Asynch_Connector::<getpeername> failed")));
00217 
00218   // Set the addresses.
00219   local_address.set  (reinterpret_cast<sockaddr_in *> (&local_addr),
00220                       local_size);
00221   remote_address.set (reinterpret_cast<sockaddr_in *> (&remote_addr),
00222                       remote_size);
00223 
00224 #if 0
00225   // @@ Just debugging.
00226   char local_address_buf  [BUFSIZ];
00227   char remote_address_buf [BUFSIZ];
00228 
00229   if (local_address.addr_to_string (local_address_buf,
00230                                     sizeof local_address_buf) == -1)
00231     ACE_ERROR ((LM_ERROR,
00232                 "Error:%m:can't obtain local_address's address string"));
00233 
00234   ACE_DEBUG ((LM_DEBUG,
00235               "ACE_Asynch_Connector<HANDLER>::parse_address : "
00236               "Local address %s\n",
00237               local_address_buf));
00238 
00239   if (remote_address.addr_to_string (remote_address_buf,
00240                                      sizeof remote_address_buf) == -1)
00241     ACE_ERROR ((LM_ERROR,
00242                 "Error:%m:can't obtain remote_address's address string"));
00243 
00244   ACE_DEBUG ((LM_DEBUG,
00245               "ACE_Asynch_Connector<HANDLER>::parse_address : "
00246               "Remote address %s\n",
00247               remote_address_buf));
00248 #endif /* 0 */
00249 
00250   return;
00251 }
00252 
00253 
00254 template <class HANDLER> ACE_Asynch_Connect &
00255 ACE_Asynch_Connector<HANDLER>::asynch_connect (void)
00256 {
00257   return this->asynch_connect_;
00258 }
00259 
00260 template <class HANDLER> HANDLER *
00261 ACE_Asynch_Connector<HANDLER>::make_handler (void)
00262 {
00263   // Default behavior
00264   HANDLER *handler = 0;
00265   ACE_NEW_RETURN (handler, HANDLER, 0);
00266   return handler;
00267 }
00268 
00269 template <class HANDLER> int
00270 ACE_Asynch_Connector<HANDLER>::pass_addresses (void) const
00271 {
00272   return this->pass_addresses_;
00273 }
00274 
00275 template <class HANDLER> void
00276 ACE_Asynch_Connector<HANDLER>::pass_addresses (int new_value)
00277 {
00278   this->pass_addresses_ = new_value;
00279 }
00280 
00281 template <class HANDLER> int
00282 ACE_Asynch_Connector<HANDLER>::validate_new_connection (void) const
00283 {
00284   return this->validate_new_connection_;
00285 }
00286 
00287 template <class HANDLER> void
00288 ACE_Asynch_Connector<HANDLER>::validate_new_connection (int new_value)
00289 {
00290   this->validate_new_connection_ = new_value;
00291 }
00292 
00293 ACE_END_VERSIONED_NAMESPACE_DECL
00294 
00295 #endif /* ACE_WIN32 || ACE_HAS_AIO_CALLS */
00296 #endif /* ACE_ASYNCH_CONNECTOR_CPP */

Generated on Thu Nov 9 09:41:46 2006 for ACE by doxygen 1.3.6